From f720e3ba558680cc7dd3995d005bdc8ee2ef46af Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 6 Jun 2007 15:28:35 -0500 Subject: [PATCH 001/551] JFS: Whitespace cleanup and remove some dead code Signed-off-by: Dave Kleikamp --- fs/jfs/endian24.h | 2 +- fs/jfs/jfs_dinode.h | 42 ++--- fs/jfs/jfs_dmap.c | 419 +++++++++++++++++++++---------------------- fs/jfs/jfs_dmap.h | 118 ++++++------ fs/jfs/jfs_dtree.c | 105 ++++++----- fs/jfs/jfs_dtree.h | 2 +- fs/jfs/jfs_extent.c | 102 +++++------ fs/jfs/jfs_filsys.h | 13 +- fs/jfs/jfs_imap.c | 293 ++++++++++++++---------------- fs/jfs/jfs_imap.h | 98 +++++----- fs/jfs/jfs_incore.h | 4 +- fs/jfs/jfs_logmgr.c | 68 +++---- fs/jfs/jfs_logmgr.h | 26 +-- fs/jfs/jfs_mount.c | 6 +- fs/jfs/jfs_txnmgr.c | 276 ++++++++++++++-------------- fs/jfs/jfs_txnmgr.h | 2 +- fs/jfs/jfs_types.h | 20 +-- fs/jfs/jfs_umount.c | 2 +- fs/jfs/jfs_xtree.c | 428 ++++++++++++++++++++++---------------------- fs/jfs/jfs_xtree.h | 48 ++--- fs/jfs/namei.c | 26 +-- fs/jfs/resize.c | 48 ++--- fs/jfs/xattr.c | 6 +- 23 files changed, 1061 insertions(+), 1093 deletions(-) diff --git a/fs/jfs/endian24.h b/fs/jfs/endian24.h index 79494c4f2b10..fa92f7f1d0d0 100644 --- a/fs/jfs/endian24.h +++ b/fs/jfs/endian24.h @@ -29,7 +29,7 @@ __u32 __x = (x); \ ((__u32)( \ ((__x & (__u32)0x000000ffUL) << 16) | \ - (__x & (__u32)0x0000ff00UL) | \ + (__x & (__u32)0x0000ff00UL) | \ ((__x & (__u32)0x00ff0000UL) >> 16) )); \ }) diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h index 40b20111383c..c387540d3425 100644 --- a/fs/jfs/jfs_dinode.h +++ b/fs/jfs/jfs_dinode.h @@ -19,23 +19,23 @@ #define _H_JFS_DINODE /* - * jfs_dinode.h: on-disk inode manager + * jfs_dinode.h: on-disk inode manager */ -#define INODESLOTSIZE 128 -#define L2INODESLOTSIZE 7 -#define log2INODESIZE 9 /* log2(bytes per dinode) */ +#define INODESLOTSIZE 128 +#define L2INODESLOTSIZE 7 +#define log2INODESIZE 9 /* log2(bytes per dinode) */ /* - * on-disk inode : 512 bytes + * on-disk inode : 512 bytes * * note: align 64-bit fields on 8-byte boundary. */ struct dinode { /* - * I. base area (128 bytes) - * ------------------------ + * I. base area (128 bytes) + * ------------------------ * * define generic/POSIX attributes */ @@ -70,16 +70,16 @@ struct dinode { __le32 di_acltype; /* 4: Type of ACL */ /* - * Extension Areas. + * Extension Areas. * - * Historically, the inode was partitioned into 4 128-byte areas, - * the last 3 being defined as unions which could have multiple - * uses. The first 96 bytes had been completely unused until - * an index table was added to the directory. It is now more - * useful to describe the last 3/4 of the inode as a single - * union. We would probably be better off redesigning the - * entire structure from scratch, but we don't want to break - * commonality with OS/2's JFS at this time. + * Historically, the inode was partitioned into 4 128-byte areas, + * the last 3 being defined as unions which could have multiple + * uses. The first 96 bytes had been completely unused until + * an index table was added to the directory. It is now more + * useful to describe the last 3/4 of the inode as a single + * union. We would probably be better off redesigning the + * entire structure from scratch, but we don't want to break + * commonality with OS/2's JFS at this time. */ union { struct { @@ -95,7 +95,7 @@ struct dinode { } _dir; /* (384) */ #define di_dirtable u._dir._table #define di_dtroot u._dir._dtroot -#define di_parent di_dtroot.header.idotdot +#define di_parent di_dtroot.header.idotdot #define di_DASD di_dtroot.header.DASD struct { @@ -127,14 +127,14 @@ struct dinode { #define di_inlinedata u._file._u2._special._u #define di_rdev u._file._u2._special._u._rdev #define di_fastsymlink u._file._u2._special._u._fastsymlink -#define di_inlineea u._file._u2._special._inlineea +#define di_inlineea u._file._u2._special._inlineea } u; }; /* extended mode bits (on-disk inode di_mode) */ -#define IFJOURNAL 0x00010000 /* journalled file */ -#define ISPARSE 0x00020000 /* sparse file enabled */ -#define INLINEEA 0x00040000 /* inline EA area free */ +#define IFJOURNAL 0x00010000 /* journalled file */ +#define ISPARSE 0x00020000 /* sparse file enabled */ +#define INLINEEA 0x00040000 /* inline EA area free */ #define ISWAPFILE 0x00800000 /* file open for pager swap space */ /* more extended mode bits: attributes for OS/2 */ diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index f3b1ebb22280..e1985066b1c6 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -154,12 +154,12 @@ static const s8 budtab[256] = { * the in-core descriptor is initialized from disk. * * PARAMETERS: - * ipbmap - pointer to in-core inode for the block map. + * ipbmap - pointer to in-core inode for the block map. * * RETURN VALUES: - * 0 - success - * -ENOMEM - insufficient memory - * -EIO - i/o error + * 0 - success + * -ENOMEM - insufficient memory + * -EIO - i/o error */ int dbMount(struct inode *ipbmap) { @@ -232,11 +232,11 @@ int dbMount(struct inode *ipbmap) * the memory for this descriptor is freed. * * PARAMETERS: - * ipbmap - pointer to in-core inode for the block map. + * ipbmap - pointer to in-core inode for the block map. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error */ int dbUnmount(struct inode *ipbmap, int mounterror) { @@ -320,13 +320,13 @@ int dbSync(struct inode *ipbmap) * at a time. * * PARAMETERS: - * ip - pointer to in-core inode; - * blkno - starting block number to be freed. - * nblocks - number of blocks to be freed. + * ip - pointer to in-core inode; + * blkno - starting block number to be freed. + * nblocks - number of blocks to be freed. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error */ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) { @@ -395,23 +395,23 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) /* * NAME: dbUpdatePMap() * - * FUNCTION: update the allocation state (free or allocate) of the + * FUNCTION: update the allocation state (free or allocate) of the * specified block range in the persistent block allocation map. * * the blocks will be updated in the persistent map one * dmap at a time. * * PARAMETERS: - * ipbmap - pointer to in-core inode for the block map. - * free - 'true' if block range is to be freed from the persistent - * map; 'false' if it is to be allocated. - * blkno - starting block number of the range. - * nblocks - number of contiguous blocks in the range. - * tblk - transaction block; + * ipbmap - pointer to in-core inode for the block map. + * free - 'true' if block range is to be freed from the persistent + * map; 'false' if it is to be allocated. + * blkno - starting block number of the range. + * nblocks - number of contiguous blocks in the range. + * tblk - transaction block; * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error */ int dbUpdatePMap(struct inode *ipbmap, @@ -573,7 +573,7 @@ dbUpdatePMap(struct inode *ipbmap, /* * NAME: dbNextAG() * - * FUNCTION: find the preferred allocation group for new allocations. + * FUNCTION: find the preferred allocation group for new allocations. * * Within the allocation groups, we maintain a preferred * allocation group which consists of a group with at least @@ -589,10 +589,10 @@ dbUpdatePMap(struct inode *ipbmap, * empty ags around for large allocations. * * PARAMETERS: - * ipbmap - pointer to in-core inode for the block map. + * ipbmap - pointer to in-core inode for the block map. * * RETURN VALUES: - * the preferred allocation group number. + * the preferred allocation group number. */ int dbNextAG(struct inode *ipbmap) { @@ -656,7 +656,7 @@ unlock: /* * NAME: dbAlloc() * - * FUNCTION: attempt to allocate a specified number of contiguous free + * FUNCTION: attempt to allocate a specified number of contiguous free * blocks from the working allocation block map. * * the block allocation policy uses hints and a multi-step @@ -680,16 +680,16 @@ unlock: * size or requests that specify no hint value. * * PARAMETERS: - * ip - pointer to in-core inode; - * hint - allocation hint. - * nblocks - number of contiguous blocks in the range. - * results - on successful return, set to the starting block number + * ip - pointer to in-core inode; + * hint - allocation hint. + * nblocks - number of contiguous blocks in the range. + * results - on successful return, set to the starting block number * of the newly allocated contiguous range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error */ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) { @@ -706,12 +706,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) /* assert that nblocks is valid */ assert(nblocks > 0); -#ifdef _STILL_TO_PORT - /* DASD limit check F226941 */ - if (OVER_LIMIT(ip, nblocks)) - return -ENOSPC; -#endif /* _STILL_TO_PORT */ - /* get the log2 number of blocks to be allocated. * if the number of blocks is not a log2 multiple, * it will be rounded up to the next log2 multiple. @@ -720,7 +714,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) bmp = JFS_SBI(ip->i_sb)->bmap; -//retry: /* serialize w.r.t.extendfs() */ mapSize = bmp->db_mapsize; /* the hint should be within the map */ @@ -879,17 +872,17 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) /* * NAME: dbAllocExact() * - * FUNCTION: try to allocate the requested extent; + * FUNCTION: try to allocate the requested extent; * * PARAMETERS: - * ip - pointer to in-core inode; - * blkno - extent address; - * nblocks - extent length; + * ip - pointer to in-core inode; + * blkno - extent address; + * nblocks - extent length; * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error */ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) { @@ -946,7 +939,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) /* * NAME: dbReAlloc() * - * FUNCTION: attempt to extend a current allocation by a specified + * FUNCTION: attempt to extend a current allocation by a specified * number of blocks. * * this routine attempts to satisfy the allocation request @@ -959,21 +952,21 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) * number of blocks required. * * PARAMETERS: - * ip - pointer to in-core inode requiring allocation. - * blkno - starting block of the current allocation. - * nblocks - number of contiguous blocks within the current + * ip - pointer to in-core inode requiring allocation. + * blkno - starting block of the current allocation. + * nblocks - number of contiguous blocks within the current * allocation. - * addnblocks - number of blocks to add to the allocation. - * results - on successful return, set to the starting block number + * addnblocks - number of blocks to add to the allocation. + * results - on successful return, set to the starting block number * of the existing allocation if the existing allocation * was extended in place or to a newly allocated contiguous * range if the existing allocation could not be extended * in place. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error */ int dbReAlloc(struct inode *ip, @@ -1004,7 +997,7 @@ dbReAlloc(struct inode *ip, /* * NAME: dbExtend() * - * FUNCTION: attempt to extend a current allocation by a specified + * FUNCTION: attempt to extend a current allocation by a specified * number of blocks. * * this routine attempts to satisfy the allocation request @@ -1013,16 +1006,16 @@ dbReAlloc(struct inode *ip, * immediately following the current allocation. * * PARAMETERS: - * ip - pointer to in-core inode requiring allocation. - * blkno - starting block of the current allocation. - * nblocks - number of contiguous blocks within the current + * ip - pointer to in-core inode requiring allocation. + * blkno - starting block of the current allocation. + * nblocks - number of contiguous blocks within the current * allocation. - * addnblocks - number of blocks to add to the allocation. + * addnblocks - number of blocks to add to the allocation. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error */ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) { @@ -1109,19 +1102,19 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) /* * NAME: dbAllocNext() * - * FUNCTION: attempt to allocate the blocks of the specified block + * FUNCTION: attempt to allocate the blocks of the specified block * range within a dmap. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap. - * blkno - starting block number of the range. - * nblocks - number of contiguous free blocks of the range. + * bmp - pointer to bmap descriptor + * dp - pointer to dmap. + * blkno - starting block number of the range. + * nblocks - number of contiguous free blocks of the range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap) held on entry/exit; */ @@ -1233,7 +1226,7 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno, /* * NAME: dbAllocNear() * - * FUNCTION: attempt to allocate a number of contiguous free blocks near + * FUNCTION: attempt to allocate a number of contiguous free blocks near * a specified block (hint) within a dmap. * * starting with the dmap leaf that covers the hint, we'll @@ -1242,18 +1235,18 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno, * the desired free space. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap. - * blkno - block number to allocate near. - * nblocks - actual number of contiguous free blocks desired. - * l2nb - log2 number of contiguous free blocks desired. - * results - on successful return, set to the starting block number + * bmp - pointer to bmap descriptor + * dp - pointer to dmap. + * blkno - block number to allocate near. + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number * of the newly allocated range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap) held on entry/exit; */ @@ -1316,7 +1309,7 @@ dbAllocNear(struct bmap * bmp, /* * NAME: dbAllocAG() * - * FUNCTION: attempt to allocate the specified number of contiguous + * FUNCTION: attempt to allocate the specified number of contiguous * free blocks within the specified allocation group. * * unless the allocation group size is equal to the number @@ -1353,17 +1346,17 @@ dbAllocNear(struct bmap * bmp, * the allocation group. * * PARAMETERS: - * bmp - pointer to bmap descriptor + * bmp - pointer to bmap descriptor * agno - allocation group number. - * nblocks - actual number of contiguous free blocks desired. - * l2nb - log2 number of contiguous free blocks desired. - * results - on successful return, set to the starting block number + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number * of the newly allocated range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * note: IWRITE_LOCK(ipmap) held on entry/exit; */ @@ -1546,7 +1539,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) /* * NAME: dbAllocAny() * - * FUNCTION: attempt to allocate the specified number of contiguous + * FUNCTION: attempt to allocate the specified number of contiguous * free blocks anywhere in the file system. * * dbAllocAny() attempts to find the sufficient free space by @@ -1556,16 +1549,16 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) * desired free space is allocated. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * nblocks - actual number of contiguous free blocks desired. - * l2nb - log2 number of contiguous free blocks desired. - * results - on successful return, set to the starting block number + * bmp - pointer to bmap descriptor + * nblocks - actual number of contiguous free blocks desired. + * l2nb - log2 number of contiguous free blocks desired. + * results - on successful return, set to the starting block number * of the newly allocated range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -1598,9 +1591,9 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results) /* * NAME: dbFindCtl() * - * FUNCTION: starting at a specified dmap control page level and block + * FUNCTION: starting at a specified dmap control page level and block * number, search down the dmap control levels for a range of - * contiguous free blocks large enough to satisfy an allocation + * contiguous free blocks large enough to satisfy an allocation * request for the specified number of free blocks. * * if sufficient contiguous free blocks are found, this routine @@ -1609,17 +1602,17 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results) * is sufficient in size. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * level - starting dmap control page level. - * l2nb - log2 number of contiguous free blocks desired. - * *blkno - on entry, starting block number for conducting the search. + * bmp - pointer to bmap descriptor + * level - starting dmap control page level. + * l2nb - log2 number of contiguous free blocks desired. + * *blkno - on entry, starting block number for conducting the search. * on successful return, the first block within a dmap page * that contains or starts a range of contiguous free blocks. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -1699,7 +1692,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) /* * NAME: dbAllocCtl() * - * FUNCTION: attempt to allocate a specified number of contiguous + * FUNCTION: attempt to allocate a specified number of contiguous * blocks starting within a specific dmap. * * this routine is called by higher level routines that search @@ -1726,18 +1719,18 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) * first dmap (i.e. blkno). * * PARAMETERS: - * bmp - pointer to bmap descriptor - * nblocks - actual number of contiguous free blocks to allocate. - * l2nb - log2 number of contiguous free blocks to allocate. - * blkno - starting block number of the dmap to start the allocation + * bmp - pointer to bmap descriptor + * nblocks - actual number of contiguous free blocks to allocate. + * l2nb - log2 number of contiguous free blocks to allocate. + * blkno - starting block number of the dmap to start the allocation * from. - * results - on successful return, set to the starting block number + * results - on successful return, set to the starting block number * of the newly allocated range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -1870,7 +1863,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) /* * NAME: dbAllocDmapLev() * - * FUNCTION: attempt to allocate a specified number of contiguous blocks + * FUNCTION: attempt to allocate a specified number of contiguous blocks * from a specified dmap. * * this routine checks if the contiguous blocks are available. @@ -1878,17 +1871,17 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) * returned. * * PARAMETERS: - * mp - pointer to bmap descriptor - * dp - pointer to dmap to attempt to allocate blocks from. - * l2nb - log2 number of contiguous block desired. - * nblocks - actual number of contiguous block desired. - * results - on successful return, set to the starting block number + * mp - pointer to bmap descriptor + * dp - pointer to dmap to attempt to allocate blocks from. + * l2nb - log2 number of contiguous block desired. + * nblocks - actual number of contiguous block desired. + * results - on successful return, set to the starting block number * of the newly allocated range. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient disk resources - * -EIO - i/o error + * 0 - success + * -ENOSPC - insufficient disk resources + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or * IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit; @@ -1933,7 +1926,7 @@ dbAllocDmapLev(struct bmap * bmp, /* * NAME: dbAllocDmap() * - * FUNCTION: adjust the disk allocation map to reflect the allocation + * FUNCTION: adjust the disk allocation map to reflect the allocation * of a specified block range within a dmap. * * this routine allocates the specified blocks from the dmap @@ -1946,14 +1939,14 @@ dbAllocDmapLev(struct bmap * bmp, * covers this dmap. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap to allocate the block range from. - * blkno - starting block number of the block to be allocated. - * nblocks - number of blocks to be allocated. + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to allocate the block range from. + * blkno - starting block number of the block to be allocated. + * nblocks - number of blocks to be allocated. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -1989,7 +1982,7 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, /* * NAME: dbFreeDmap() * - * FUNCTION: adjust the disk allocation map to reflect the allocation + * FUNCTION: adjust the disk allocation map to reflect the allocation * of a specified block range within a dmap. * * this routine frees the specified blocks from the dmap through @@ -1997,18 +1990,18 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, * causes the maximum string of free blocks within the dmap to * change (i.e. the value of the root of the dmap's dmtree), this * routine will cause this change to be reflected up through the - * appropriate levels of the dmap control pages by a call to + * appropriate levels of the dmap control pages by a call to * dbAdjCtl() for the L0 dmap control page that covers this dmap. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap to free the block range from. - * blkno - starting block number of the block to be freed. - * nblocks - number of blocks to be freed. + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to free the block range from. + * blkno - starting block number of the block to be freed. + * nblocks - number of blocks to be freed. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -2055,7 +2048,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, /* * NAME: dbAllocBits() * - * FUNCTION: allocate a specified block range from a dmap. + * FUNCTION: allocate a specified block range from a dmap. * * this routine updates the dmap to reflect the working * state allocation of the specified block range. it directly @@ -2065,10 +2058,10 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, * dmap's dmtree, as a whole, to reflect the allocated range. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap to allocate bits from. - * blkno - starting block number of the bits to be allocated. - * nblocks - number of bits to be allocated. + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to allocate bits from. + * blkno - starting block number of the bits to be allocated. + * nblocks - number of bits to be allocated. * * RETURN VALUES: none * @@ -2149,7 +2142,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * the allocated words. */ for (; nwords > 0; nwords -= nw) { - if (leaf[word] < BUDMIN) { + if (leaf[word] < BUDMIN) { jfs_error(bmp->db_ipbmap->i_sb, "dbAllocBits: leaf page " "corrupt"); @@ -2202,7 +2195,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, /* * NAME: dbFreeBits() * - * FUNCTION: free a specified block range from a dmap. + * FUNCTION: free a specified block range from a dmap. * * this routine updates the dmap to reflect the working * state allocation of the specified block range. it directly @@ -2212,10 +2205,10 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * dmtree, as a whole, to reflect the deallocated range. * * PARAMETERS: - * bmp - pointer to bmap descriptor - * dp - pointer to dmap to free bits from. - * blkno - starting block number of the bits to be freed. - * nblocks - number of bits to be freed. + * bmp - pointer to bmap descriptor + * dp - pointer to dmap to free bits from. + * blkno - starting block number of the bits to be freed. + * nblocks - number of bits to be freed. * * RETURN VALUES: 0 for success * @@ -2388,19 +2381,19 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * the new root value and the next dmap control page level to * be adjusted. * PARAMETERS: - * bmp - pointer to bmap descriptor - * blkno - the first block of a block range within a dmap. it is + * bmp - pointer to bmap descriptor + * blkno - the first block of a block range within a dmap. it is * the allocation or deallocation of this block range that * requires the dmap control page to be adjusted. - * newval - the new value of the lower level dmap or dmap control + * newval - the new value of the lower level dmap or dmap control * page root. - * alloc - 'true' if adjustment is due to an allocation. - * level - current level of dmap control page (i.e. L0, L1, L2) to + * alloc - 'true' if adjustment is due to an allocation. + * level - current level of dmap control page (i.e. L0, L1, L2) to * be adjusted. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ @@ -2544,16 +2537,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) /* * NAME: dbSplit() * - * FUNCTION: update the leaf of a dmtree with a new value, splitting + * FUNCTION: update the leaf of a dmtree with a new value, splitting * the leaf from the binary buddy system of the dmtree's * leaves, as required. * * PARAMETERS: - * tp - pointer to the tree containing the leaf. - * leafno - the number of the leaf to be updated. - * splitsz - the size the binary buddy system starting at the leaf + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. + * splitsz - the size the binary buddy system starting at the leaf * must be split to, specified as the log2 number of blocks. - * newval - the new value for the leaf. + * newval - the new value for the leaf. * * RETURN VALUES: none * @@ -2600,7 +2593,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) /* * NAME: dbBackSplit() * - * FUNCTION: back split the binary buddy system of dmtree leaves + * FUNCTION: back split the binary buddy system of dmtree leaves * that hold a specified leaf until the specified leaf * starts its own binary buddy system. * @@ -2617,8 +2610,8 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) * in which a previous join operation must be backed out. * * PARAMETERS: - * tp - pointer to the tree containing the leaf. - * leafno - the number of the leaf to be updated. + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. * * RETURN VALUES: none * @@ -2692,14 +2685,14 @@ static int dbBackSplit(dmtree_t * tp, int leafno) /* * NAME: dbJoin() * - * FUNCTION: update the leaf of a dmtree with a new value, joining + * FUNCTION: update the leaf of a dmtree with a new value, joining * the leaf with other leaves of the dmtree into a multi-leaf * binary buddy system, as required. * * PARAMETERS: - * tp - pointer to the tree containing the leaf. - * leafno - the number of the leaf to be updated. - * newval - the new value for the leaf. + * tp - pointer to the tree containing the leaf. + * leafno - the number of the leaf to be updated. + * newval - the new value for the leaf. * * RETURN VALUES: none */ @@ -2785,15 +2778,15 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval) /* * NAME: dbAdjTree() * - * FUNCTION: update a leaf of a dmtree with a new value, adjusting + * FUNCTION: update a leaf of a dmtree with a new value, adjusting * the dmtree, as required, to reflect the new leaf value. * the combination of any buddies must already be done before * this is called. * * PARAMETERS: - * tp - pointer to the tree to be adjusted. - * leafno - the number of the leaf to be updated. - * newval - the new value for the leaf. + * tp - pointer to the tree to be adjusted. + * leafno - the number of the leaf to be updated. + * newval - the new value for the leaf. * * RETURN VALUES: none */ @@ -2852,7 +2845,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) /* * NAME: dbFindLeaf() * - * FUNCTION: search a dmtree_t for sufficient free blocks, returning + * FUNCTION: search a dmtree_t for sufficient free blocks, returning * the index of a leaf describing the free blocks if * sufficient free blocks are found. * @@ -2861,15 +2854,15 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) * free space. * * PARAMETERS: - * tp - pointer to the tree to be searched. - * l2nb - log2 number of free blocks to search for. + * tp - pointer to the tree to be searched. + * l2nb - log2 number of free blocks to search for. * leafidx - return pointer to be set to the index of the leaf * describing at least l2nb free blocks if sufficient * free blocks are found. * * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient free blocks. + * 0 - success + * -ENOSPC - insufficient free blocks. */ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) { @@ -2916,18 +2909,18 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) /* * NAME: dbFindBits() * - * FUNCTION: find a specified number of binary buddy free bits within a + * FUNCTION: find a specified number of binary buddy free bits within a * dmap bitmap word value. * * this routine searches the bitmap value for (1 << l2nb) free * bits at (1 << l2nb) alignments within the value. * * PARAMETERS: - * word - dmap bitmap word value. - * l2nb - number of free bits specified as a log2 number. + * word - dmap bitmap word value. + * l2nb - number of free bits specified as a log2 number. * * RETURN VALUES: - * starting bit number of free bits. + * starting bit number of free bits. */ static int dbFindBits(u32 word, int l2nb) { @@ -2963,14 +2956,14 @@ static int dbFindBits(u32 word, int l2nb) /* * NAME: dbMaxBud(u8 *cp) * - * FUNCTION: determine the largest binary buddy string of free + * FUNCTION: determine the largest binary buddy string of free * bits within 32-bits of the map. * * PARAMETERS: - * cp - pointer to the 32-bit value. + * cp - pointer to the 32-bit value. * * RETURN VALUES: - * largest binary buddy of free bits within a dmap word. + * largest binary buddy of free bits within a dmap word. */ static int dbMaxBud(u8 * cp) { @@ -3000,14 +2993,14 @@ static int dbMaxBud(u8 * cp) /* * NAME: cnttz(uint word) * - * FUNCTION: determine the number of trailing zeros within a 32-bit + * FUNCTION: determine the number of trailing zeros within a 32-bit * value. * * PARAMETERS: - * value - 32-bit value to be examined. + * value - 32-bit value to be examined. * * RETURN VALUES: - * count of trailing zeros + * count of trailing zeros */ static int cnttz(u32 word) { @@ -3025,14 +3018,14 @@ static int cnttz(u32 word) /* * NAME: cntlz(u32 value) * - * FUNCTION: determine the number of leading zeros within a 32-bit + * FUNCTION: determine the number of leading zeros within a 32-bit * value. * * PARAMETERS: - * value - 32-bit value to be examined. + * value - 32-bit value to be examined. * * RETURN VALUES: - * count of leading zeros + * count of leading zeros */ static int cntlz(u32 value) { @@ -3050,14 +3043,14 @@ static int cntlz(u32 value) * NAME: blkstol2(s64 nb) * * FUNCTION: convert a block count to its log2 value. if the block - * count is not a l2 multiple, it is rounded up to the next + * count is not a l2 multiple, it is rounded up to the next * larger l2 multiple. * * PARAMETERS: - * nb - number of blocks + * nb - number of blocks * * RETURN VALUES: - * log2 number of blocks + * log2 number of blocks */ static int blkstol2(s64 nb) { @@ -3099,13 +3092,13 @@ static int blkstol2(s64 nb) * at a time. * * PARAMETERS: - * ip - pointer to in-core inode; - * blkno - starting block number to be freed. - * nblocks - number of blocks to be freed. + * ip - pointer to in-core inode; + * blkno - starting block number to be freed. + * nblocks - number of blocks to be freed. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error + * 0 - success + * -EIO - i/o error */ int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks) { @@ -3278,10 +3271,10 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno, * L2 * | * L1---------------------------------L1 - * | | - * L0---------L0---------L0 L0---------L0---------L0 - * | | | | | | - * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm; + * | | + * L0---------L0---------L0 L0---------L0---------L0 + * | | | | | | + * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm; * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm * * <---old---><----------------------------extend-----------------------> @@ -3307,7 +3300,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) (long long) blkno, (long long) nblocks, (long long) newsize); /* - * initialize bmap control page. + * initialize bmap control page. * * all the data in bmap control page should exclude * the mkfs hidden dmap page. @@ -3330,7 +3323,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0; /* - * reconfigure db_agfree[] + * reconfigure db_agfree[] * from old AG configuration to new AG configuration; * * coalesce contiguous k (newAGSize/oldAGSize) AGs; @@ -3362,7 +3355,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) bmp->db_maxag = bmp->db_maxag / k; /* - * extend bmap + * extend bmap * * update bit maps and corresponding level control pages; * global control page db_nfree, db_agfree[agno], db_maxfreebud; @@ -3410,7 +3403,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) /* compute start L0 */ j = 0; l1leaf = l1dcp->stree + CTLLEAFIND; - p += nbperpage; /* 1st L0 of L1.k */ + p += nbperpage; /* 1st L0 of L1.k */ } /* @@ -3548,7 +3541,7 @@ errout: return -EIO; /* - * finalize bmap control page + * finalize bmap control page */ finalize: @@ -3567,7 +3560,7 @@ void dbFinalizeBmap(struct inode *ipbmap) int i, n; /* - * finalize bmap control page + * finalize bmap control page */ //finalize: /* @@ -3953,8 +3946,8 @@ static int dbGetL2AGSize(s64 nblocks) * convert number of map pages to the zero origin top dmapctl level */ #define BMAPPGTOLEV(npages) \ - (((npages) <= 3 + MAXL0PAGES) ? 0 \ - : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2) + (((npages) <= 3 + MAXL0PAGES) ? 0 : \ + ((npages) <= 2 + MAXL1PAGES) ? 1 : 2) s64 dbMapFileSizeToMapSize(struct inode * ipbmap) { @@ -3981,8 +3974,8 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap) factor = (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1); complete = (u32) npages / factor; - ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL - : ((i == 1) ? LPERCTL : 1)); + ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL : + ((i == 1) ? LPERCTL : 1)); /* pages in last/incomplete child */ npages = (u32) npages % factor; diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h index 45ea454c74bd..11e6d471b364 100644 --- a/fs/jfs/jfs_dmap.h +++ b/fs/jfs/jfs_dmap.h @@ -83,7 +83,7 @@ static __inline signed char TREEMAX(signed char *cp) * - 1 is added to account for the control page of the map. */ #define BLKTODMAP(b,s) \ - ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s)) + ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s)) /* * convert disk block number to the logical block number of the LEVEL 0 @@ -98,7 +98,7 @@ static __inline signed char TREEMAX(signed char *cp) * - 1 is added to account for the control page of the map. */ #define BLKTOL0(b,s) \ - (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s)) + (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s)) /* * convert disk block number to the logical block number of the LEVEL 1 @@ -120,7 +120,7 @@ static __inline signed char TREEMAX(signed char *cp) * at the specified level which describes the disk block. */ #define BLKTOCTL(b,s,l) \ - (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s))) + (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s))) /* * convert aggregate map size to the zero origin dmapctl level of the @@ -145,27 +145,27 @@ static __inline signed char TREEMAX(signed char *cp) * dmaptree must be consistent with dmapctl. */ struct dmaptree { - __le32 nleafs; /* 4: number of tree leafs */ - __le32 l2nleafs; /* 4: l2 number of tree leafs */ - __le32 leafidx; /* 4: index of first tree leaf */ - __le32 height; /* 4: height of the tree */ + __le32 nleafs; /* 4: number of tree leafs */ + __le32 l2nleafs; /* 4: l2 number of tree leafs */ + __le32 leafidx; /* 4: index of first tree leaf */ + __le32 height; /* 4: height of the tree */ s8 budmin; /* 1: min l2 tree leaf value to combine */ - s8 stree[TREESIZE]; /* TREESIZE: tree */ - u8 pad[2]; /* 2: pad to word boundary */ -}; /* - 360 - */ + s8 stree[TREESIZE]; /* TREESIZE: tree */ + u8 pad[2]; /* 2: pad to word boundary */ +}; /* - 360 - */ /* * dmap page per 8K blocks bitmap */ struct dmap { - __le32 nblocks; /* 4: num blks covered by this dmap */ - __le32 nfree; /* 4: num of free blks in this dmap */ - __le64 start; /* 8: starting blkno for this dmap */ - struct dmaptree tree; /* 360: dmap tree */ - u8 pad[1672]; /* 1672: pad to 2048 bytes */ - __le32 wmap[LPERDMAP]; /* 1024: bits of the working map */ - __le32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */ -}; /* - 4096 - */ + __le32 nblocks; /* 4: num blks covered by this dmap */ + __le32 nfree; /* 4: num of free blks in this dmap */ + __le64 start; /* 8: starting blkno for this dmap */ + struct dmaptree tree; /* 360: dmap tree */ + u8 pad[1672]; /* 1672: pad to 2048 bytes */ + __le32 wmap[LPERDMAP]; /* 1024: bits of the working map */ + __le32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */ +}; /* - 4096 - */ /* * disk map control page per level. @@ -173,14 +173,14 @@ struct dmap { * dmapctl must be consistent with dmaptree. */ struct dmapctl { - __le32 nleafs; /* 4: number of tree leafs */ - __le32 l2nleafs; /* 4: l2 number of tree leafs */ - __le32 leafidx; /* 4: index of the first tree leaf */ - __le32 height; /* 4: height of tree */ - s8 budmin; /* 1: minimum l2 tree leaf value */ - s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */ - u8 pad[2714]; /* 2714: pad to 4096 */ -}; /* - 4096 - */ + __le32 nleafs; /* 4: number of tree leafs */ + __le32 l2nleafs; /* 4: l2 number of tree leafs */ + __le32 leafidx; /* 4: index of the first tree leaf */ + __le32 height; /* 4: height of tree */ + s8 budmin; /* 1: minimum l2 tree leaf value */ + s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */ + u8 pad[2714]; /* 2714: pad to 4096 */ +}; /* - 4096 - */ /* * common definition for dmaptree within dmap and dmapctl @@ -202,41 +202,41 @@ typedef union dmtree { * on-disk aggregate disk allocation map descriptor. */ struct dbmap_disk { - __le64 dn_mapsize; /* 8: number of blocks in aggregate */ - __le64 dn_nfree; /* 8: num free blks in aggregate map */ - __le32 dn_l2nbperpage; /* 4: number of blks per page */ - __le32 dn_numag; /* 4: total number of ags */ - __le32 dn_maxlevel; /* 4: number of active ags */ - __le32 dn_maxag; /* 4: max active alloc group number */ - __le32 dn_agpref; /* 4: preferred alloc group (hint) */ - __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ - __le32 dn_agheigth; /* 4: height in dmapctl of the AG */ - __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ - __le32 dn_agstart; /* 4: start tree index at AG height */ - __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ - __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count */ - __le64 dn_agsize; /* 8: num of blks per alloc group */ - s8 dn_maxfreebud; /* 1: max free buddy system */ - u8 pad[3007]; /* 3007: pad to 4096 */ -}; /* - 4096 - */ + __le64 dn_mapsize; /* 8: number of blocks in aggregate */ + __le64 dn_nfree; /* 8: num free blks in aggregate map */ + __le32 dn_l2nbperpage; /* 4: number of blks per page */ + __le32 dn_numag; /* 4: total number of ags */ + __le32 dn_maxlevel; /* 4: number of active ags */ + __le32 dn_maxag; /* 4: max active alloc group number */ + __le32 dn_agpref; /* 4: preferred alloc group (hint) */ + __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ + __le32 dn_agheigth; /* 4: height in dmapctl of the AG */ + __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ + __le32 dn_agstart; /* 4: start tree index at AG height */ + __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ + __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count */ + __le64 dn_agsize; /* 8: num of blks per alloc group */ + s8 dn_maxfreebud; /* 1: max free buddy system */ + u8 pad[3007]; /* 3007: pad to 4096 */ +}; /* - 4096 - */ struct dbmap { - s64 dn_mapsize; /* number of blocks in aggregate */ - s64 dn_nfree; /* num free blks in aggregate map */ - int dn_l2nbperpage; /* number of blks per page */ - int dn_numag; /* total number of ags */ - int dn_maxlevel; /* number of active ags */ - int dn_maxag; /* max active alloc group number */ - int dn_agpref; /* preferred alloc group (hint) */ - int dn_aglevel; /* dmapctl level holding the AG */ - int dn_agheigth; /* height in dmapctl of the AG */ - int dn_agwidth; /* width in dmapctl of the AG */ - int dn_agstart; /* start tree index at AG height */ - int dn_agl2size; /* l2 num of blks per alloc group */ - s64 dn_agfree[MAXAG]; /* per AG free count */ - s64 dn_agsize; /* num of blks per alloc group */ - signed char dn_maxfreebud; /* max free buddy system */ -}; /* - 4096 - */ + s64 dn_mapsize; /* number of blocks in aggregate */ + s64 dn_nfree; /* num free blks in aggregate map */ + int dn_l2nbperpage; /* number of blks per page */ + int dn_numag; /* total number of ags */ + int dn_maxlevel; /* number of active ags */ + int dn_maxag; /* max active alloc group number */ + int dn_agpref; /* preferred alloc group (hint) */ + int dn_aglevel; /* dmapctl level holding the AG */ + int dn_agheigth; /* height in dmapctl of the AG */ + int dn_agwidth; /* width in dmapctl of the AG */ + int dn_agstart; /* start tree index at AG height */ + int dn_agl2size; /* l2 num of blks per alloc group */ + s64 dn_agfree[MAXAG]; /* per AG free count */ + s64 dn_agsize; /* num of blks per alloc group */ + signed char dn_maxfreebud; /* max free buddy system */ +}; /* - 4096 - */ /* * in-memory aggregate disk allocation map descriptor. */ diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 6d62f3222892..c14ba3cfa818 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -315,8 +315,8 @@ static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp, lv = &llck->lv[llck->index]; /* - * Linelock slot size is twice the size of directory table - * slot size. 512 entries per page. + * Linelock slot size is twice the size of directory table + * slot size. 512 entries per page. */ lv->offset = ((index - 2) & 511) >> 1; lv->length = 1; @@ -615,7 +615,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, btstack->nsplit = 1; /* - * search down tree from root: + * search down tree from root: * * between two consecutive entries of and of * internal page, child page Pi contains entry with k, Ki <= K < Kj. @@ -659,7 +659,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, } if (cmp == 0) { /* - * search hit + * search hit */ /* search hit - leaf page: * return the entry found @@ -723,7 +723,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, } /* - * search miss + * search miss * * base is the smallest index with key (Kj) greater than * search key (K) and may be zero or (maxindex + 1) index. @@ -834,7 +834,7 @@ int dtInsert(tid_t tid, struct inode *ip, struct lv *lv; /* - * retrieve search result + * retrieve search result * * dtSearch() returns (leaf page pinned, index at which to insert). * n.b. dtSearch() may return index of (maxindex + 1) of @@ -843,7 +843,7 @@ int dtInsert(tid_t tid, struct inode *ip, DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); /* - * insert entry for new key + * insert entry for new key */ if (DO_INDEX(ip)) { if (JFS_IP(ip)->next_index == DIREND) { @@ -860,9 +860,9 @@ int dtInsert(tid_t tid, struct inode *ip, data.leaf.ino = *fsn; /* - * leaf page does not have enough room for new entry: + * leaf page does not have enough room for new entry: * - * extend/split the leaf page; + * extend/split the leaf page; * * dtSplitUp() will insert the entry and unpin the leaf page. */ @@ -877,9 +877,9 @@ int dtInsert(tid_t tid, struct inode *ip, } /* - * leaf page does have enough room for new entry: + * leaf page does have enough room for new entry: * - * insert the new data entry into the leaf page; + * insert the new data entry into the leaf page; */ BT_MARK_DIRTY(mp, ip); /* @@ -967,13 +967,13 @@ static int dtSplitUp(tid_t tid, } /* - * split leaf page + * split leaf page * * The split routines insert the new entry, and * acquire txLock as appropriate. */ /* - * split root leaf page: + * split root leaf page: */ if (sp->header.flag & BT_ROOT) { /* @@ -1012,7 +1012,7 @@ static int dtSplitUp(tid_t tid, } /* - * extend first leaf page + * extend first leaf page * * extend the 1st extent if less than buffer page size * (dtExtendPage() reurns leaf page unpinned) @@ -1068,7 +1068,7 @@ static int dtSplitUp(tid_t tid, } /* - * split leaf page into and a new right page . + * split leaf page into and a new right page . * * return pinned and its extent descriptor */ @@ -1433,7 +1433,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, rp->header.freecnt = rp->header.maxslot - fsi; /* - * sequential append at tail: append without split + * sequential append at tail: append without split * * If splitting the last page on a level because of appending * a entry to it (skip is maxentry), it's likely that the access is @@ -1467,7 +1467,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, } /* - * non-sequential insert (at possibly middle page) + * non-sequential insert (at possibly middle page) */ /* @@ -1508,7 +1508,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, left = 0; /* - * compute fill factor for split pages + * compute fill factor for split pages * * traces the next entry to move to rp * traces the next entry to stay in sp @@ -1551,7 +1551,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, /* poins to the 1st entry to move */ /* - * move entries to right page + * move entries to right page * * dtMoveEntry() initializes rp and reserves entry for insertion * @@ -1677,7 +1677,7 @@ static int dtExtendPage(tid_t tid, return (rc); /* - * extend the extent + * extend the extent */ pxdlist = split->pxdlist; pxd = &pxdlist->pxd[pxdlist->npxd]; @@ -1722,7 +1722,7 @@ static int dtExtendPage(tid_t tid, } /* - * extend the page + * extend the page */ sp->header.self = *pxd; @@ -1739,9 +1739,6 @@ static int dtExtendPage(tid_t tid, /* update buffer extent descriptor of extended page */ xlen = lengthPXD(pxd); xsize = xlen << JFS_SBI(sb)->l2bsize; -#ifdef _STILL_TO_PORT - bmSetXD(smp, xaddr, xsize); -#endif /* _STILL_TO_PORT */ /* * copy old stbl to new stbl at start of extended area @@ -1836,7 +1833,7 @@ static int dtExtendPage(tid_t tid, } /* - * update parent entry on the parent/root page + * update parent entry on the parent/root page */ /* * acquire a transaction lock on the parent/root page @@ -1904,7 +1901,7 @@ static int dtSplitRoot(tid_t tid, sp = &JFS_IP(ip)->i_dtroot; /* - * allocate/initialize a single (right) child page + * allocate/initialize a single (right) child page * * N.B. at first split, a one (or two) block to fit new entry * is allocated; at subsequent split, a full page is allocated; @@ -1943,7 +1940,7 @@ static int dtSplitRoot(tid_t tid, rp->header.prev = 0; /* - * move in-line root page into new right page extent + * move in-line root page into new right page extent */ /* linelock header + copied entries + new stbl (1st slot) in new page */ ASSERT(dtlck->index == 0); @@ -2016,7 +2013,7 @@ static int dtSplitRoot(tid_t tid, dtInsertEntry(rp, split->index, split->key, split->data, &dtlck); /* - * reset parent/root page + * reset parent/root page * * set the 1st entry offset to 0, which force the left-most key * at any level of the tree to be less than any search key. @@ -2102,7 +2099,7 @@ int dtDelete(tid_t tid, dtpage_t *np; /* - * search for the entry to delete: + * search for the entry to delete: * * dtSearch() returns (leaf page pinned, index at which to delete). */ @@ -2253,7 +2250,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, int i; /* - * keep the root leaf page which has become empty + * keep the root leaf page which has become empty */ if (BT_IS_ROOT(fmp)) { /* @@ -2269,7 +2266,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, } /* - * free the non-root leaf page + * free the non-root leaf page */ /* * acquire a transaction lock on the page @@ -2299,7 +2296,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, discard_metapage(fmp); /* - * propagate page deletion up the directory tree + * propagate page deletion up the directory tree * * If the delete from the parent page makes it empty, * continue all the way up the tree. @@ -2440,10 +2437,10 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, #ifdef _NOTYET /* - * NAME: dtRelocate() + * NAME: dtRelocate() * - * FUNCTION: relocate dtpage (internal or leaf) of directory; - * This function is mainly used by defragfs utility. + * FUNCTION: relocate dtpage (internal or leaf) of directory; + * This function is mainly used by defragfs utility. */ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, s64 nxaddr) @@ -2471,8 +2468,8 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, xlen); /* - * 1. get the internal parent dtpage covering - * router entry for the tartget page to be relocated; + * 1. get the internal parent dtpage covering + * router entry for the tartget page to be relocated; */ rc = dtSearchNode(ip, lmxaddr, opxd, &btstack); if (rc) @@ -2483,7 +2480,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, jfs_info("dtRelocate: parent router entry validated."); /* - * 2. relocate the target dtpage + * 2. relocate the target dtpage */ /* read in the target page from src extent */ DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); @@ -2581,9 +2578,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, /* update the buffer extent descriptor of the dtpage */ xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; -#ifdef _STILL_TO_PORT - bmSetXD(mp, nxaddr, xsize); -#endif /* _STILL_TO_PORT */ + /* unpin the relocated page */ DT_PUTPAGE(mp); jfs_info("dtRelocate: target dtpage relocated."); @@ -2594,7 +2589,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, */ /* - * 3. acquire maplock for the source extent to be freed; + * 3. acquire maplock for the source extent to be freed; */ /* for dtpage relocation, write a LOG_NOREDOPAGE record * for the source dtpage (logredo() will init NoRedoPage @@ -2609,7 +2604,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, pxdlock->index = 1; /* - * 4. update the parent router entry for relocation; + * 4. update the parent router entry for relocation; * * acquire tlck for the parent entry covering the target dtpage; * write LOG_REDOPAGE to apply after image only; @@ -2637,7 +2632,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, * NAME: dtSearchNode() * * FUNCTION: Search for an dtpage containing a specified address - * This function is mainly used by defragfs utility. + * This function is mainly used by defragfs utility. * * NOTE: Search result on stack, the found page is pinned at exit. * The result page must be an internal dtpage. @@ -2660,7 +2655,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd, BT_CLR(btstack); /* reset stack */ /* - * descend tree to the level with specified leftmost page + * descend tree to the level with specified leftmost page * * by convention, root bn = 0. */ @@ -2699,7 +2694,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd, } /* - * search each page at the current levevl + * search each page at the current levevl */ loop: stbl = DT_GETSTBL(p); @@ -3044,9 +3039,9 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (DO_INDEX(ip)) { /* * persistent index is stored in directory entries. - * Special cases: 0 = . - * 1 = .. - * -1 = End of directory + * Special cases: 0 = . + * 1 = .. + * -1 = End of directory */ do_index = 1; @@ -3128,10 +3123,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) /* * Legacy filesystem - OS/2 & Linux JFS < 0.3.6 * - * pn = index = 0: First entry "." - * pn = 0; index = 1: Second entry ".." - * pn > 0: Real entries, pn=1 -> leftmost page - * pn = index = -1: No more entries + * pn = index = 0: First entry "." + * pn = 0; index = 1: Second entry ".." + * pn > 0: Real entries, pn=1 -> leftmost page + * pn = index = -1: No more entries */ dtpos = filp->f_pos; if (dtpos == 0) { @@ -3351,7 +3346,7 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack) BT_CLR(btstack); /* reset stack */ /* - * descend leftmost path of the tree + * descend leftmost path of the tree * * by convention, root bn = 0. */ @@ -4531,7 +4526,7 @@ int dtModify(tid_t tid, struct inode *ip, struct ldtentry *entry; /* - * search for the entry to modify: + * search for the entry to modify: * * dtSearch() returns (leaf page pinned, index at which to modify). */ diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h index af8513f78648..8561c6ecece0 100644 --- a/fs/jfs/jfs_dtree.h +++ b/fs/jfs/jfs_dtree.h @@ -35,7 +35,7 @@ typedef union { /* - * entry segment/slot + * entry segment/slot * * an entry consists of type dependent head/only segment/slot and * additional segments/slots linked vi next field; diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index a35bdca6a805..7ae1e3281de9 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -34,8 +34,8 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *); #endif static s64 extRoundDown(s64 nb); -#define DPD(a) (printk("(a): %d\n",(a))) -#define DPC(a) (printk("(a): %c\n",(a))) +#define DPD(a) (printk("(a): %d\n",(a))) +#define DPC(a) (printk("(a): %c\n",(a))) #define DPL1(a) \ { \ if ((a) >> 32) \ @@ -51,19 +51,19 @@ static s64 extRoundDown(s64 nb); printk("(a): %x\n",(a) << 32); \ } -#define DPD1(a) (printk("(a): %d ",(a))) -#define DPX(a) (printk("(a): %08x\n",(a))) -#define DPX1(a) (printk("(a): %08x ",(a))) -#define DPS(a) (printk("%s\n",(a))) -#define DPE(a) (printk("\nENTERING: %s\n",(a))) -#define DPE1(a) (printk("\nENTERING: %s",(a))) -#define DPS1(a) (printk(" %s ",(a))) +#define DPD1(a) (printk("(a): %d ",(a))) +#define DPX(a) (printk("(a): %08x\n",(a))) +#define DPX1(a) (printk("(a): %08x ",(a))) +#define DPS(a) (printk("%s\n",(a))) +#define DPE(a) (printk("\nENTERING: %s\n",(a))) +#define DPE1(a) (printk("\nENTERING: %s",(a))) +#define DPS1(a) (printk(" %s ",(a))) /* * NAME: extAlloc() * - * FUNCTION: allocate an extent for a specified page range within a + * FUNCTION: allocate an extent for a specified page range within a * file. * * PARAMETERS: @@ -78,9 +78,9 @@ static s64 extRoundDown(s64 nb); * should be marked as allocated but not recorded. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ int extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) @@ -192,9 +192,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) #ifdef _NOTYET /* - * NAME: extRealloc() + * NAME: extRealloc() * - * FUNCTION: extend the allocation of a file extent containing a + * FUNCTION: extend the allocation of a file extent containing a * partial back last page. * * PARAMETERS: @@ -207,9 +207,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) * should be marked as allocated but not recorded. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) { @@ -345,9 +345,9 @@ exit: /* - * NAME: extHint() + * NAME: extHint() * - * FUNCTION: produce an extent allocation hint for a file offset. + * FUNCTION: produce an extent allocation hint for a file offset. * * PARAMETERS: * ip - the inode of the file. @@ -356,8 +356,8 @@ exit: * the hint. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. + * 0 - success + * -EIO - i/o error. */ int extHint(struct inode *ip, s64 offset, xad_t * xp) { @@ -387,7 +387,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) lxdl.nlxd = 1; lxdl.lxd = &lxd; LXDoffset(&lxd, prev) - LXDlength(&lxd, nbperpage); + LXDlength(&lxd, nbperpage); xadl.maxnxad = 1; xadl.nxad = 0; @@ -397,11 +397,11 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) return (rc); - /* check if not extent exists for the previous page. + /* check if no extent exists for the previous page. * this is possible for sparse files. */ if (xadl.nxad == 0) { -// assert(ISSPARSE(ip)); +// assert(ISSPARSE(ip)); return (0); } @@ -410,28 +410,28 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) */ xp->flag &= XAD_NOTRECORDED; - if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { + if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { jfs_error(ip->i_sb, "extHint: corrupt xtree"); return -EIO; - } + } return (0); } /* - * NAME: extRecord() + * NAME: extRecord() * - * FUNCTION: change a page with a file from not recorded to recorded. + * FUNCTION: change a page with a file from not recorded to recorded. * * PARAMETERS: * ip - inode of the file. * cp - cbuf of the file page. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ int extRecord(struct inode *ip, xad_t * xp) { @@ -451,9 +451,9 @@ int extRecord(struct inode *ip, xad_t * xp) #ifdef _NOTYET /* - * NAME: extFill() + * NAME: extFill() * - * FUNCTION: allocate disk space for a file page that represents + * FUNCTION: allocate disk space for a file page that represents * a file hole. * * PARAMETERS: @@ -461,16 +461,16 @@ int extRecord(struct inode *ip, xad_t * xp) * cp - cbuf of the file page represent the hole. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ int extFill(struct inode *ip, xad_t * xp) { int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage; s64 blkno = offsetXAD(xp) >> ip->i_blkbits; -// assert(ISSPARSE(ip)); +// assert(ISSPARSE(ip)); /* initialize the extent allocation hint */ XADaddress(xp, 0); @@ -489,7 +489,7 @@ int extFill(struct inode *ip, xad_t * xp) /* * NAME: extBalloc() * - * FUNCTION: allocate disk blocks to form an extent. + * FUNCTION: allocate disk blocks to form an extent. * * initially, we will try to allocate disk blocks for the * requested size (nblocks). if this fails (nblocks @@ -513,9 +513,9 @@ int extFill(struct inode *ip, xad_t * xp) * allocated block range. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ static int extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) @@ -580,7 +580,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) /* * NAME: extBrealloc() * - * FUNCTION: attempt to extend an extent's allocation. + * FUNCTION: attempt to extend an extent's allocation. * * Initially, we will try to extend the extent's allocation * in place. If this fails, we'll try to move the extent @@ -597,8 +597,8 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) * * PARAMETERS: * ip - the inode of the file. - * blkno - starting block number of the extents current allocation. - * nblks - number of blocks within the extents current allocation. + * blkno - starting block number of the extents current allocation. + * nblks - number of blocks within the extents current allocation. * newnblks - pointer to a s64 value. on entry, this value is the * the new desired extent size (number of blocks). on * successful exit, this value is set to the extent's actual @@ -606,9 +606,9 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) * newblkno - the starting block number of the extents new allocation. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOSPC - insufficient disk resources. + * 0 - success + * -EIO - i/o error. + * -ENOSPC - insufficient disk resources. */ static int extBrealloc(struct inode *ip, @@ -634,16 +634,16 @@ extBrealloc(struct inode *ip, /* - * NAME: extRoundDown() + * NAME: extRoundDown() * - * FUNCTION: round down a specified number of blocks to the next + * FUNCTION: round down a specified number of blocks to the next * smallest power of 2 number. * * PARAMETERS: * nb - the inode of the file. * * RETURN VALUES: - * next smallest power of 2 number. + * next smallest power of 2 number. */ static s64 extRoundDown(s64 nb) { diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h index 38f70ac03bec..b3f5463fbe52 100644 --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h @@ -34,9 +34,9 @@ #define JFS_UNICODE 0x00000001 /* unicode name */ /* mount time flags for error handling */ -#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */ -#define JFS_ERR_CONTINUE 0x00000004 /* continue */ -#define JFS_ERR_PANIC 0x00000008 /* panic */ +#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */ +#define JFS_ERR_CONTINUE 0x00000004 /* continue */ +#define JFS_ERR_PANIC 0x00000008 /* panic */ /* Quota support */ #define JFS_USRQUOTA 0x00000010 @@ -83,7 +83,6 @@ /* case-insensitive name/directory support */ #define JFS_AIX 0x80000000 /* AIX support */ -/* POSIX name/directory support - Never implemented*/ /* * buffer cache configuration @@ -113,10 +112,10 @@ #define IDATASIZE 256 /* inode inline data size */ #define IXATTRSIZE 128 /* inode inline extended attribute size */ -#define XTPAGE_SIZE 4096 -#define log2_PAGESIZE 12 +#define XTPAGE_SIZE 4096 +#define log2_PAGESIZE 12 -#define IAG_SIZE 4096 +#define IAG_SIZE 4096 #define IAG_EXTENT_SIZE 4096 #define INOSPERIAG 4096 /* number of disk inodes per iag */ #define L2INOSPERIAG 12 /* l2 number of disk inodes per iag */ diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index c6530227cda6..f5c5227b0d1f 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -93,21 +93,21 @@ static int copy_from_dinode(struct dinode *, struct inode *); static void copy_to_dinode(struct dinode *, struct inode *); /* - * NAME: diMount() + * NAME: diMount() * - * FUNCTION: initialize the incore inode map control structures for + * FUNCTION: initialize the incore inode map control structures for * a fileset or aggregate init time. * - * the inode map's control structure (dinomap) is - * brought in from disk and placed in virtual memory. + * the inode map's control structure (dinomap) is + * brought in from disk and placed in virtual memory. * * PARAMETERS: - * ipimap - pointer to inode map inode for the aggregate or fileset. + * ipimap - pointer to inode map inode for the aggregate or fileset. * * RETURN VALUES: - * 0 - success - * -ENOMEM - insufficient free virtual memory. - * -EIO - i/o error. + * 0 - success + * -ENOMEM - insufficient free virtual memory. + * -EIO - i/o error. */ int diMount(struct inode *ipimap) { @@ -180,18 +180,18 @@ int diMount(struct inode *ipimap) /* - * NAME: diUnmount() + * NAME: diUnmount() * - * FUNCTION: write to disk the incore inode map control structures for + * FUNCTION: write to disk the incore inode map control structures for * a fileset or aggregate at unmount time. * * PARAMETERS: - * ipimap - pointer to inode map inode for the aggregate or fileset. + * ipimap - pointer to inode map inode for the aggregate or fileset. * * RETURN VALUES: - * 0 - success - * -ENOMEM - insufficient free virtual memory. - * -EIO - i/o error. + * 0 - success + * -ENOMEM - insufficient free virtual memory. + * -EIO - i/o error. */ int diUnmount(struct inode *ipimap, int mounterror) { @@ -274,9 +274,9 @@ int diSync(struct inode *ipimap) /* - * NAME: diRead() + * NAME: diRead() * - * FUNCTION: initialize an incore inode from disk. + * FUNCTION: initialize an incore inode from disk. * * on entry, the specifed incore inode should itself * specify the disk inode number corresponding to the @@ -285,7 +285,7 @@ int diSync(struct inode *ipimap) * this routine handles incore inode initialization for * both "special" and "regular" inodes. special inodes * are those required early in the mount process and - * require special handling since much of the file system + * require special handling since much of the file system * is not yet initialized. these "special" inodes are * identified by a NULL inode map inode pointer and are * actually initialized by a call to diReadSpecial(). @@ -298,12 +298,12 @@ int diSync(struct inode *ipimap) * incore inode. * * PARAMETERS: - * ip - pointer to incore inode to be initialized from disk. + * ip - pointer to incore inode to be initialized from disk. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. - * -ENOMEM - insufficient memory + * 0 - success + * -EIO - i/o error. + * -ENOMEM - insufficient memory * */ int diRead(struct inode *ip) @@ -410,26 +410,26 @@ int diRead(struct inode *ip) /* - * NAME: diReadSpecial() + * NAME: diReadSpecial() * - * FUNCTION: initialize a 'special' inode from disk. + * FUNCTION: initialize a 'special' inode from disk. * * this routines handles aggregate level inodes. The * inode cache cannot differentiate between the * aggregate inodes and the filesystem inodes, so we * handle these here. We don't actually use the aggregate - * inode map, since these inodes are at a fixed location + * inode map, since these inodes are at a fixed location * and in some cases the aggregate inode map isn't initialized * yet. * * PARAMETERS: - * sb - filesystem superblock + * sb - filesystem superblock * inum - aggregate inode number * secondary - 1 if secondary aggregate inode table * * RETURN VALUES: - * new inode - success - * NULL - i/o error. + * new inode - success + * NULL - i/o error. */ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) { @@ -502,12 +502,12 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) } /* - * NAME: diWriteSpecial() + * NAME: diWriteSpecial() * - * FUNCTION: Write the special inode to disk + * FUNCTION: Write the special inode to disk * * PARAMETERS: - * ip - special inode + * ip - special inode * secondary - 1 if secondary aggregate inode table * * RETURN VALUES: none @@ -554,9 +554,9 @@ void diWriteSpecial(struct inode *ip, int secondary) } /* - * NAME: diFreeSpecial() + * NAME: diFreeSpecial() * - * FUNCTION: Free allocated space for special inode + * FUNCTION: Free allocated space for special inode */ void diFreeSpecial(struct inode *ip) { @@ -572,9 +572,9 @@ void diFreeSpecial(struct inode *ip) /* - * NAME: diWrite() + * NAME: diWrite() * - * FUNCTION: write the on-disk inode portion of the in-memory inode + * FUNCTION: write the on-disk inode portion of the in-memory inode * to its corresponding on-disk inode. * * on entry, the specifed incore inode should itself @@ -589,11 +589,11 @@ void diFreeSpecial(struct inode *ip) * * PARAMETERS: * tid - transacation id - * ip - pointer to incore inode to be written to the inode extent. + * ip - pointer to incore inode to be written to the inode extent. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. + * 0 - success + * -EIO - i/o error. */ int diWrite(tid_t tid, struct inode *ip) { @@ -730,7 +730,7 @@ int diWrite(tid_t tid, struct inode *ip) ilinelock = (struct linelock *) & tlck->lock; /* - * regular file: 16 byte (XAD slot) granularity + * regular file: 16 byte (XAD slot) granularity */ if (type & tlckXTREE) { xtpage_t *p, *xp; @@ -755,7 +755,7 @@ int diWrite(tid_t tid, struct inode *ip) xad->flag &= ~(XAD_NEW | XAD_EXTENDED); } /* - * directory: 32 byte (directory entry slot) granularity + * directory: 32 byte (directory entry slot) granularity */ else if (type & tlckDTREE) { dtpage_t *p, *xp; @@ -800,9 +800,8 @@ int diWrite(tid_t tid, struct inode *ip) } /* - * lock/copy inode base: 128 byte slot granularity + * lock/copy inode base: 128 byte slot granularity */ -// baseDinode: lv = & dilinelock->lv[dilinelock->index]; lv->offset = dioffset >> L2INODESLOTSIZE; copy_to_dinode(dp, ip); @@ -813,17 +812,6 @@ int diWrite(tid_t tid, struct inode *ip) lv->length = 1; dilinelock->index++; -#ifdef _JFS_FASTDASD - /* - * We aren't logging changes to the DASD used in directory inodes, - * but we need to write them to disk. If we don't unmount cleanly, - * mount will recalculate the DASD used. - */ - if (S_ISDIR(ip->i_mode) - && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED)) - memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd)); -#endif /* _JFS_FASTDASD */ - /* release the buffer holding the updated on-disk inode. * the buffer will be later written by commit processing. */ @@ -834,9 +822,9 @@ int diWrite(tid_t tid, struct inode *ip) /* - * NAME: diFree(ip) + * NAME: diFree(ip) * - * FUNCTION: free a specified inode from the inode working map + * FUNCTION: free a specified inode from the inode working map * for a fileset or aggregate. * * if the inode to be freed represents the first (only) @@ -865,11 +853,11 @@ int diWrite(tid_t tid, struct inode *ip) * any updates and are held until all updates are complete. * * PARAMETERS: - * ip - inode to be freed. + * ip - inode to be freed. * * RETURN VALUES: - * 0 - success - * -EIO - i/o error. + * 0 - success + * -EIO - i/o error. */ int diFree(struct inode *ip) { @@ -964,8 +952,8 @@ int diFree(struct inode *ip) return -EIO; } /* - * inode extent still has some inodes or below low water mark: - * keep the inode extent; + * inode extent still has some inodes or below low water mark: + * keep the inode extent; */ if (bitmap || imap->im_agctl[agno].numfree < 96 || @@ -1047,12 +1035,12 @@ int diFree(struct inode *ip) /* - * inode extent has become free and above low water mark: - * free the inode extent; + * inode extent has become free and above low water mark: + * free the inode extent; */ /* - * prepare to update iag list(s) (careful update step 1) + * prepare to update iag list(s) (careful update step 1) */ amp = bmp = cmp = dmp = NULL; fwd = back = -1; @@ -1152,7 +1140,7 @@ int diFree(struct inode *ip) invalidate_pxd_metapages(ip, freepxd); /* - * update iag list(s) (careful update step 2) + * update iag list(s) (careful update step 2) */ /* add the iag to the ag extent free list if this is the * first free extent for the iag. @@ -1338,20 +1326,20 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) /* - * NAME: diAlloc(pip,dir,ip) + * NAME: diAlloc(pip,dir,ip) * - * FUNCTION: allocate a disk inode from the inode working map + * FUNCTION: allocate a disk inode from the inode working map * for a fileset or aggregate. * * PARAMETERS: - * pip - pointer to incore inode for the parent inode. - * dir - 'true' if the new disk inode is for a directory. - * ip - pointer to a new inode + * pip - pointer to incore inode for the parent inode. + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to a new inode * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ int diAlloc(struct inode *pip, bool dir, struct inode *ip) { @@ -1433,7 +1421,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts); /* - * try to allocate from the IAG + * try to allocate from the IAG */ /* check if the inode may be allocated from the iag * (i.e. the inode has free inodes or new extent can be added). @@ -1633,9 +1621,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) /* - * NAME: diAllocAG(imap,agno,dir,ip) + * NAME: diAllocAG(imap,agno,dir,ip) * - * FUNCTION: allocate a disk inode from the allocation group. + * FUNCTION: allocate a disk inode from the allocation group. * * this routine first determines if a new extent of free * inodes should be added for the allocation group, with @@ -1649,17 +1637,17 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) * PRE CONDITION: Already have the AG lock for this AG. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group to allocate from. - * dir - 'true' if the new disk inode is for a directory. - * ip - pointer to the new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group to allocate from. + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to the new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) @@ -1709,9 +1697,9 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) /* - * NAME: diAllocAny(imap,agno,dir,iap) + * NAME: diAllocAny(imap,agno,dir,iap) * - * FUNCTION: allocate a disk inode from any other allocation group. + * FUNCTION: allocate a disk inode from any other allocation group. * * this routine is called when an allocation attempt within * the primary allocation group has failed. if attempts to @@ -1719,17 +1707,17 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) * specified primary group. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - primary allocation group (to avoid). - * dir - 'true' if the new disk inode is for a directory. - * ip - pointer to a new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - primary allocation group (to avoid). + * dir - 'true' if the new disk inode is for a directory. + * ip - pointer to a new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) @@ -1772,9 +1760,9 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) /* - * NAME: diAllocIno(imap,agno,ip) + * NAME: diAllocIno(imap,agno,ip) * - * FUNCTION: allocate a disk inode from the allocation group's free + * FUNCTION: allocate a disk inode from the allocation group's free * inode list, returning an error if this free list is * empty (i.e. no iags on the list). * @@ -1785,16 +1773,16 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) * PRE CONDITION: Already have AG lock for this AG. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group. - * ip - pointer to new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group. + * ip - pointer to new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) { @@ -1890,7 +1878,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) /* - * NAME: diAllocExt(imap,agno,ip) + * NAME: diAllocExt(imap,agno,ip) * * FUNCTION: add a new extent of free inodes to an iag, allocating * an inode from this extent to satisfy the current allocation @@ -1910,16 +1898,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) * for the purpose of satisfying this request. * * PARAMETERS: - * imap - pointer to inode map control structure. - * agno - allocation group number. - * ip - pointer to new inode to be filled in on successful return + * imap - pointer to inode map control structure. + * agno - allocation group number. + * ip - pointer to new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) { @@ -2010,7 +1998,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) /* - * NAME: diAllocBit(imap,iagp,ino) + * NAME: diAllocBit(imap,iagp,ino) * * FUNCTION: allocate a backed inode from an iag. * @@ -2030,14 +2018,14 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) * this AG. Must have read lock on imap inode. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagp - pointer to iag. - * ino - inode number to be allocated within the iag. + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * ino - inode number to be allocated within the iag. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) { @@ -2144,11 +2132,11 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) /* - * NAME: diNewExt(imap,iagp,extno) + * NAME: diNewExt(imap,iagp,extno) * - * FUNCTION: initialize a new extent of inodes for an iag, allocating - * the first inode of the extent for use for the current - * allocation request. + * FUNCTION: initialize a new extent of inodes for an iag, allocating + * the first inode of the extent for use for the current + * allocation request. * * disk resources are allocated for the new extent of inodes * and the inodes themselves are initialized to reflect their @@ -2177,14 +2165,14 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) * this AG. Must have read lock on imap inode. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagp - pointer to iag. - * extno - extent number. + * imap - pointer to inode map control structure. + * iagp - pointer to iag. + * extno - extent number. * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. */ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) { @@ -2430,7 +2418,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) /* - * NAME: diNewIAG(imap,iagnop,agno) + * NAME: diNewIAG(imap,iagnop,agno) * * FUNCTION: allocate a new iag for an allocation group. * @@ -2443,16 +2431,16 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) * and returned to satisfy the request. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagnop - pointer to an iag number set with the number of the + * imap - pointer to inode map control structure. + * iagnop - pointer to an iag number set with the number of the * newly allocated iag upon successful return. - * agno - allocation group number. + * agno - allocation group number. * bpp - Buffer pointer to be filled in with new IAG's buffer * * RETURN VALUES: - * 0 - success. - * -ENOSPC - insufficient disk resources. - * -EIO - i/o error. + * 0 - success. + * -ENOSPC - insufficient disk resources. + * -EIO - i/o error. * * serialization: * AG lock held on entry/exit; @@ -2461,7 +2449,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) * * note: new iag transaction: * . synchronously write iag; - * . write log of xtree and inode of imap; + * . write log of xtree and inode of imap; * . commit; * . synchronous write of xtree (right to left, bottom to top); * . at start of logredo(): init in-memory imap with one additional iag page; @@ -2481,9 +2469,6 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) s64 xaddr = 0; s64 blkno; tid_t tid; -#ifdef _STILL_TO_PORT - xad_t xad; -#endif /* _STILL_TO_PORT */ struct inode *iplist[1]; /* pick up pointers to the inode map and mount inodes */ @@ -2674,15 +2659,15 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) } /* - * NAME: diIAGRead() + * NAME: diIAGRead() * - * FUNCTION: get the buffer for the specified iag within a fileset + * FUNCTION: get the buffer for the specified iag within a fileset * or aggregate inode map. * * PARAMETERS: - * imap - pointer to inode map control structure. - * iagno - iag number. - * bpp - point to buffer pointer to be filled in on successful + * imap - pointer to inode map control structure. + * iagno - iag number. + * bpp - point to buffer pointer to be filled in on successful * exit. * * SERIALIZATION: @@ -2691,8 +2676,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) * the read lock is unnecessary.) * * RETURN VALUES: - * 0 - success. - * -EIO - i/o error. + * 0 - success. + * -EIO - i/o error. */ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp) { @@ -2712,17 +2697,17 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp) } /* - * NAME: diFindFree() + * NAME: diFindFree() * - * FUNCTION: find the first free bit in a word starting at + * FUNCTION: find the first free bit in a word starting at * the specified bit position. * * PARAMETERS: - * word - word to be examined. - * start - starting bit position. + * word - word to be examined. + * start - starting bit position. * * RETURN VALUES: - * bit position of first free bit in the word or 32 if + * bit position of first free bit in the word or 32 if * no free bits were found. */ static int diFindFree(u32 word, int start) @@ -2897,7 +2882,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) atomic_read(&imap->im_numfree)); /* - * reconstruct imap + * reconstruct imap * * coalesce contiguous k (newAGSize/oldAGSize) AGs; * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn; @@ -2913,7 +2898,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) } /* - * process each iag page of the map. + * process each iag page of the map. * * rebuild AG Free Inode List, AG Free Inode Extent List; */ @@ -2932,7 +2917,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap) /* leave free iag in the free iag list */ if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { - release_metapage(bp); + release_metapage(bp); continue; } @@ -3063,13 +3048,13 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, } /* - * NAME: copy_from_dinode() + * NAME: copy_from_dinode() * - * FUNCTION: Copies inode info from disk inode to in-memory inode + * FUNCTION: Copies inode info from disk inode to in-memory inode * * RETURN VALUES: - * 0 - success - * -ENOMEM - insufficient memory + * 0 - success + * -ENOMEM - insufficient memory */ static int copy_from_dinode(struct dinode * dip, struct inode *ip) { @@ -3151,9 +3136,9 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) } /* - * NAME: copy_to_dinode() + * NAME: copy_to_dinode() * - * FUNCTION: Copies inode info from in-memory inode to disk inode + * FUNCTION: Copies inode info from in-memory inode to disk inode */ static void copy_to_dinode(struct dinode * dip, struct inode *ip) { diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h index 4f9c346ed498..610a0e9d8941 100644 --- a/fs/jfs/jfs_imap.h +++ b/fs/jfs/jfs_imap.h @@ -24,17 +24,17 @@ * jfs_imap.h: disk inode manager */ -#define EXTSPERIAG 128 /* number of disk inode extent per iag */ -#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */ -#define SMAPSZ 4 /* number of words per summary map */ +#define EXTSPERIAG 128 /* number of disk inode extent per iag */ +#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */ +#define SMAPSZ 4 /* number of words per summary map */ #define EXTSPERSUM 32 /* number of extents per summary map entry */ #define L2EXTSPERSUM 5 /* l2 number of extents per summary map */ #define PGSPERIEXT 4 /* number of 4K pages per dinode extent */ -#define MAXIAGS ((1<<20)-1) /* maximum number of iags */ -#define MAXAG 128 /* maximum number of allocation groups */ +#define MAXIAGS ((1<<20)-1) /* maximum number of iags */ +#define MAXAG 128 /* maximum number of allocation groups */ -#define AMAPSIZE 512 /* bytes in the IAG allocation maps */ -#define SMAPSIZE 16 /* bytes in the IAG summary maps */ +#define AMAPSIZE 512 /* bytes in the IAG allocation maps */ +#define SMAPSIZE 16 /* bytes in the IAG summary maps */ /* convert inode number to iag number */ #define INOTOIAG(ino) ((ino) >> L2INOSPERIAG) @@ -60,31 +60,31 @@ * inode allocation group page (per 4096 inodes of an AG) */ struct iag { - __le64 agstart; /* 8: starting block of ag */ - __le32 iagnum; /* 4: inode allocation group number */ - __le32 inofreefwd; /* 4: ag inode free list forward */ - __le32 inofreeback; /* 4: ag inode free list back */ - __le32 extfreefwd; /* 4: ag inode extent free list forward */ - __le32 extfreeback; /* 4: ag inode extent free list back */ - __le32 iagfree; /* 4: iag free list */ + __le64 agstart; /* 8: starting block of ag */ + __le32 iagnum; /* 4: inode allocation group number */ + __le32 inofreefwd; /* 4: ag inode free list forward */ + __le32 inofreeback; /* 4: ag inode free list back */ + __le32 extfreefwd; /* 4: ag inode extent free list forward */ + __le32 extfreeback; /* 4: ag inode extent free list back */ + __le32 iagfree; /* 4: iag free list */ /* summary map: 1 bit per inode extent */ __le32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes; - * note: this indicates free and backed - * inodes, if the extent is not backed the - * value will be 1. if the extent is - * backed but all inodes are being used the - * value will be 1. if the extent is - * backed but at least one of the inodes is - * free the value will be 0. + * note: this indicates free and backed + * inodes, if the extent is not backed the + * value will be 1. if the extent is + * backed but all inodes are being used the + * value will be 1. if the extent is + * backed but at least one of the inodes is + * free the value will be 0. */ __le32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */ - __le32 nfreeinos; /* 4: number of free inodes */ - __le32 nfreeexts; /* 4: number of free extents */ + __le32 nfreeinos; /* 4: number of free inodes */ + __le32 nfreeexts; /* 4: number of free extents */ /* (72) */ u8 pad[1976]; /* 1976: pad to 2048 bytes */ /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */ - __le32 wmap[EXTSPERIAG]; /* 512: working allocation map */ + __le32 wmap[EXTSPERIAG]; /* 512: working allocation map */ __le32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */ pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */ }; /* (4096) */ @@ -93,44 +93,44 @@ struct iag { * per AG control information (in inode map control page) */ struct iagctl_disk { - __le32 inofree; /* 4: free inode list anchor */ - __le32 extfree; /* 4: free extent list anchor */ - __le32 numinos; /* 4: number of backed inodes */ - __le32 numfree; /* 4: number of free inodes */ + __le32 inofree; /* 4: free inode list anchor */ + __le32 extfree; /* 4: free extent list anchor */ + __le32 numinos; /* 4: number of backed inodes */ + __le32 numfree; /* 4: number of free inodes */ }; /* (16) */ struct iagctl { - int inofree; /* free inode list anchor */ - int extfree; /* free extent list anchor */ - int numinos; /* number of backed inodes */ - int numfree; /* number of free inodes */ + int inofree; /* free inode list anchor */ + int extfree; /* free extent list anchor */ + int numinos; /* number of backed inodes */ + int numfree; /* number of free inodes */ }; /* * per fileset/aggregate inode map control page */ struct dinomap_disk { - __le32 in_freeiag; /* 4: free iag list anchor */ - __le32 in_nextiag; /* 4: next free iag number */ - __le32 in_numinos; /* 4: num of backed inodes */ + __le32 in_freeiag; /* 4: free iag list anchor */ + __le32 in_nextiag; /* 4: next free iag number */ + __le32 in_numinos; /* 4: num of backed inodes */ __le32 in_numfree; /* 4: num of free backed inodes */ __le32 in_nbperiext; /* 4: num of blocks per inode extent */ - __le32 in_l2nbperiext; /* 4: l2 of in_nbperiext */ - __le32 in_diskblock; /* 4: for standalone test driver */ - __le32 in_maxag; /* 4: for standalone test driver */ - u8 pad[2016]; /* 2016: pad to 2048 */ + __le32 in_l2nbperiext; /* 4: l2 of in_nbperiext */ + __le32 in_diskblock; /* 4: for standalone test driver */ + __le32 in_maxag; /* 4: for standalone test driver */ + u8 pad[2016]; /* 2016: pad to 2048 */ struct iagctl_disk in_agctl[MAXAG]; /* 2048: AG control information */ }; /* (4096) */ struct dinomap { - int in_freeiag; /* free iag list anchor */ - int in_nextiag; /* next free iag number */ - int in_numinos; /* num of backed inodes */ - int in_numfree; /* num of free backed inodes */ + int in_freeiag; /* free iag list anchor */ + int in_nextiag; /* next free iag number */ + int in_numinos; /* num of backed inodes */ + int in_numfree; /* num of free backed inodes */ int in_nbperiext; /* num of blocks per inode extent */ - int in_l2nbperiext; /* l2 of in_nbperiext */ - int in_diskblock; /* for standalone test driver */ - int in_maxag; /* for standalone test driver */ + int in_l2nbperiext; /* l2 of in_nbperiext */ + int in_diskblock; /* for standalone test driver */ + int in_maxag; /* for standalone test driver */ struct iagctl in_agctl[MAXAG]; /* AG control information */ }; @@ -139,9 +139,9 @@ struct dinomap { */ struct inomap { struct dinomap im_imap; /* 4096: inode allocation control */ - struct inode *im_ipimap; /* 4: ptr to inode for imap */ - struct mutex im_freelock; /* 4: iag free list lock */ - struct mutex im_aglock[MAXAG]; /* 512: per AG locks */ + struct inode *im_ipimap; /* 4: ptr to inode for imap */ + struct mutex im_freelock; /* 4: iag free list lock */ + struct mutex im_aglock[MAXAG]; /* 512: per AG locks */ u32 *im_DBGdimap; atomic_t im_numinos; /* num of backed inodes */ atomic_t im_numfree; /* num of free backed inodes */ diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 8f453eff3c83..cb8f30985ad1 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h @@ -40,7 +40,7 @@ struct jfs_inode_info { uint mode2; /* jfs-specific mode */ uint saved_uid; /* saved for uid mount option */ uint saved_gid; /* saved for gid mount option */ - pxd_t ixpxd; /* inode extent descriptor */ + pxd_t ixpxd; /* inode extent descriptor */ dxd_t acl; /* dxd describing acl */ dxd_t ea; /* dxd describing ea */ time_t otime; /* time created */ @@ -190,7 +190,7 @@ struct jfs_sb_info { uint gengen; /* inode generation generator*/ uint inostamp; /* shows inode belongs to fileset*/ - /* Formerly in ipbmap */ + /* Formerly in ipbmap */ struct bmap *bmap; /* incore bmap descriptor */ struct nls_table *nls_tab; /* current codepage */ struct inode *direct_inode; /* metadata inode */ diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 44a2f33cb98d..88eae45a4644 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -244,7 +244,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, goto writeRecord; /* - * initialize/update page/transaction recovery lsn + * initialize/update page/transaction recovery lsn */ lsn = log->lsn; @@ -263,7 +263,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * initialize/update lsn of tblock of the page + * initialize/update lsn of tblock of the page * * transaction inherits oldest lsn of pages associated * with allocation/deallocation of resources (their @@ -307,7 +307,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, LOGSYNC_UNLOCK(log, flags); /* - * write the log record + * write the log record */ writeRecord: lsn = lmWriteRecord(log, tblk, lrd, tlck); @@ -372,7 +372,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, goto moveLrd; /* - * move log record data + * move log record data */ /* retrieve source meta-data page to log */ if (tlck->flag & tlckPAGELOCK) { @@ -465,7 +465,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * move log record descriptor + * move log record descriptor */ moveLrd: lrd->length = cpu_to_le16(len); @@ -574,7 +574,7 @@ static int lmNextPage(struct jfs_log * log) LOGGC_LOCK(log); /* - * write or queue the full page at the tail of write queue + * write or queue the full page at the tail of write queue */ /* get the tail tblk on commit queue */ if (list_empty(&log->cqueue)) @@ -625,7 +625,7 @@ static int lmNextPage(struct jfs_log * log) LOGGC_UNLOCK(log); /* - * allocate/initialize next page + * allocate/initialize next page */ /* if log wraps, the first data page of log is 2 * (0 never used, 1 is superblock). @@ -953,7 +953,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync) } /* - * forward syncpt + * forward syncpt */ /* if last sync is same as last syncpt, * invoke sync point forward processing to update sync. @@ -989,7 +989,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync) lsn = log->lsn; /* - * setup next syncpt trigger (SWAG) + * setup next syncpt trigger (SWAG) */ logsize = log->logsize; @@ -1000,11 +1000,11 @@ static int lmLogSync(struct jfs_log * log, int hard_sync) if (more < 2 * LOGPSIZE) { jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n"); /* - * log wrapping + * log wrapping * * option 1 - panic ? No.! * option 2 - shutdown file systems - * associated with log ? + * associated with log ? * option 3 - extend log ? */ /* @@ -1062,7 +1062,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync) /* * NAME: lmLogOpen() * - * FUNCTION: open the log on first open; + * FUNCTION: open the log on first open; * insert filesystem in the active list of the log. * * PARAMETER: ipmnt - file system mount inode @@ -1113,7 +1113,7 @@ int lmLogOpen(struct super_block *sb) init_waitqueue_head(&log->syncwait); /* - * external log as separate logical volume + * external log as separate logical volume * * file systems to log may have n-to-1 relationship; */ @@ -1155,7 +1155,7 @@ journal_found: return 0; /* - * unwind on error + * unwind on error */ shutdown: /* unwind lbmLogInit() */ list_del(&log->journal_list); @@ -1427,7 +1427,7 @@ int lmLogInit(struct jfs_log * log) return 0; /* - * unwind on error + * unwind on error */ errout30: /* release log page */ log->wqueue = NULL; @@ -1480,7 +1480,7 @@ int lmLogClose(struct super_block *sb) if (test_bit(log_INLINELOG, &log->flag)) { /* - * in-line log in host file system + * in-line log in host file system */ rc = lmLogShutdown(log); kfree(log); @@ -1504,7 +1504,7 @@ int lmLogClose(struct super_block *sb) goto out; /* - * external log as separate logical volume + * external log as separate logical volume */ list_del(&log->journal_list); bdev = log->bdev; @@ -1723,7 +1723,7 @@ int lmLogShutdown(struct jfs_log * log) * * PARAMETE: log - pointer to logs inode. * fsdev - kdev_t of filesystem. - * serial - pointer to returned log serial number + * serial - pointer to returned log serial number * activate - insert/remove device from active list. * * RETURN: 0 - success @@ -1963,7 +1963,7 @@ static void lbmfree(struct lbuf * bp) * FUNCTION: add a log buffer to the log redrive list * * PARAMETER: - * bp - log buffer + * bp - log buffer * * NOTES: * Takes log_redrive_lock. @@ -2054,7 +2054,7 @@ static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, bp->l_flag = flag; /* - * insert bp at tail of write queue associated with log + * insert bp at tail of write queue associated with log * * (request is either for bp already/currently at head of queue * or new bp to be inserted at tail) @@ -2117,7 +2117,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag) log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); /* - * initiate pageout of the page + * initiate pageout of the page */ lbmStartIO(bp); } @@ -2128,7 +2128,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag) * * FUNCTION: Interface to DD strategy routine * - * RETURN: none + * RETURN: none * * serialization: LCACHE_LOCK() is NOT held during log i/o; */ @@ -2222,7 +2222,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) bio_put(bio); /* - * pagein completion + * pagein completion */ if (bp->l_flag & lbmREAD) { bp->l_flag &= ~lbmREAD; @@ -2236,7 +2236,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) } /* - * pageout completion + * pageout completion * * the bp at the head of write queue has completed pageout. * @@ -2302,7 +2302,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) } /* - * synchronous pageout: + * synchronous pageout: * * buffer has not necessarily been removed from write queue * (e.g., synchronous write of partial-page with COMMIT): @@ -2316,7 +2316,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) } /* - * Group Commit pageout: + * Group Commit pageout: */ else if (bp->l_flag & lbmGC) { LCACHE_UNLOCK(flags); @@ -2324,7 +2324,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error) } /* - * asynchronous pageout: + * asynchronous pageout: * * buffer must have been removed from write queue: * insert buffer at head of freelist where it can be recycled @@ -2375,7 +2375,7 @@ int jfsIOWait(void *arg) * FUNCTION: format file system log * * PARAMETERS: - * log - volume log + * log - volume log * logAddress - start address of log space in FS block * logSize - length of log space in FS block; * @@ -2407,16 +2407,16 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) npages = logSize >> sbi->l2nbperpage; /* - * log space: + * log space: * * page 0 - reserved; * page 1 - log superblock; * page 2 - log data page: A SYNC log record is written - * into this page at logform time; + * into this page at logform time; * pages 3-N - log data page: set to empty log data pages; */ /* - * init log superblock: log page 1 + * init log superblock: log page 1 */ logsuper = (struct logsuper *) bp->l_ldata; @@ -2436,7 +2436,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) goto exit; /* - * init pages 2 to npages-1 as log data pages: + * init pages 2 to npages-1 as log data pages: * * log page sequence number (lpsn) initialization: * @@ -2479,7 +2479,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) goto exit; /* - * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2) + * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2) */ for (lspn = 0; lspn < npages - 3; lspn++) { lp->h.page = lp->t.page = cpu_to_le32(lspn); @@ -2495,7 +2495,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) rc = 0; exit: /* - * finalize log + * finalize log */ /* release the buffer */ lbmFree(bp); diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index a53fb17ea219..1f85ef0ec045 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -144,7 +144,7 @@ struct logpage { * * (this comment should be rewritten !) * jfs uses only "after" log records (only a single writer is allowed - * in a page, pages are written to temporary paging space if + * in a page, pages are written to temporary paging space if * if they must be written to disk before commit, and i/o is * scheduled for modified pages to their home location after * the log records containing the after values and the commit @@ -153,7 +153,7 @@ struct logpage { * * a log record consists of a data area of variable length followed by * a descriptor of fixed size LOGRDSIZE bytes. - * the data area is rounded up to an integral number of 4-bytes and + * the data area is rounded up to an integral number of 4-bytes and * must be no longer than LOGPSIZE. * the descriptor is of size of multiple of 4-bytes and aligned on a * 4-byte boundary. @@ -215,13 +215,13 @@ struct lrd { union { /* - * COMMIT: commit + * COMMIT: commit * * transaction commit: no type-dependent information; */ /* - * REDOPAGE: after-image + * REDOPAGE: after-image * * apply after-image; * @@ -236,7 +236,7 @@ struct lrd { } redopage; /* (20) */ /* - * NOREDOPAGE: the page is freed + * NOREDOPAGE: the page is freed * * do not apply after-image records which precede this record * in the log with the same page block number to this page. @@ -252,7 +252,7 @@ struct lrd { } noredopage; /* (20) */ /* - * UPDATEMAP: update block allocation map + * UPDATEMAP: update block allocation map * * either in-line PXD, * or out-of-line XADLIST; @@ -268,7 +268,7 @@ struct lrd { } updatemap; /* (20) */ /* - * NOREDOINOEXT: the inode extent is freed + * NOREDOINOEXT: the inode extent is freed * * do not apply after-image records which precede this * record in the log with the any of the 4 page block @@ -286,7 +286,7 @@ struct lrd { } noredoinoext; /* (20) */ /* - * SYNCPT: log sync point + * SYNCPT: log sync point * * replay log upto syncpt address specified; */ @@ -295,13 +295,13 @@ struct lrd { } syncpt; /* - * MOUNT: file system mount + * MOUNT: file system mount * * file system mount: no type-dependent information; */ /* - * ? FREEXTENT: free specified extent(s) + * ? FREEXTENT: free specified extent(s) * * free specified extent(s) from block allocation map * N.B.: nextents should be length of data/sizeof(xad_t) @@ -314,7 +314,7 @@ struct lrd { } freextent; /* - * ? NOREDOFILE: this file is freed + * ? NOREDOFILE: this file is freed * * do not apply records which precede this record in the log * with the same inode number. @@ -330,7 +330,7 @@ struct lrd { } noredofile; /* - * ? NEWPAGE: + * ? NEWPAGE: * * metadata type dependent */ @@ -342,7 +342,7 @@ struct lrd { } newpage; /* - * ? DUMMY: filler + * ? DUMMY: filler * * no type-dependent information */ diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 4dd479834897..644429acb8c0 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -80,7 +80,7 @@ static int logMOUNT(struct super_block *sb); */ int jfs_mount(struct super_block *sb) { - int rc = 0; /* Return code */ + int rc = 0; /* Return code */ struct jfs_sb_info *sbi = JFS_SBI(sb); struct inode *ipaimap = NULL; struct inode *ipaimap2 = NULL; @@ -169,7 +169,7 @@ int jfs_mount(struct super_block *sb) sbi->ipaimap2 = NULL; /* - * mount (the only/single) fileset + * mount (the only/single) fileset */ /* * open fileset inode allocation map (aka fileset inode) @@ -195,7 +195,7 @@ int jfs_mount(struct super_block *sb) goto out; /* - * unwind on error + * unwind on error */ errout41: /* close fileset inode allocation map inode */ diFreeSpecial(ipimap); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 25430d0b0d59..f2dc4b986392 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -18,7 +18,7 @@ */ /* - * jfs_txnmgr.c: transaction manager + * jfs_txnmgr.c: transaction manager * * notes: * transaction starts with txBegin() and ends with txCommit() @@ -60,7 +60,7 @@ #include "jfs_debug.h" /* - * transaction management structures + * transaction management structures */ static struct { int freetid; /* index of a free tid structure */ @@ -103,19 +103,19 @@ module_param(nTxLock, int, 0); MODULE_PARM_DESC(nTxLock, "Number of transaction locks (max:65536)"); -struct tblock *TxBlock; /* transaction block table */ -static int TxLockLWM; /* Low water mark for number of txLocks used */ -static int TxLockHWM; /* High water mark for number of txLocks used */ -static int TxLockVHWM; /* Very High water mark */ -struct tlock *TxLock; /* transaction lock table */ +struct tblock *TxBlock; /* transaction block table */ +static int TxLockLWM; /* Low water mark for number of txLocks used */ +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 + * transaction management lock */ static DEFINE_SPINLOCK(jfsTxnLock); -#define TXN_LOCK() spin_lock(&jfsTxnLock) -#define TXN_UNLOCK() spin_unlock(&jfsTxnLock) +#define TXN_LOCK() spin_lock(&jfsTxnLock) +#define TXN_UNLOCK() spin_unlock(&jfsTxnLock) #define LAZY_LOCK_INIT() spin_lock_init(&TxAnchor.LazyLock); #define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags) @@ -148,7 +148,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event) #define TXN_WAKEUP(event) wake_up_all(event) /* - * statistics + * statistics */ static struct { tid_t maxtid; /* 4: biggest tid ever used */ @@ -181,8 +181,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, static void LogSyncRelease(struct metapage * mp); /* - * transaction block/lock management - * --------------------------------- + * transaction block/lock management + * --------------------------------- */ /* @@ -227,9 +227,9 @@ static void txLockFree(lid_t lid) } /* - * NAME: txInit() + * NAME: txInit() * - * FUNCTION: initialize transaction management structures + * FUNCTION: initialize transaction management structures * * RETURN: * @@ -333,9 +333,9 @@ int txInit(void) } /* - * NAME: txExit() + * NAME: txExit() * - * FUNCTION: clean up when module is unloaded + * FUNCTION: clean up when module is unloaded */ void txExit(void) { @@ -346,12 +346,12 @@ void txExit(void) } /* - * NAME: txBegin() + * NAME: txBegin() * - * FUNCTION: start a transaction. + * FUNCTION: start a transaction. * - * PARAMETER: sb - superblock - * flag - force for nested tx; + * PARAMETER: sb - superblock + * flag - force for nested tx; * * RETURN: tid - transaction id * @@ -447,13 +447,13 @@ tid_t txBegin(struct super_block *sb, int flag) } /* - * NAME: txBeginAnon() + * NAME: txBeginAnon() * - * FUNCTION: start an anonymous transaction. + * FUNCTION: start an anonymous transaction. * Blocks if logsync or available tlocks are low to prevent * anonymous tlocks from depleting supply. * - * PARAMETER: sb - superblock + * PARAMETER: sb - superblock * * RETURN: none */ @@ -489,11 +489,11 @@ void txBeginAnon(struct super_block *sb) } /* - * txEnd() + * txEnd() * * function: free specified transaction block. * - * logsync barrier processing: + * logsync barrier processing: * * serialization: */ @@ -577,13 +577,13 @@ wakeup: } /* - * txLock() + * txLock() * * function: acquire a transaction lock on the specified * * parameter: * - * return: transaction lock id + * return: transaction lock id * * serialization: */ @@ -857,17 +857,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, } /* - * NAME: txRelease() + * NAME: txRelease() * - * FUNCTION: Release buffers associated with transaction locks, but don't + * FUNCTION: Release buffers associated with transaction locks, but don't * mark homeok yet. The allows other transactions to modify * buffers, but won't let them go to disk until commit record * actually gets written. * * PARAMETER: - * tblk - + * tblk - * - * RETURN: Errors from subroutines. + * RETURN: Errors from subroutines. */ static void txRelease(struct tblock * tblk) { @@ -896,10 +896,10 @@ static void txRelease(struct tblock * tblk) } /* - * NAME: txUnlock() + * NAME: txUnlock() * - * FUNCTION: Initiates pageout of pages modified by tid in journalled - * objects and frees their lockwords. + * FUNCTION: Initiates pageout of pages modified by tid in journalled + * objects and frees their lockwords. */ static void txUnlock(struct tblock * tblk) { @@ -983,10 +983,10 @@ static void txUnlock(struct tblock * tblk) } /* - * txMaplock() + * txMaplock() * * function: allocate a transaction lock for freed page/entry; - * for freed page, maplock is used as xtlock/dtlock type; + * for freed page, maplock is used as xtlock/dtlock type; */ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type) { @@ -1057,7 +1057,7 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type) } /* - * txLinelock() + * txLinelock() * * function: allocate a transaction lock for log vector list */ @@ -1092,39 +1092,39 @@ struct linelock *txLinelock(struct linelock * tlock) } /* - * transaction commit management - * ----------------------------- + * transaction commit management + * ----------------------------- */ /* - * NAME: txCommit() + * NAME: txCommit() * - * FUNCTION: commit the changes to the objects specified in - * clist. For journalled segments only the - * changes of the caller are committed, ie by tid. - * for non-journalled segments the data are flushed to - * disk and then the change to the disk inode and indirect - * blocks committed (so blocks newly allocated to the - * segment will be made a part of the segment atomically). + * FUNCTION: commit the changes to the objects specified in + * clist. For journalled segments only the + * changes of the caller are committed, ie by tid. + * for non-journalled segments the data are flushed to + * disk and then the change to the disk inode and indirect + * blocks committed (so blocks newly allocated to the + * segment will be made a part of the segment atomically). * - * all of the segments specified in clist must be in - * one file system. no more than 6 segments are needed - * to handle all unix svcs. + * all of the segments specified in clist must be in + * one file system. no more than 6 segments are needed + * to handle all unix svcs. * - * if the i_nlink field (i.e. disk inode link count) - * is zero, and the type of inode is a regular file or - * directory, or symbolic link , the inode is truncated - * to zero length. the truncation is committed but the - * VM resources are unaffected until it is closed (see - * iput and iclose). + * if the i_nlink field (i.e. disk inode link count) + * is zero, and the type of inode is a regular file or + * directory, or symbolic link , the inode is truncated + * to zero length. the truncation is committed but the + * VM resources are unaffected until it is closed (see + * iput and iclose). * * PARAMETER: * * RETURN: * * serialization: - * on entry the inode lock on each segment is assumed - * to be held. + * on entry the inode lock on each segment is assumed + * to be held. * * i/o error: */ @@ -1175,7 +1175,7 @@ int txCommit(tid_t tid, /* transaction identifier */ if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0) tblk->xflag |= COMMIT_LAZY; /* - * prepare non-journaled objects for commit + * prepare non-journaled objects for commit * * flush data pages of non-journaled file * to prevent the file getting non-initialized disk blocks @@ -1186,7 +1186,7 @@ int txCommit(tid_t tid, /* transaction identifier */ cd.nip = nip; /* - * acquire transaction lock on (on-disk) inodes + * acquire transaction lock on (on-disk) inodes * * update on-disk inode from in-memory inode * acquiring transaction locks for AFTER records @@ -1262,7 +1262,7 @@ int txCommit(tid_t tid, /* transaction identifier */ } /* - * write log records from transaction locks + * write log records from transaction locks * * txUpdateMap() resets XAD_NEW in XAD. */ @@ -1294,7 +1294,7 @@ int txCommit(tid_t tid, /* transaction identifier */ !test_cflag(COMMIT_Nolink, tblk->u.ip))); /* - * write COMMIT log record + * write COMMIT log record */ lrd->type = cpu_to_le16(LOG_COMMIT); lrd->length = 0; @@ -1303,7 +1303,7 @@ int txCommit(tid_t tid, /* transaction identifier */ lmGroupCommit(log, tblk); /* - * - transaction is now committed - + * - transaction is now committed - */ /* @@ -1314,11 +1314,11 @@ int txCommit(tid_t tid, /* transaction identifier */ txForce(tblk); /* - * update allocation map. + * update allocation map. * * update inode allocation map and inode: * free pager lock on memory object of inode if any. - * update block allocation map. + * update block allocation map. * * txUpdateMap() resets XAD_NEW in XAD. */ @@ -1326,7 +1326,7 @@ int txCommit(tid_t tid, /* transaction identifier */ txUpdateMap(tblk); /* - * free transaction locks and pageout/free pages + * free transaction locks and pageout/free pages */ txRelease(tblk); @@ -1335,7 +1335,7 @@ int txCommit(tid_t tid, /* transaction identifier */ /* - * reset in-memory object state + * reset in-memory object state */ for (k = 0; k < cd.nip; k++) { ip = cd.iplist[k]; @@ -1358,11 +1358,11 @@ int txCommit(tid_t tid, /* transaction identifier */ } /* - * NAME: txLog() + * NAME: txLog() * - * FUNCTION: Writes AFTER log records for all lines modified - * by tid for segments specified by inodes in comdata. - * Code assumes only WRITELOCKS are recorded in lockwords. + * FUNCTION: Writes AFTER log records for all lines modified + * by tid for segments specified by inodes in comdata. + * Code assumes only WRITELOCKS are recorded in lockwords. * * PARAMETERS: * @@ -1421,12 +1421,12 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd) } /* - * diLog() + * diLog() * - * function: log inode tlock and format maplock to update bmap; + * function: log inode tlock and format maplock to update bmap; */ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, - struct tlock * tlck, struct commit * cd) + struct tlock * tlck, struct commit * cd) { int rc = 0; struct metapage *mp; @@ -1442,7 +1442,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, pxd = &lrd->log.redopage.pxd; /* - * inode after image + * inode after image */ if (tlck->type & tlckENTRY) { /* log after-image for logredo(): */ @@ -1456,7 +1456,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, tlck->flag |= tlckWRITEPAGE; } else if (tlck->type & tlckFREE) { /* - * free inode extent + * free inode extent * * (pages of the freed inode extent have been invalidated and * a maplock for free of the extent has been formatted at @@ -1498,7 +1498,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, jfs_err("diLog: UFO type tlck:0x%p", tlck); #ifdef _JFS_WIP /* - * alloc/free external EA extent + * alloc/free external EA extent * * a maplock for txUpdateMap() to update bPWMAP for alloc/free * of the extent has been formatted at txLock() time; @@ -1534,9 +1534,9 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * dataLog() + * dataLog() * - * function: log data tlock + * function: log data tlock */ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, struct tlock * tlck) @@ -1580,9 +1580,9 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * dtLog() + * dtLog() * - * function: log dtree tlock and format maplock to update bmap; + * function: log dtree tlock and format maplock to update bmap; */ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, struct tlock * tlck) @@ -1603,10 +1603,10 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); /* - * page extension via relocation: entry insertion; - * page extension in-place: entry insertion; - * new right page from page split, reinitialized in-line - * root from root page split: entry insertion; + * page extension via relocation: entry insertion; + * page extension in-place: entry insertion; + * new right page from page split, reinitialized in-line + * root from root page split: entry insertion; */ if (tlck->type & (tlckNEW | tlckEXTEND)) { /* log after-image of the new page for logredo(): @@ -1641,8 +1641,8 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * entry insertion/deletion, - * sibling page link update (old right page before split); + * entry insertion/deletion, + * sibling page link update (old right page before split); */ if (tlck->type & (tlckENTRY | tlckRELINK)) { /* log after-image for logredo(): */ @@ -1658,11 +1658,11 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * page deletion: page has been invalidated - * page relocation: source extent + * page deletion: page has been invalidated + * page relocation: source extent * - * a maplock for free of the page has been formatted - * at txLock() time); + * a maplock for free of the page has been formatted + * at txLock() time); */ if (tlck->type & (tlckFREE | tlckRELOCATE)) { /* log LOG_NOREDOPAGE of the deleted page for logredo() @@ -1683,9 +1683,9 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * xtLog() + * xtLog() * - * function: log xtree tlock and format maplock to update bmap; + * function: log xtree tlock and format maplock to update bmap; */ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, struct tlock * tlck) @@ -1725,8 +1725,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, xadlock = (struct xdlistlock *) maplock; /* - * entry insertion/extension; - * sibling page link update (old right page before split); + * entry insertion/extension; + * sibling page link update (old right page before split); */ if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) { /* log after-image for logredo(): @@ -1801,7 +1801,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * page deletion: file deletion/truncation (ref. xtTruncate()) + * page deletion: file deletion/truncation (ref. xtTruncate()) * * (page will be invalidated after log is written and bmap * is updated from the page); @@ -1908,13 +1908,13 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * page/entry truncation: file truncation (ref. xtTruncate()) + * page/entry truncation: file truncation (ref. xtTruncate()) * - * |----------+------+------+---------------| - * | | | - * | | hwm - hwm before truncation - * | next - truncation point - * lwm - lwm before truncation + * |----------+------+------+---------------| + * | | | + * | | hwm - hwm before truncation + * | next - truncation point + * lwm - lwm before truncation * header ? */ if (tlck->type & tlckTRUNCATE) { @@ -1937,7 +1937,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, twm = xtlck->twm.offset; /* - * write log records + * write log records */ /* log after-image for logredo(): * @@ -1997,7 +1997,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * format maplock(s) for txUpdateMap() to update bmap + * format maplock(s) for txUpdateMap() to update bmap */ maplock->index = 0; @@ -2069,9 +2069,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * mapLog() + * mapLog() * - * function: log from maplock of freed data extents; + * function: log from maplock of freed data extents; */ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, struct tlock * tlck) @@ -2081,7 +2081,7 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, pxd_t *pxd; /* - * page relocation: free the source page extent + * page relocation: free the source page extent * * a maplock for txUpdateMap() for free of the page * has been formatted at txLock() time saving the src @@ -2155,10 +2155,10 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } /* - * txEA() + * txEA() * - * function: acquire maplock for EA/ACL extents or - * set COMMIT_INLINE flag; + * function: acquire maplock for EA/ACL extents or + * set COMMIT_INLINE flag; */ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) { @@ -2207,10 +2207,10 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) } /* - * txForce() + * txForce() * * function: synchronously write pages locked by transaction - * after txLog() but before txUpdateMap(); + * after txLog() but before txUpdateMap(); */ static void txForce(struct tblock * tblk) { @@ -2273,10 +2273,10 @@ static void txForce(struct tblock * tblk) } /* - * txUpdateMap() + * txUpdateMap() * - * function: update persistent allocation map (and working map - * if appropriate); + * function: update persistent allocation map (and working map + * if appropriate); * * parameter: */ @@ -2298,7 +2298,7 @@ static void txUpdateMap(struct tblock * tblk) /* - * update block allocation map + * update block allocation map * * update allocation state in pmap (and wmap) and * update lsn of the pmap page; @@ -2382,7 +2382,7 @@ static void txUpdateMap(struct tblock * tblk) } } /* - * update inode allocation map + * update inode allocation map * * update allocation state in pmap and * update lsn of the pmap page; @@ -2407,24 +2407,24 @@ static void txUpdateMap(struct tblock * tblk) } /* - * txAllocPMap() + * txAllocPMap() * * function: allocate from persistent map; * * parameter: - * ipbmap - - * malock - - * xad list: - * pxd: + * ipbmap - + * malock - + * xad list: + * pxd: * - * maptype - - * allocate from persistent map; - * free from persistent map; - * (e.g., tmp file - free from working map at releae - * of last reference); - * free from persistent and working map; + * maptype - + * allocate from persistent map; + * free from persistent map; + * (e.g., tmp file - free from working map at releae + * of last reference); + * free from persistent and working map; * - * lsn - log sequence number; + * lsn - log sequence number; */ static void txAllocPMap(struct inode *ip, struct maplock * maplock, struct tblock * tblk) @@ -2478,9 +2478,9 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, } /* - * txFreeMap() + * txFreeMap() * - * function: free from persistent and/or working map; + * function: free from persistent and/or working map; * * todo: optimization */ @@ -2579,9 +2579,9 @@ void txFreeMap(struct inode *ip, } /* - * txFreelock() + * txFreelock() * - * function: remove tlock from inode anonymous locklist + * function: remove tlock from inode anonymous locklist */ void txFreelock(struct inode *ip) { @@ -2619,7 +2619,7 @@ void txFreelock(struct inode *ip) } /* - * txAbort() + * txAbort() * * function: abort tx before commit; * @@ -2679,7 +2679,7 @@ void txAbort(tid_t tid, int dirty) } /* - * txLazyCommit(void) + * txLazyCommit(void) * * All transactions except those changing ipimap (COMMIT_FORCE) are * processed by this routine. This insures that the inode and block @@ -2728,7 +2728,7 @@ static void txLazyCommit(struct tblock * tblk) } /* - * jfs_lazycommit(void) + * jfs_lazycommit(void) * * To be run as a kernel daemon. If lbmIODone is called in an interrupt * context, or where blocking is not wanted, this routine will process @@ -2913,7 +2913,7 @@ void txResume(struct super_block *sb) } /* - * jfs_sync(void) + * jfs_sync(void) * * To be run as a kernel daemon. This is awakened when tlocks run low. * We write any inodes that have anonymous tlocks so they will become diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h index 7863cf21afca..ab7288937019 100644 --- a/fs/jfs/jfs_txnmgr.h +++ b/fs/jfs/jfs_txnmgr.h @@ -94,7 +94,7 @@ extern struct tblock *TxBlock; /* transaction block table */ */ struct tlock { lid_t next; /* 2: index next lockword on tid locklist - * next lockword on freelist + * next lockword on freelist */ tid_t tid; /* 2: transaction id holding lock */ diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h index 09b252958687..649f9817accd 100644 --- a/fs/jfs/jfs_types.h +++ b/fs/jfs/jfs_types.h @@ -21,7 +21,7 @@ /* * jfs_types.h: * - * basic type/utility definitions + * basic type/utility definitions * * note: this header file must be the 1st include file * of JFS include list in all JFS .c file. @@ -54,8 +54,8 @@ struct timestruc_t { */ #define LEFTMOSTONE 0x80000000 -#define HIGHORDER 0x80000000u /* high order bit on */ -#define ONES 0xffffffffu /* all bit on */ +#define HIGHORDER 0x80000000u /* high order bit on */ +#define ONES 0xffffffffu /* all bit on */ /* * logical xd (lxd) @@ -148,7 +148,7 @@ typedef struct { #define sizeDXD(dxd) le32_to_cpu((dxd)->size) /* - * directory entry argument + * directory entry argument */ struct component_name { int namlen; @@ -160,14 +160,14 @@ struct component_name { * DASD limit information - stored in directory inode */ struct dasd { - u8 thresh; /* Alert Threshold (in percent) */ - u8 delta; /* Alert Threshold delta (in percent) */ + u8 thresh; /* Alert Threshold (in percent) */ + u8 delta; /* Alert Threshold delta (in percent) */ u8 rsrvd1; - u8 limit_hi; /* DASD limit (in logical blocks) */ - __le32 limit_lo; /* DASD limit (in logical blocks) */ + u8 limit_hi; /* DASD limit (in logical blocks) */ + __le32 limit_lo; /* DASD limit (in logical blocks) */ u8 rsrvd2[3]; - u8 used_hi; /* DASD usage (in logical blocks) */ - __le32 used_lo; /* DASD usage (in logical blocks) */ + u8 used_hi; /* DASD usage (in logical blocks) */ + __le32 used_lo; /* DASD usage (in logical blocks) */ }; #define DASDLIMIT(dasdp) \ diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c index a386f48c73fc..7971f37534a3 100644 --- a/fs/jfs/jfs_umount.c +++ b/fs/jfs/jfs_umount.c @@ -60,7 +60,7 @@ int jfs_umount(struct super_block *sb) jfs_info("UnMount JFS: sb:0x%p", sb); /* - * update superblock and close log + * update superblock and close log * * if mounted read-write and log based recovery was enabled */ diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index acc97c46d8a4..1543906a2e0d 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - * jfs_xtree.c: extent allocation descriptor B+-tree manager + * jfs_xtree.c: extent allocation descriptor B+-tree manager */ #include @@ -32,30 +32,30 @@ /* * xtree local flag */ -#define XT_INSERT 0x00000001 +#define XT_INSERT 0x00000001 /* - * xtree key/entry comparison: extent offset + * xtree key/entry comparison: extent offset * * return: - * -1: k < start of extent - * 0: start_of_extent <= k <= end_of_extent - * 1: k > end_of_extent + * -1: k < start of extent + * 0: start_of_extent <= k <= end_of_extent + * 1: k > end_of_extent */ #define XT_CMP(CMP, K, X, OFFSET64)\ {\ - OFFSET64 = offsetXAD(X);\ - (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\ - ((K) < OFFSET64) ? -1 : 0;\ + OFFSET64 = offsetXAD(X);\ + (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\ + ((K) < OFFSET64) ? -1 : 0;\ } /* write a xad entry */ #define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\ {\ - (XAD)->flag = (FLAG);\ - XADoffset((XAD), (OFF));\ - XADlength((XAD), (LEN));\ - XADaddress((XAD), (ADDR));\ + (XAD)->flag = (FLAG);\ + XADoffset((XAD), (OFF));\ + XADlength((XAD), (LEN));\ + XADaddress((XAD), (ADDR));\ } #define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot) @@ -76,13 +76,13 @@ MP = NULL;\ RC = -EIO;\ }\ - }\ + }\ } /* for consistency */ #define XT_PUTPAGE(MP) BT_PUTPAGE(MP) -#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ +#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot) /* xtree entry parameter descriptor */ struct xtsplit { @@ -97,7 +97,7 @@ struct xtsplit { /* - * statistics + * statistics */ #ifdef CONFIG_JFS_STATISTICS static struct { @@ -136,7 +136,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp); #endif /* _STILL_TO_PORT */ /* - * xtLookup() + * xtLookup() * * function: map a single page into a physical extent; */ @@ -179,7 +179,7 @@ int xtLookup(struct inode *ip, s64 lstart, } /* - * compute the physical extent covering logical extent + * compute the physical extent covering logical extent * * N.B. search may have failed (e.g., hole in sparse file), * and returned the index of the next entry. @@ -220,27 +220,27 @@ int xtLookup(struct inode *ip, s64 lstart, /* - * xtLookupList() + * xtLookupList() * * function: map a single logical extent into a list of physical extent; * * parameter: - * struct inode *ip, - * struct lxdlist *lxdlist, lxd list (in) - * struct xadlist *xadlist, xad list (in/out) - * int flag) + * struct inode *ip, + * struct lxdlist *lxdlist, lxd list (in) + * struct xadlist *xadlist, xad list (in/out) + * int flag) * * coverage of lxd by xad under assumption of * . lxd's are ordered and disjoint. * . xad's are ordered and disjoint. * * return: - * 0: success + * 0: success * * note: a page being written (even a single byte) is backed fully, - * except the last page which is only backed with blocks - * required to cover the last byte; - * the extent backing a page is fully contained within an xad; + * except the last page which is only backed with blocks + * required to cover the last byte; + * the extent backing a page is fully contained within an xad; */ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, struct xadlist * xadlist, int flag) @@ -284,7 +284,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, return rc; /* - * compute the physical extent covering logical extent + * compute the physical extent covering logical extent * * N.B. search may have failed (e.g., hole in sparse file), * and returned the index of the next entry. @@ -343,7 +343,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, if (lstart >= size) goto mapend; - /* compare with the current xad */ + /* compare with the current xad */ goto compare1; } /* lxd is covered by xad */ @@ -430,7 +430,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, /* * lxd is partially covered by xad */ - else { /* (xend < lend) */ + else { /* (xend < lend) */ /* * get next xad @@ -477,22 +477,22 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, /* - * xtSearch() + * xtSearch() * - * function: search for the xad entry covering specified offset. + * function: search for the xad entry covering specified offset. * * parameters: - * ip - file object; - * xoff - extent offset; - * nextp - address of next extent (if any) for search miss - * cmpp - comparison result: - * btstack - traverse stack; - * flag - search process flag (XT_INSERT); + * ip - file object; + * xoff - extent offset; + * nextp - address of next extent (if any) for search miss + * cmpp - comparison result: + * btstack - traverse stack; + * flag - search process flag (XT_INSERT); * * returns: - * btstack contains (bn, index) of search path traversed to the entry. - * *cmpp is set to result of comparison with the entry returned. - * the page containing the entry is pinned at exit. + * btstack contains (bn, index) of search path traversed to the entry. + * *cmpp is set to result of comparison with the entry returned. + * the page containing the entry is pinned at exit. */ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, int *cmpp, struct btstack * btstack, int flag) @@ -517,7 +517,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, btstack->nsplit = 0; /* - * search down tree from root: + * search down tree from root: * * between two consecutive entries of and of * internal page, child page Pi contains entry with k, Ki <= K < Kj. @@ -642,7 +642,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, XT_CMP(cmp, xoff, &p->xad[index], t64); if (cmp == 0) { /* - * search hit + * search hit */ /* search hit - leaf page: * return the entry found @@ -692,7 +692,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, } /* - * search miss + * search miss * * base is the smallest index with key (Kj) greater than * search key (K) and may be zero or maxentry index. @@ -773,22 +773,22 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, } /* - * xtInsert() + * xtInsert() * * function: * * parameter: - * tid - transaction id; - * ip - file object; - * xflag - extent flag (XAD_NOTRECORDED): - * xoff - extent offset; - * xlen - extent length; - * xaddrp - extent address pointer (in/out): - * if (*xaddrp) - * caller allocated data extent at *xaddrp; - * else - * allocate data extent and return its xaddr; - * flag - + * tid - transaction id; + * ip - file object; + * xflag - extent flag (XAD_NOTRECORDED): + * xoff - extent offset; + * xlen - extent length; + * xaddrp - extent address pointer (in/out): + * if (*xaddrp) + * caller allocated data extent at *xaddrp; + * else + * allocate data extent and return its xaddr; + * flag - * * return: */ @@ -813,7 +813,7 @@ int xtInsert(tid_t tid, /* transaction id */ jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); /* - * search for the entry location at which to insert: + * search for the entry location at which to insert: * * xtFastSearch() and xtSearch() both returns (leaf page * pinned, index at which to insert). @@ -853,13 +853,13 @@ int xtInsert(tid_t tid, /* transaction id */ } /* - * insert entry for new extent + * insert entry for new extent */ xflag |= XAD_NEW; /* - * if the leaf page is full, split the page and - * propagate up the router entry for the new page from split + * if the leaf page is full, split the page and + * propagate up the router entry for the new page from split * * The xtSplitUp() will insert the entry and unpin the leaf page. */ @@ -886,7 +886,7 @@ int xtInsert(tid_t tid, /* transaction id */ } /* - * insert the new entry into the leaf page + * insert the new entry into the leaf page */ /* * acquire a transaction lock on the leaf page; @@ -930,16 +930,16 @@ int xtInsert(tid_t tid, /* transaction id */ /* - * xtSplitUp() + * xtSplitUp() * * function: - * split full pages as propagating insertion up the tree + * split full pages as propagating insertion up the tree * * parameter: - * tid - transaction id; - * ip - file object; - * split - entry parameter descriptor; - * btstack - traverse stack from xtSearch() + * tid - transaction id; + * ip - file object; + * split - entry parameter descriptor; + * btstack - traverse stack from xtSearch() * * return: */ @@ -1199,22 +1199,22 @@ xtSplitUp(tid_t tid, /* - * xtSplitPage() + * xtSplitPage() * * function: - * split a full non-root page into - * original/split/left page and new right page - * i.e., the original/split page remains as left page. + * split a full non-root page into + * original/split/left page and new right page + * i.e., the original/split page remains as left page. * * parameter: - * int tid, - * struct inode *ip, - * struct xtsplit *split, - * struct metapage **rmpp, - * u64 *rbnp, + * int tid, + * struct inode *ip, + * struct xtsplit *split, + * struct metapage **rmpp, + * u64 *rbnp, * * return: - * Pointer to page in which to insert or NULL on error. + * Pointer to page in which to insert or NULL on error. */ static int xtSplitPage(tid_t tid, struct inode *ip, @@ -1248,9 +1248,9 @@ xtSplitPage(tid_t tid, struct inode *ip, rbn = addressPXD(pxd); /* Allocate blocks to quota. */ - if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { - rc = -EDQUOT; - goto clean_up; + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { + rc = -EDQUOT; + goto clean_up; } quota_allocation += lengthPXD(pxd); @@ -1304,7 +1304,7 @@ xtSplitPage(tid_t tid, struct inode *ip, skip = split->index; /* - * sequential append at tail (after last entry of last page) + * sequential append at tail (after last entry of last page) * * if splitting the last page on a level because of appending * a entry to it (skip is maxentry), it's likely that the access is @@ -1342,7 +1342,7 @@ xtSplitPage(tid_t tid, struct inode *ip, } /* - * non-sequential insert (at possibly middle page) + * non-sequential insert (at possibly middle page) */ /* @@ -1465,25 +1465,24 @@ xtSplitPage(tid_t tid, struct inode *ip, /* - * xtSplitRoot() + * xtSplitRoot() * * function: - * split the full root page into - * original/root/split page and new right page - * i.e., root remains fixed in tree anchor (inode) and - * the root is copied to a single new right child page - * since root page << non-root page, and - * the split root page contains a single entry for the - * new right child page. + * split the full root page into original/root/split page and new + * right page + * i.e., root remains fixed in tree anchor (inode) and the root is + * copied to a single new right child page since root page << + * non-root page, and the split root page contains a single entry + * for the new right child page. * * parameter: - * int tid, - * struct inode *ip, - * struct xtsplit *split, - * struct metapage **rmpp) + * int tid, + * struct inode *ip, + * struct xtsplit *split, + * struct metapage **rmpp) * * return: - * Pointer to page in which to insert or NULL on error. + * Pointer to page in which to insert or NULL on error. */ static int xtSplitRoot(tid_t tid, @@ -1505,7 +1504,7 @@ xtSplitRoot(tid_t tid, INCREMENT(xtStat.split); /* - * allocate a single (right) child page + * allocate a single (right) child page */ pxdlist = split->pxdlist; pxd = &pxdlist->pxd[pxdlist->npxd]; @@ -1573,7 +1572,7 @@ xtSplitRoot(tid_t tid, } /* - * reset the root + * reset the root * * init root with the single entry for the new right page * set the 1st entry offset to 0, which force the left-most key @@ -1610,7 +1609,7 @@ xtSplitRoot(tid_t tid, /* - * xtExtend() + * xtExtend() * * function: extend in-place; * @@ -1677,7 +1676,7 @@ int xtExtend(tid_t tid, /* transaction id */ goto extendOld; /* - * extent overflow: insert entry for new extent + * extent overflow: insert entry for new extent */ //insertNew: xoff = offsetXAD(xad) + MAXXLEN; @@ -1685,8 +1684,8 @@ int xtExtend(tid_t tid, /* transaction id */ nextindex = le16_to_cpu(p->header.nextindex); /* - * if the leaf page is full, insert the new entry and - * propagate up the router entry for the new page from split + * if the leaf page is full, insert the new entry and + * propagate up the router entry for the new page from split * * The xtSplitUp() will insert the entry and unpin the leaf page. */ @@ -1731,7 +1730,7 @@ int xtExtend(tid_t tid, /* transaction id */ } } /* - * insert the new entry into the leaf page + * insert the new entry into the leaf page */ else { /* insert the new entry: mark the entry NEW */ @@ -1771,11 +1770,11 @@ int xtExtend(tid_t tid, /* transaction id */ #ifdef _NOTYET /* - * xtTailgate() + * xtTailgate() * * function: split existing 'tail' extent - * (split offset >= start offset of tail extent), and - * relocate and extend the split tail half; + * (split offset >= start offset of tail extent), and + * relocate and extend the split tail half; * * note: existing extent may or may not have been committed. * caller is responsible for pager buffer cache update, and @@ -1804,7 +1803,7 @@ int xtTailgate(tid_t tid, /* transaction id */ /* printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", - (ulong)xoff, xlen, (ulong)xaddr); + (ulong)xoff, xlen, (ulong)xaddr); */ /* there must exist extent to be tailgated */ @@ -1842,18 +1841,18 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", xad = &p->xad[index]; /* printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", - (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad)); + (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad)); */ if ((llen = xoff - offsetXAD(xad)) == 0) goto updateOld; /* - * partially replace extent: insert entry for new extent + * partially replace extent: insert entry for new extent */ //insertNew: /* - * if the leaf page is full, insert the new entry and - * propagate up the router entry for the new page from split + * if the leaf page is full, insert the new entry and + * propagate up the router entry for the new page from split * * The xtSplitUp() will insert the entry and unpin the leaf page. */ @@ -1898,7 +1897,7 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", } } /* - * insert the new entry into the leaf page + * insert the new entry into the leaf page */ else { /* insert the new entry: mark the entry NEW */ @@ -1955,17 +1954,17 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", #endif /* _NOTYET */ /* - * xtUpdate() + * xtUpdate() * * function: update XAD; * - * update extent for allocated_but_not_recorded or - * compressed extent; + * update extent for allocated_but_not_recorded or + * compressed extent; * * parameter: - * nxad - new XAD; - * logical extent of the specified XAD must be completely - * contained by an existing XAD; + * nxad - new XAD; + * logical extent of the specified XAD must be completely + * contained by an existing XAD; */ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) { /* new XAD */ @@ -2416,19 +2415,19 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p); /* - * xtAppend() + * xtAppend() * * function: grow in append mode from contiguous region specified ; * * parameter: - * tid - transaction id; - * ip - file object; - * xflag - extent flag: - * xoff - extent offset; - * maxblocks - max extent length; - * xlen - extent length (in/out); - * xaddrp - extent address pointer (in/out): - * flag - + * tid - transaction id; + * ip - file object; + * xflag - extent flag: + * xoff - extent offset; + * maxblocks - max extent length; + * xlen - extent length (in/out); + * xaddrp - extent address pointer (in/out): + * flag - * * return: */ @@ -2460,7 +2459,7 @@ int xtAppend(tid_t tid, /* transaction id */ (ulong) xoff, maxblocks, xlen, (ulong) xaddr); /* - * search for the entry location at which to insert: + * search for the entry location at which to insert: * * xtFastSearch() and xtSearch() both returns (leaf page * pinned, index at which to insert). @@ -2482,13 +2481,13 @@ int xtAppend(tid_t tid, /* transaction id */ xlen = min(xlen, (int)(next - xoff)); //insert: /* - * insert entry for new extent + * insert entry for new extent */ xflag |= XAD_NEW; /* - * if the leaf page is full, split the page and - * propagate up the router entry for the new page from split + * if the leaf page is full, split the page and + * propagate up the router entry for the new page from split * * The xtSplitUp() will insert the entry and unpin the leaf page. */ @@ -2545,7 +2544,7 @@ int xtAppend(tid_t tid, /* transaction id */ return 0; /* - * insert the new entry into the leaf page + * insert the new entry into the leaf page */ insertLeaf: /* @@ -2589,17 +2588,17 @@ int xtAppend(tid_t tid, /* transaction id */ /* - TBD for defragmentaion/reorganization - * - * xtDelete() + * xtDelete() * * function: - * delete the entry with the specified key. + * delete the entry with the specified key. * - * N.B.: whole extent of the entry is assumed to be deleted. + * N.B.: whole extent of the entry is assumed to be deleted. * * parameter: * * return: - * ENOENT: if the entry is not found. + * ENOENT: if the entry is not found. * * exception: */ @@ -2665,10 +2664,10 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) /* - TBD for defragmentaion/reorganization - * - * xtDeleteUp() + * xtDeleteUp() * * function: - * free empty pages as propagating deletion up the tree + * free empty pages as propagating deletion up the tree * * parameter: * @@ -2815,15 +2814,15 @@ xtDeleteUp(tid_t tid, struct inode *ip, /* - * NAME: xtRelocate() + * NAME: xtRelocate() * - * FUNCTION: relocate xtpage or data extent of regular file; - * This function is mainly used by defragfs utility. + * FUNCTION: relocate xtpage or data extent of regular file; + * This function is mainly used by defragfs utility. * - * NOTE: This routine does not have the logic to handle - * uncommitted allocated extent. The caller should call - * txCommit() to commit all the allocation before call - * this routine. + * NOTE: This routine does not have the logic to handle + * uncommitted allocated extent. The caller should call + * txCommit() to commit all the allocation before call + * this routine. */ int xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ @@ -2865,8 +2864,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr); /* - * 1. get and validate the parent xtpage/xad entry - * covering the source extent to be relocated; + * 1. get and validate the parent xtpage/xad entry + * covering the source extent to be relocated; */ if (xtype == DATAEXT) { /* search in leaf entry */ @@ -2910,7 +2909,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ jfs_info("xtRelocate: parent xad entry validated."); /* - * 2. relocate the extent + * 2. relocate the extent */ if (xtype == DATAEXT) { /* if the extent is allocated-but-not-recorded @@ -2923,7 +2922,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ XT_PUTPAGE(pmp); /* - * cmRelocate() + * cmRelocate() * * copy target data pages to be relocated; * @@ -2945,8 +2944,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ pno = offset >> CM_L2BSIZE; npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE; /* - npages = ((offset + nbytes - 1) >> CM_L2BSIZE) - - (offset >> CM_L2BSIZE) + 1; + npages = ((offset + nbytes - 1) >> CM_L2BSIZE) - + (offset >> CM_L2BSIZE) + 1; */ sxaddr = oxaddr; dxaddr = nxaddr; @@ -2981,7 +2980,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); jfs_info("xtRelocate: target data extent relocated."); - } else { /* (xtype == XTPAGE) */ + } else { /* (xtype == XTPAGE) */ /* * read in the target xtpage from the source extent; @@ -3026,16 +3025,14 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ */ if (lmp) { BT_MARK_DIRTY(lmp, ip); - tlck = - txLock(tid, ip, lmp, tlckXTREE | tlckRELINK); + tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK); lp->header.next = cpu_to_le64(nxaddr); XT_PUTPAGE(lmp); } if (rmp) { BT_MARK_DIRTY(rmp, ip); - tlck = - txLock(tid, ip, rmp, tlckXTREE | tlckRELINK); + tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK); rp->header.prev = cpu_to_le64(nxaddr); XT_PUTPAGE(rmp); } @@ -3062,7 +3059,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ * scan may be skipped by commit() and logredo(); */ BT_MARK_DIRTY(mp, ip); - /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */ + /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */ tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW); xtlck = (struct xtlock *) & tlck->lock; @@ -3084,7 +3081,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ } /* - * 3. acquire maplock for the source extent to be freed; + * 3. acquire maplock for the source extent to be freed; * * acquire a maplock saving the src relocated extent address; * to free of the extent at commit time; @@ -3105,7 +3102,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ * is no buffer associated with this lock since the buffer * has been redirected to the target location. */ - else /* (xtype == XTPAGE) */ + else /* (xtype == XTPAGE) */ tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE); pxdlock = (struct pxd_lock *) & tlck->lock; @@ -3115,7 +3112,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ pxdlock->index = 1; /* - * 4. update the parent xad entry for relocation; + * 4. update the parent xad entry for relocation; * * acquire tlck for the parent entry with XAD_NEW as entry * update which will write LOG_REDOPAGE and update bmap for @@ -3143,22 +3140,22 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ /* - * xtSearchNode() + * xtSearchNode() * - * function: search for the internal xad entry covering specified extent. - * This function is mainly used by defragfs utility. + * function: search for the internal xad entry covering specified extent. + * This function is mainly used by defragfs utility. * * parameters: - * ip - file object; - * xad - extent to find; - * cmpp - comparison result: - * btstack - traverse stack; - * flag - search process flag; + * ip - file object; + * xad - extent to find; + * cmpp - comparison result: + * btstack - traverse stack; + * flag - search process flag; * * returns: - * btstack contains (bn, index) of search path traversed to the entry. - * *cmpp is set to result of comparison with the entry returned. - * the page containing the entry is pinned at exit. + * btstack contains (bn, index) of search path traversed to the entry. + * *cmpp is set to result of comparison with the entry returned. + * the page containing the entry is pinned at exit. */ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ int *cmpp, struct btstack * btstack, int flag) @@ -3181,7 +3178,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ xaddr = addressXAD(xad); /* - * search down tree from root: + * search down tree from root: * * between two consecutive entries of and of * internal page, child page Pi contains entry with k, Ki <= K < Kj. @@ -3217,7 +3214,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ XT_CMP(cmp, xoff, &p->xad[index], t64); if (cmp == 0) { /* - * search hit + * search hit * * verify for exact match; */ @@ -3245,7 +3242,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ } /* - * search miss - non-leaf page: + * search miss - non-leaf page: * * base is the smallest index with key (Kj) greater than * search key (K) and may be zero or maxentry index. @@ -3268,15 +3265,15 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ /* - * xtRelink() + * xtRelink() * * function: - * link around a freed page. + * link around a freed page. * * Parameter: - * int tid, - * struct inode *ip, - * xtpage_t *p) + * int tid, + * struct inode *ip, + * xtpage_t *p) * * returns: */ @@ -3338,7 +3335,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p) /* - * xtInitRoot() + * xtInitRoot() * * initialize file root (inline in inode) */ @@ -3385,42 +3382,42 @@ void xtInitRoot(tid_t tid, struct inode *ip) #define MAX_TRUNCATE_LEAVES 50 /* - * xtTruncate() + * xtTruncate() * * function: - * traverse for truncation logging backward bottom up; - * terminate at the last extent entry at the current subtree - * root page covering new down size. - * truncation may occur within the last extent entry. + * traverse for truncation logging backward bottom up; + * terminate at the last extent entry at the current subtree + * root page covering new down size. + * truncation may occur within the last extent entry. * * parameter: - * int tid, - * struct inode *ip, - * s64 newsize, - * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE} + * int tid, + * struct inode *ip, + * s64 newsize, + * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE} * * return: * * note: - * PWMAP: - * 1. truncate (non-COMMIT_NOLINK file) - * by jfs_truncate() or jfs_open(O_TRUNC): - * xtree is updated; + * PWMAP: + * 1. truncate (non-COMMIT_NOLINK file) + * by jfs_truncate() or jfs_open(O_TRUNC): + * xtree is updated; * 2. truncate index table of directory when last entry removed - * map update via tlock at commit time; - * PMAP: + * map update via tlock at commit time; + * PMAP: * Call xtTruncate_pmap instead - * WMAP: - * 1. remove (free zero link count) on last reference release - * (pmap has been freed at commit zero link count); - * 2. truncate (COMMIT_NOLINK file, i.e., tmp file): - * xtree is updated; - * map update directly at truncation time; + * WMAP: + * 1. remove (free zero link count) on last reference release + * (pmap has been freed at commit zero link count); + * 2. truncate (COMMIT_NOLINK file, i.e., tmp file): + * xtree is updated; + * map update directly at truncation time; * - * if (DELETE) - * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient); - * else if (TRUNCATE) - * must write LOG_NOREDOPAGE for deleted index page; + * if (DELETE) + * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient); + * else if (TRUNCATE) + * must write LOG_NOREDOPAGE for deleted index page; * * pages may already have been tlocked by anonymous transactions * during file growth (i.e., write) before truncation; @@ -3493,7 +3490,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) * retained in the new sized file. * if type is PMAP, the data and index pages are NOT * freed, and the data and index blocks are NOT freed - * from working map. + * from working map. * (this will allow continued access of data/index of * temporary file (zerolink count file truncated to zero-length)). */ @@ -3542,7 +3539,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) goto getChild; /* - * leaf page + * leaf page */ freed = 0; @@ -3916,7 +3913,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) } /* - * internal page: go down to child page of current entry + * internal page: go down to child page of current entry */ getChild: /* save current parent entry for the child page */ @@ -3965,7 +3962,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) /* - * xtTruncate_pmap() + * xtTruncate_pmap() * * function: * Perform truncate to zero lenghth for deleted file, leaving the @@ -3974,9 +3971,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) * is committed to disk. * * parameter: - * tid_t tid, - * struct inode *ip, - * s64 committed_size) + * tid_t tid, + * struct inode *ip, + * s64 committed_size) * * return: new committed size * @@ -4050,7 +4047,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) } /* - * leaf page + * leaf page */ if (++locked_leaves > MAX_TRUNCATE_LEAVES) { @@ -4062,7 +4059,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) xoff = offsetXAD(xad); xlen = lengthXAD(xad); XT_PUTPAGE(mp); - return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize; + return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize; } tlck = txLock(tid, ip, mp, tlckXTREE); tlck->type = tlckXTREE | tlckFREE; @@ -4099,8 +4096,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) */ tlck = txLock(tid, ip, mp, tlckXTREE); xtlck = (struct xtlock *) & tlck->lock; - xtlck->hwm.offset = - le16_to_cpu(p->header.nextindex) - 1; + xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1; tlck->type = tlckXTREE | tlckFREE; XT_PUTPAGE(mp); @@ -4118,7 +4114,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) else index--; /* - * internal page: go down to child page of current entry + * internal page: go down to child page of current entry */ getChild: /* save current parent entry for the child page */ diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h index 164f6f2b1019..70815c8a3d6a 100644 --- a/fs/jfs/jfs_xtree.h +++ b/fs/jfs/jfs_xtree.h @@ -19,14 +19,14 @@ #define _H_JFS_XTREE /* - * jfs_xtree.h: extent allocation descriptor B+-tree manager + * jfs_xtree.h: extent allocation descriptor B+-tree manager */ #include "jfs_btree.h" /* - * extent allocation descriptor (xad) + * extent allocation descriptor (xad) */ typedef struct xad { unsigned flag:8; /* 1: flag */ @@ -38,30 +38,30 @@ typedef struct xad { __le32 addr2; /* 4: address in unit of fsblksize */ } xad_t; /* (16) */ -#define MAXXLEN ((1 << 24) - 1) +#define MAXXLEN ((1 << 24) - 1) -#define XTSLOTSIZE 16 -#define L2XTSLOTSIZE 4 +#define XTSLOTSIZE 16 +#define L2XTSLOTSIZE 4 /* xad_t field construction */ #define XADoffset(xad, offset64)\ {\ - (xad)->off1 = ((u64)offset64) >> 32;\ - (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\ + (xad)->off1 = ((u64)offset64) >> 32;\ + (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\ } #define XADaddress(xad, address64)\ {\ - (xad)->addr1 = ((u64)address64) >> 32;\ - (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ + (xad)->addr1 = ((u64)address64) >> 32;\ + (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ } -#define XADlength(xad, length32) (xad)->len = __cpu_to_le24(length32) +#define XADlength(xad, length32) (xad)->len = __cpu_to_le24(length32) /* xad_t field extraction */ #define offsetXAD(xad)\ - ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2)) + ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2)) #define addressXAD(xad)\ - ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2)) -#define lengthXAD(xad) __le24_to_cpu((xad)->len) + ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2)) +#define lengthXAD(xad) __le24_to_cpu((xad)->len) /* xad list */ struct xadlist { @@ -71,22 +71,22 @@ struct xadlist { }; /* xad_t flags */ -#define XAD_NEW 0x01 /* new */ -#define XAD_EXTENDED 0x02 /* extended */ -#define XAD_COMPRESSED 0x04 /* compressed with recorded length */ +#define XAD_NEW 0x01 /* new */ +#define XAD_EXTENDED 0x02 /* extended */ +#define XAD_COMPRESSED 0x04 /* compressed with recorded length */ #define XAD_NOTRECORDED 0x08 /* allocated but not recorded */ -#define XAD_COW 0x10 /* copy-on-write */ +#define XAD_COW 0x10 /* copy-on-write */ /* possible values for maxentry */ -#define XTROOTINITSLOT_DIR 6 -#define XTROOTINITSLOT 10 -#define XTROOTMAXSLOT 18 -#define XTPAGEMAXSLOT 256 -#define XTENTRYSTART 2 +#define XTROOTINITSLOT_DIR 6 +#define XTROOTINITSLOT 10 +#define XTROOTMAXSLOT 18 +#define XTPAGEMAXSLOT 256 +#define XTENTRYSTART 2 /* - * xtree page: + * xtree page: */ typedef union { struct xtheader { @@ -106,7 +106,7 @@ typedef union { } xtpage_t; /* - * external declaration + * external declaration */ extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, int *pflag, s64 * paddr, int *plen, int flag); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 41c204771262..25161c4121e4 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -328,7 +328,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) * dentry - child directory dentry * * RETURN: -EINVAL - if name is . or .. - * -EINVAL - if . or .. exist but are invalid. + * -EINVAL - if . or .. exist but are invalid. * errors from subroutines * * note: @@ -517,7 +517,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) inode_dec_link_count(ip); /* - * commit zero link count object + * commit zero link count object */ if (ip->i_nlink == 0) { assert(!test_cflag(COMMIT_Nolink, ip)); @@ -596,7 +596,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) /* * NAME: commitZeroLink() * - * FUNCTION: for non-directory, called by jfs_remove(), + * FUNCTION: for non-directory, called by jfs_remove(), * truncate a regular file, directory or symbolic * link to zero length. return 0 if type is not * one of these. @@ -676,7 +676,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip) /* * NAME: jfs_free_zero_link() * - * FUNCTION: for non-directory, called by iClose(), + * FUNCTION: for non-directory, called by iClose(), * free resources of a file from cache and WORKING map * for a file previously committed with zero link count * while associated with a pager object, @@ -855,12 +855,12 @@ static int jfs_link(struct dentry *old_dentry, * NAME: jfs_symlink(dip, dentry, name) * * FUNCTION: creates a symbolic link to by name - * in directory + * in directory * - * PARAMETER: dip - parent directory vnode - * dentry - dentry of symbolic link - * name - the path name of the existing object - * that will be the source of the link + * PARAMETER: dip - parent directory vnode + * dentry - dentry of symbolic link + * name - the path name of the existing object + * that will be the source of the link * * RETURN: errors from subroutines * @@ -1052,9 +1052,9 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, /* - * NAME: jfs_rename + * NAME: jfs_rename * - * FUNCTION: rename a file or directory + * FUNCTION: rename a file or directory */ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) @@ -1331,9 +1331,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, /* - * NAME: jfs_mknod + * NAME: jfs_mknod * - * FUNCTION: Create a special file (device) + * FUNCTION: Create a special file (device) */ static int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 79d625f3f733..71984ee95346 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c @@ -29,17 +29,17 @@ #include "jfs_txnmgr.h" #include "jfs_debug.h" -#define BITSPERPAGE (PSIZE << 3) -#define L2MEGABYTE 20 -#define MEGABYTE (1 << L2MEGABYTE) -#define MEGABYTE32 (MEGABYTE << 5) +#define BITSPERPAGE (PSIZE << 3) +#define L2MEGABYTE 20 +#define MEGABYTE (1 << L2MEGABYTE) +#define MEGABYTE32 (MEGABYTE << 5) /* convert block number to bmap file page number */ #define BLKTODMAPN(b)\ - (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) + (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) /* - * jfs_extendfs() + * jfs_extendfs() * * function: extend file system; * @@ -48,9 +48,9 @@ * workspace space * * input: - * new LVSize: in LV blocks (required) - * new LogSize: in LV blocks (optional) - * new FSSize: in LV blocks (optional) + * new LVSize: in LV blocks (required) + * new LogSize: in LV blocks (optional) + * new FSSize: in LV blocks (optional) * * new configuration: * 1. set new LogSize as specified or default from new LVSize; @@ -125,8 +125,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) } /* - * reconfigure LV spaces - * --------------------- + * reconfigure LV spaces + * --------------------- * * validate new size, or, if not specified, determine new size */ @@ -198,7 +198,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) log_formatted = 1; } /* - * quiesce file system + * quiesce file system * * (prepare to move the inline log and to prevent map update) * @@ -270,8 +270,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) } /* - * extend block allocation map - * --------------------------- + * extend block allocation map + * --------------------------- * * extendfs() for new extension, retry after crash recovery; * @@ -283,7 +283,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) * s_size: aggregate size in physical blocks; */ /* - * compute the new block allocation map configuration + * compute the new block allocation map configuration * * map dinode: * di_size: map file size in byte; @@ -301,7 +301,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) newNpages = BLKTODMAPN(t64) + 1; /* - * extend map from current map (WITHOUT growing mapfile) + * extend map from current map (WITHOUT growing mapfile) * * map new extension with unmapped part of the last partial * dmap page, if applicable, and extra page(s) allocated @@ -341,8 +341,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) XSize -= nblocks; /* - * grow map file to cover remaining extension - * and/or one extra dmap page for next extendfs(); + * grow map file to cover remaining extension + * and/or one extra dmap page for next extendfs(); * * allocate new map pages and its backing blocks, and * update map file xtree @@ -422,8 +422,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) dbFinalizeBmap(ipbmap); /* - * update inode allocation map - * --------------------------- + * update inode allocation map + * --------------------------- * * move iag lists from old to new iag; * agstart field is not updated for logredo() to reconstruct @@ -442,8 +442,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) } /* - * finalize - * -------- + * finalize + * -------- * * extension is committed when on-disk super block is * updated with new descriptors: logredo will recover @@ -480,7 +480,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) diFreeSpecial(ipbmap2); /* - * update superblock + * update superblock */ if ((rc = readSuper(sb, &bh))) goto error_out; @@ -530,7 +530,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) resume: /* - * resume file system transactions + * resume file system transactions */ txResume(sb); diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index b753ba216450..5c0f2de01316 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -63,9 +63,9 @@ * * On-disk: * - * FEALISTs are stored on disk using blocks allocated by dbAlloc() and - * written directly. An EA list may be in-lined in the inode if there is - * sufficient room available. + * FEALISTs are stored on disk using blocks allocated by dbAlloc() and + * written directly. An EA list may be in-lined in the inode if there is + * sufficient room available. */ struct ea_buffer { From 209e101bf408a50acc426e32c8252daefacde5b0 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 6 Jun 2007 16:30:17 -0500 Subject: [PATCH 002/551] JFS: use print_hex_dump() rather than private dump_mem() function Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_debug.c | 28 ---------------------------- fs/jfs/jfs_debug.h | 2 -- fs/jfs/jfs_imap.c | 3 ++- fs/jfs/jfs_logmgr.c | 18 ++++++++++++------ fs/jfs/jfs_metapage.c | 3 ++- fs/jfs/jfs_txnmgr.c | 17 +++++++++++------ fs/jfs/xattr.c | 3 ++- 7 files changed, 29 insertions(+), 45 deletions(-) diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index 9c5d59632aac..887f5759e536 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c @@ -26,34 +26,6 @@ #include "jfs_filsys.h" #include "jfs_debug.h" -#ifdef CONFIG_JFS_DEBUG -void dump_mem(char *label, void *data, int length) -{ - int i, j; - int *intptr = data; - char *charptr = data; - char buf[10], line[80]; - - printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length, - data); - for (i = 0; i < length; i += 16) { - line[0] = 0; - for (j = 0; (j < 4) && (i + j * 4 < length); j++) { - sprintf(buf, " %08x", intptr[i / 4 + j]); - strcat(line, buf); - } - buf[0] = ' '; - buf[2] = 0; - for (j = 0; (j < 16) && (i + j < length); j++) { - buf[1] = - isprint(charptr[i + j]) ? charptr[i + j] : '.'; - strcat(line, buf); - } - printk("%s\n", line); - } -} -#endif - #ifdef PROC_FS_JFS /* see jfs_debug.h */ static struct proc_dir_entry *base; diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h index 7378798f0b21..044c1e654cc0 100644 --- a/fs/jfs/jfs_debug.h +++ b/fs/jfs/jfs_debug.h @@ -62,7 +62,6 @@ extern void jfs_proc_clean(void); extern int jfsloglevel; -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 */ @@ -94,7 +93,6 @@ extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *); * --------- */ #else /* CONFIG_JFS_DEBUG */ -#define dump_mem(label,data,length) do {} while (0) #define ASSERT(p) do {} while (0) #define jfs_info(fmt, arg...) do {} while (0) #define jfs_debug(fmt, arg...) do {} while (0) diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index f5c5227b0d1f..19da0e17e4de 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -890,7 +890,8 @@ int diFree(struct inode *ip) * the map. */ if (iagno >= imap->im_nextiag) { - dump_mem("imap", imap, 32); + printk(KERN_ERR "Dump of imap:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, imap, 32); jfs_error(ip->i_sb, "diFree: inum = %d, iagno = %d, nextiag = %d", (uint) inum, iagno, imap->im_nextiag); diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 88eae45a4644..2917ede90d67 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1622,16 +1622,22 @@ void jfs_flush_journal(struct jfs_log *log, int wait) if (!list_empty(&log->synclist)) { struct logsyncblk *lp; + printk(KERN_ERR "jfs_flush_journal: synclist not empty\n"); list_for_each_entry(lp, &log->synclist, synclist) { if (lp->xflag & COMMIT_PAGE) { struct metapage *mp = (struct metapage *)lp; - dump_mem("orphan metapage", lp, - sizeof(struct metapage)); - dump_mem("page", mp->page, sizeof(struct page)); + printk (KERN_ERR "orphan metapage:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, + lp, sizeof(struct metapage)); + printk (KERN_ERR "page:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, + mp->page, sizeof(struct page)); + } + else { + printk (KERN_ERR "orphan tblock:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, + lp, sizeof(struct tblock)); } - else - dump_mem("orphan tblock", lp, - sizeof(struct tblock)); } } #endif diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 43d4f69afbec..1c4fced1e6d8 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -472,7 +472,8 @@ add_failed: printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n"); goto skip; dump_bio: - dump_mem("bio", bio, sizeof(*bio)); + printk(KERN_ERR "JFS: dump of bio:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, bio, sizeof(*bio)); skip: bio_put(bio); unlock_page(page); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index f2dc4b986392..d6f23f90ad36 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -829,12 +829,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, /* Only locks on ipimap or ipaimap should reach here */ /* assert(jfs_ip->fileset == AGGREGATE_I); */ if (jfs_ip->fileset != AGGREGATE_I) { - jfs_err("txLock: trying to lock locked page!"); - dump_mem("ip", ip, sizeof(struct inode)); - dump_mem("mp", mp, sizeof(struct metapage)); - dump_mem("Locker's tblk", tid_to_tblock(tid), - sizeof(struct tblock)); - dump_mem("Tlock", tlck, sizeof(struct tlock)); + printk(KERN_ERR "txLock: trying to lock locked page!"); + printk(KERN_ERR "ip:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, ip, sizeof(*ip)); + printk(KERN_ERR "mp:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, mp, sizeof(*mp)); + printk(KERN_ERR "Locker's tblk:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, + tid_to_tblock(tid), sizeof(struct tblock)); + printk(KERN_ERR "Tlock:\n"); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, tlck, + sizeof(*tlck)); BUG(); } INCREMENT(stattx.waitlock); /* statistics */ diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 5c0f2de01316..2dcb13275429 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -590,7 +590,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) size_check: if (EALIST_SIZE(ea_buf->xattr) != ea_size) { printk(KERN_ERR "ea_get: invalid extended attribute\n"); - dump_mem("xattr", ea_buf->xattr, ea_size); + print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, ea_buf->xattr, + ea_size); ea_release(inode, ea_buf); rc = -EIO; goto clean_up; From 288e4d838d1e999c0515f85a337cacb2be233071 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 13 Jun 2007 10:17:50 -0500 Subject: [PATCH 003/551] JFS: Update print_hex_dump() syntax Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_imap.c | 4 ++-- fs/jfs/jfs_logmgr.c | 26 +++++++++++++------------- fs/jfs/jfs_metapage.c | 4 ++-- fs/jfs/jfs_txnmgr.c | 19 +++++++++---------- fs/jfs/xattr.c | 4 ++-- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 19da0e17e4de..3870ba8b9086 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -890,8 +890,8 @@ int diFree(struct inode *ip) * the map. */ if (iagno >= imap->im_nextiag) { - printk(KERN_ERR "Dump of imap:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, imap, 32); + print_hex_dump(KERN_ERR, "imap: ", DUMP_PREFIX_ADDRESS, 16, 4, + imap, 32, 0); jfs_error(ip->i_sb, "diFree: inum = %d, iagno = %d, nextiag = %d", (uint) inum, iagno, imap->im_nextiag); diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 2917ede90d67..de3e4a506dbc 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1626,22 +1626,22 @@ void jfs_flush_journal(struct jfs_log *log, int wait) list_for_each_entry(lp, &log->synclist, synclist) { if (lp->xflag & COMMIT_PAGE) { struct metapage *mp = (struct metapage *)lp; - printk (KERN_ERR "orphan metapage:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, - lp, sizeof(struct metapage)); - printk (KERN_ERR "page:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, - mp->page, sizeof(struct page)); - } - else { - printk (KERN_ERR "orphan tblock:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, - lp, sizeof(struct tblock)); - } + print_hex_dump(KERN_ERR, "metapage: ", + DUMP_PREFIX_ADDRESS, 16, 4, + mp, sizeof(struct metapage), 0); + print_hex_dump(KERN_ERR, "page: ", + DUMP_PREFIX_ADDRESS, 16, + sizeof(long), mp->page, + sizeof(struct page), 0); + } else + print_hex_dump(KERN_ERR, "tblock:", + DUMP_PREFIX_ADDRESS, 16, 4, + lp, sizeof(struct tblock), 0); } } +#else + WARN_ON(!list_empty(&log->synclist)); #endif - //assert(list_empty(&log->synclist)); clear_bit(log_FLUSH, &log->flag); } diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 1c4fced1e6d8..77c7f1129dde 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -472,8 +472,8 @@ add_failed: printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n"); goto skip; dump_bio: - printk(KERN_ERR "JFS: dump of bio:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, bio, sizeof(*bio)); + print_hex_dump(KERN_ERR, "JFS: dump of bio: ", DUMP_PREFIX_ADDRESS, 16, + 4, bio, sizeof(*bio), 0); skip: bio_put(bio); unlock_page(page); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index d6f23f90ad36..7aa1f7004eaf 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -830,16 +830,15 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, /* assert(jfs_ip->fileset == AGGREGATE_I); */ if (jfs_ip->fileset != AGGREGATE_I) { printk(KERN_ERR "txLock: trying to lock locked page!"); - printk(KERN_ERR "ip:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, ip, sizeof(*ip)); - printk(KERN_ERR "mp:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, mp, sizeof(*mp)); - printk(KERN_ERR "Locker's tblk:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, - tid_to_tblock(tid), sizeof(struct tblock)); - printk(KERN_ERR "Tlock:\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, tlck, - sizeof(*tlck)); + print_hex_dump(KERN_ERR, "ip: ", DUMP_PREFIX_ADDRESS, 16, 4, + ip, sizeof(*ip), 0); + print_hex_dump(KERN_ERR, "mp: ", DUMP_PREFIX_ADDRESS, 16, 4, + mp, sizeof(*mp), 0); + print_hex_dump(KERN_ERR, "Locker's tblock: ", + DUMP_PREFIX_ADDRESS, 16, 4, tid_to_tblock(tid), + sizeof(struct tblock), 0); + print_hex_dump(KERN_ERR, "Tlock: ", DUMP_PREFIX_ADDRESS, 16, 4, + tlck, sizeof(*tlck), 0); BUG(); } INCREMENT(stattx.waitlock); /* statistics */ diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 2dcb13275429..b2375f0774b7 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -590,8 +590,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) size_check: if (EALIST_SIZE(ea_buf->xattr) != ea_size) { printk(KERN_ERR "ea_get: invalid extended attribute\n"); - print_hex_dump(KERN_ERR, DUMP_PREFIX_ADDRESS, ea_buf->xattr, - ea_size); + print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, + ea_buf->xattr, ea_size, 1); ea_release(inode, ea_buf); rc = -EIO; goto clean_up; From 9d9d50bb2efb50594abfc3941a5504b62c514ebd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 28 Jun 2007 00:44:27 -0400 Subject: [PATCH 004/551] Input: i8042 - add HP Pavilion ZT1000 to the MUX blacklist This should get rid of "atkbd.c: Suprious NAK on isa0060/serio0" messages caused by broken MUX implementation. The box does not have external PS/2 ports and, according to documentation, automatically disables touchpad when an external mouse is plugged into a port replicator, so MUX mode would not work anyway. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index f4a2517925e4..4fca1e7f2678 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -199,6 +199,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), }, }, + { + /* + * Like DV4017EA does not raise AUXERR for errors on MUX ports. + */ + .ident = "HP Pavilion ZT1000", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), + DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), + }, + }, { .ident = "Toshiba P10", .matches = { From da4249c99fd59c4e224e4f9acaf07669d205bb1d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 28 Jun 2007 00:46:56 -0400 Subject: [PATCH 005/551] Input: atkbd - throttle LED switching On some boxes keyboard controllers are too slow to withstand continuous flow of requests to turn keyboard LEDs on and off and start losing some keypresses or even all of them. Delay executing of LED switching request if we had another one within 50 ms thus easing load on the controller. Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 40 ++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index be1fe46cd308..9e80012d0d0c 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -219,7 +219,8 @@ struct atkbd { unsigned long time; unsigned long err_count; - struct work_struct event_work; + struct delayed_work event_work; + unsigned long event_jiffies; struct mutex event_mutex; unsigned long event_mask; }; @@ -565,7 +566,7 @@ static int atkbd_set_leds(struct atkbd *atkbd) static void atkbd_event_work(struct work_struct *work) { - struct atkbd *atkbd = container_of(work, struct atkbd, event_work); + struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); mutex_lock(&atkbd->event_mutex); @@ -578,13 +579,31 @@ static void atkbd_event_work(struct work_struct *work) mutex_unlock(&atkbd->event_mutex); } +/* + * Schedule switch for execution. We need to throttle requests, + * otherwise keyboard may become unresponsive. + */ +static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) +{ + unsigned long delay = msecs_to_jiffies(50); + + if (time_after(jiffies, atkbd->event_jiffies + delay)) + delay = 0; + + atkbd->event_jiffies = jiffies; + set_bit(event_bit, &atkbd->event_mask); + wmb(); + schedule_delayed_work(&atkbd->event_work, delay); +} + /* * Event callback from the input module. Events that change the state of * the hardware are processed here. If action can not be performed in * interrupt context it is offloaded to atkbd_event_work. */ -static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) +static int atkbd_event(struct input_dev *dev, + unsigned int type, unsigned int code, int value) { struct atkbd *atkbd = input_get_drvdata(dev); @@ -594,19 +613,12 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co switch (type) { case EV_LED: - set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask); - wmb(); - schedule_work(&atkbd->event_work); + atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); return 0; case EV_REP: - - if (!atkbd->softrepeat) { - set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask); - wmb(); - schedule_work(&atkbd->event_work); - } - + if (!atkbd->softrepeat) + atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); return 0; } @@ -940,7 +952,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); - INIT_WORK(&atkbd->event_work, atkbd_event_work); + INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); mutex_init(&atkbd->event_mutex); switch (serio->id.type) { From 9f7a60d6e47a70957e5f6676cfe8c83956b08aa6 Mon Sep 17 00:00:00 2001 From: Qi Yong Date: Thu, 28 Jun 2007 00:47:10 -0400 Subject: [PATCH 006/551] Input: atkbd - use printk_ratelimit for spurious ACK messages Signed-off-by: Qi Yong Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 9e80012d0d0c..9950fcb33650 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -409,9 +409,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, goto out; case ATKBD_RET_ACK: case ATKBD_RET_NAK: - printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " - "Some program might be trying access hardware directly.\n", - data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); + if (printk_ratelimit()) + printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " + "Some program might be trying access hardware directly.\n", + data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); goto out; case ATKBD_RET_HANGEUL: case ATKBD_RET_HANJA: From 33143ea1a34d12699e6aa222ba124498abcfe4d1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 29 Jun 2007 01:06:35 -0400 Subject: [PATCH 007/551] Input: serio - take drv_mutex in serio_cleanup() We need to take serio->drv_mutex in serio_cleanup() to prevent the function from being called while driver is in the middle of attaching to a serio port. Such situation can happen with i8042 and atkbd drivers if user rapidly presses Ctrl-Alt-Del during system startup, and leads to kernel oops. Reported-by: Dave Young Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 5895202b972c..a8f3bc1dff22 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -769,8 +769,10 @@ static int serio_driver_remove(struct device *dev) static void serio_cleanup(struct serio *serio) { + mutex_lock(&serio->drv_mutex); if (serio->drv && serio->drv->cleanup) serio->drv->cleanup(serio); + mutex_unlock(&serio->drv_mutex); } static void serio_shutdown(struct device *dev) From c77da1780325d889cac98e8179449ddf54e71ce0 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Fri, 29 Jun 2007 01:08:49 -0400 Subject: [PATCH 008/551] Input: add a new EV_SW SW_RADIO event, for radio switches on laptops Many laptops have rf-kill physical switches that are not keys, but slider or rocker switches. Often (like in all ThinkPads with a radio kill slider switch), they have both a slider/rocker switch and a hot key. Trying to kludge a real switch to act like a key is not a very smart thing to do if you can help it, and it gets specially bad when you are going to have both in the same machine. So, we do the right thing and add an input EV_SW event for radio kill switches. The EV_SW SW_RADIO event is defined with positive logic, i.e. when the switch is active, the radios are to be enabled. When the switch is inactive, the radios are to be disabled. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/input.h b/include/linux/input.h index be2bf3a2b031..48f1ad6d6bb7 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -603,6 +603,7 @@ struct input_absinfo { #define SW_LID 0x00 /* set = lid shut */ #define SW_TABLET_MODE 0x01 /* set = tablet mode */ #define SW_HEADPHONE_INSERT 0x02 /* set = inserted */ +#define SW_RADIO 0x03 /* set = radio enabled */ #define SW_MAX 0x0f /* From 4e4eda866ec7bd7a151e4884a291221eb74644ae Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 29 Jun 2007 01:10:54 -0400 Subject: [PATCH 009/551] Input: document some of keycodes Document some of keycodes, based on USB HUT 1.12 and current mapping in HID driver. Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 142 ++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 67 deletions(-) diff --git a/include/linux/input.h b/include/linux/input.h index 48f1ad6d6bb7..d8521c72f69f 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -108,6 +108,13 @@ struct input_absinfo { /* * Keys and buttons + * + * Most of the keys/buttons are modeled after USB HUT 1.12 + * (see http://www.usb.org/developers/hidpage). + * Abbreviations in the comments: + * AC - Application Control + * AL - Application Launch Button + * SC - System Control */ #define KEY_RESERVED 0 @@ -226,7 +233,7 @@ struct input_absinfo { #define KEY_MUTE 113 #define KEY_VOLUMEDOWN 114 #define KEY_VOLUMEUP 115 -#define KEY_POWER 116 +#define KEY_POWER 116 /* SC System Power Down */ #define KEY_KPEQUAL 117 #define KEY_KPPLUSMINUS 118 #define KEY_PAUSE 119 @@ -240,38 +247,39 @@ struct input_absinfo { #define KEY_RIGHTMETA 126 #define KEY_COMPOSE 127 -#define KEY_STOP 128 +#define KEY_STOP 128 /* AC Stop */ #define KEY_AGAIN 129 -#define KEY_PROPS 130 -#define KEY_UNDO 131 +#define KEY_PROPS 130 /* AC Properties */ +#define KEY_UNDO 131 /* AC Undo */ #define KEY_FRONT 132 -#define KEY_COPY 133 -#define KEY_OPEN 134 -#define KEY_PASTE 135 -#define KEY_FIND 136 -#define KEY_CUT 137 -#define KEY_HELP 138 -#define KEY_MENU 139 -#define KEY_CALC 140 +#define KEY_COPY 133 /* AC Copy */ +#define KEY_OPEN 134 /* AC Open */ +#define KEY_PASTE 135 /* AC Paste */ +#define KEY_FIND 136 /* AC Search */ +#define KEY_CUT 137 /* AC Cut */ +#define KEY_HELP 138 /* AL Integrated Help Center */ +#define KEY_MENU 139 /* Menu (show menu) */ +#define KEY_CALC 140 /* AL Calculator */ #define KEY_SETUP 141 -#define KEY_SLEEP 142 -#define KEY_WAKEUP 143 -#define KEY_FILE 144 +#define KEY_SLEEP 142 /* SC System Sleep */ +#define KEY_WAKEUP 143 /* System Wake Up */ +#define KEY_FILE 144 /* AL Local Machine Browser */ #define KEY_SENDFILE 145 #define KEY_DELETEFILE 146 #define KEY_XFER 147 #define KEY_PROG1 148 #define KEY_PROG2 149 -#define KEY_WWW 150 +#define KEY_WWW 150 /* AL Internet Browser */ #define KEY_MSDOS 151 -#define KEY_COFFEE 152 +#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */ +#define KEY_SCREENLOCK KEY_COFFEE #define KEY_DIRECTION 153 #define KEY_CYCLEWINDOWS 154 #define KEY_MAIL 155 -#define KEY_BOOKMARKS 156 +#define KEY_BOOKMARKS 156 /* AC Bookmarks */ #define KEY_COMPUTER 157 -#define KEY_BACK 158 -#define KEY_FORWARD 159 +#define KEY_BACK 158 /* AC Back */ +#define KEY_FORWARD 159 /* AC Forward */ #define KEY_CLOSECD 160 #define KEY_EJECTCD 161 #define KEY_EJECTCLOSECD 162 @@ -281,20 +289,20 @@ struct input_absinfo { #define KEY_STOPCD 166 #define KEY_RECORD 167 #define KEY_REWIND 168 -#define KEY_PHONE 169 +#define KEY_PHONE 169 /* Media Select Telephone */ #define KEY_ISO 170 -#define KEY_CONFIG 171 -#define KEY_HOMEPAGE 172 -#define KEY_REFRESH 173 -#define KEY_EXIT 174 +#define KEY_CONFIG 171 /* AL Consumer Control Configuration */ +#define KEY_HOMEPAGE 172 /* AC Home */ +#define KEY_REFRESH 173 /* AC Refresh */ +#define KEY_EXIT 174 /* AC Exit */ #define KEY_MOVE 175 #define KEY_EDIT 176 #define KEY_SCROLLUP 177 #define KEY_SCROLLDOWN 178 #define KEY_KPLEFTPAREN 179 #define KEY_KPRIGHTPAREN 180 -#define KEY_NEW 181 -#define KEY_REDO 182 +#define KEY_NEW 181 /* AC New */ +#define KEY_REDO 182 /* AC Redo/Repeat */ #define KEY_F13 183 #define KEY_F14 184 @@ -314,11 +322,11 @@ struct input_absinfo { #define KEY_PROG3 202 #define KEY_PROG4 203 #define KEY_SUSPEND 205 -#define KEY_CLOSE 206 +#define KEY_CLOSE 206 /* AC Close */ #define KEY_PLAY 207 #define KEY_FASTFORWARD 208 #define KEY_BASSBOOST 209 -#define KEY_PRINT 210 +#define KEY_PRINT 210 /* AC Print */ #define KEY_HP 211 #define KEY_CAMERA 212 #define KEY_SOUND 213 @@ -327,11 +335,11 @@ struct input_absinfo { #define KEY_CHAT 216 #define KEY_SEARCH 217 #define KEY_CONNECT 218 -#define KEY_FINANCE 219 +#define KEY_FINANCE 219 /* AL Checkbook/Finance */ #define KEY_SPORT 220 #define KEY_SHOP 221 #define KEY_ALTERASE 222 -#define KEY_CANCEL 223 +#define KEY_CANCEL 223 /* AC Cancel */ #define KEY_BRIGHTNESSDOWN 224 #define KEY_BRIGHTNESSUP 225 #define KEY_MEDIA 226 @@ -341,10 +349,10 @@ struct input_absinfo { #define KEY_KBDILLUMDOWN 229 #define KEY_KBDILLUMUP 230 -#define KEY_SEND 231 -#define KEY_REPLY 232 -#define KEY_FORWARDMAIL 233 -#define KEY_SAVE 234 +#define KEY_SEND 231 /* AC Send */ +#define KEY_REPLY 232 /* AC Reply */ +#define KEY_FORWARDMAIL 233 /* AC Forward Msg */ +#define KEY_SAVE 234 /* AC Save */ #define KEY_DOCUMENTS 235 #define KEY_BATTERY 236 @@ -433,15 +441,15 @@ struct input_absinfo { #define KEY_CLEAR 0x163 #define KEY_POWER2 0x164 #define KEY_OPTION 0x165 -#define KEY_INFO 0x166 +#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */ #define KEY_TIME 0x167 #define KEY_VENDOR 0x168 #define KEY_ARCHIVE 0x169 -#define KEY_PROGRAM 0x16a +#define KEY_PROGRAM 0x16a /* Media Select Program Guide */ #define KEY_CHANNEL 0x16b #define KEY_FAVORITES 0x16c #define KEY_EPG 0x16d -#define KEY_PVR 0x16e +#define KEY_PVR 0x16e /* Media Select Home */ #define KEY_MHP 0x16f #define KEY_LANGUAGE 0x170 #define KEY_TITLE 0x171 @@ -451,36 +459,36 @@ struct input_absinfo { #define KEY_MODE 0x175 #define KEY_KEYBOARD 0x176 #define KEY_SCREEN 0x177 -#define KEY_PC 0x178 -#define KEY_TV 0x179 -#define KEY_TV2 0x17a -#define KEY_VCR 0x17b -#define KEY_VCR2 0x17c -#define KEY_SAT 0x17d +#define KEY_PC 0x178 /* Media Select Computer */ +#define KEY_TV 0x179 /* Media Select TV */ +#define KEY_TV2 0x17a /* Media Select Cable */ +#define KEY_VCR 0x17b /* Media Select VCR */ +#define KEY_VCR2 0x17c /* VCR Plus */ +#define KEY_SAT 0x17d /* Media Select Satellite */ #define KEY_SAT2 0x17e -#define KEY_CD 0x17f -#define KEY_TAPE 0x180 +#define KEY_CD 0x17f /* Media Select CD */ +#define KEY_TAPE 0x180 /* Media Select Tape */ #define KEY_RADIO 0x181 -#define KEY_TUNER 0x182 +#define KEY_TUNER 0x182 /* Media Select Tuner */ #define KEY_PLAYER 0x183 #define KEY_TEXT 0x184 -#define KEY_DVD 0x185 +#define KEY_DVD 0x185 /* Media Select DVD */ #define KEY_AUX 0x186 #define KEY_MP3 0x187 #define KEY_AUDIO 0x188 #define KEY_VIDEO 0x189 #define KEY_DIRECTORY 0x18a #define KEY_LIST 0x18b -#define KEY_MEMO 0x18c +#define KEY_MEMO 0x18c /* Media Select Messages */ #define KEY_CALENDAR 0x18d #define KEY_RED 0x18e #define KEY_GREEN 0x18f #define KEY_YELLOW 0x190 #define KEY_BLUE 0x191 -#define KEY_CHANNELUP 0x192 -#define KEY_CHANNELDOWN 0x193 +#define KEY_CHANNELUP 0x192 /* Channel Increment */ +#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */ #define KEY_FIRST 0x194 -#define KEY_LAST 0x195 +#define KEY_LAST 0x195 /* Recall Last */ #define KEY_AB 0x196 #define KEY_NEXT 0x197 #define KEY_RESTART 0x198 @@ -491,21 +499,21 @@ struct input_absinfo { #define KEY_DIGITS 0x19d #define KEY_TEEN 0x19e #define KEY_TWEN 0x19f -#define KEY_VIDEOPHONE 0x1a0 -#define KEY_GAMES 0x1a1 -#define KEY_ZOOMIN 0x1a2 -#define KEY_ZOOMOUT 0x1a3 -#define KEY_ZOOMRESET 0x1a4 -#define KEY_WORDPROCESSOR 0x1a5 -#define KEY_EDITOR 0x1a6 -#define KEY_SPREADSHEET 0x1a7 -#define KEY_GRAPHICSEDITOR 0x1a8 -#define KEY_PRESENTATION 0x1a9 -#define KEY_DATABASE 0x1aa -#define KEY_NEWS 0x1ab -#define KEY_VOICEMAIL 0x1ac -#define KEY_ADDRESSBOOK 0x1ad -#define KEY_MESSENGER 0x1ae +#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */ +#define KEY_GAMES 0x1a1 /* Media Select Games */ +#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */ +#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */ +#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */ +#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */ +#define KEY_EDITOR 0x1a6 /* AL Text Editor */ +#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */ +#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */ +#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */ +#define KEY_DATABASE 0x1aa /* AL Database App */ +#define KEY_NEWS 0x1ab /* AL Newsreader */ +#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */ +#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */ +#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */ #define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */ #define KEY_DEL_EOL 0x1c0 From 86affd5a00a92e491e5f00ed659492767519fdf7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 28 Jun 2007 11:27:57 +1000 Subject: [PATCH 010/551] [POWERPC] Disable old EMAC driver in arch/powerpc The EMAC driver, in drivers/net/ibm_emac, for the embedded Ethernet MAC found in PowerPC 4xx embedded chips is not suitable for arch/powerpc. It will not build because it relies on the old arch/ppc OCP mechanism. BenH has a new, device-tree aware version of the driver which will work in arch/powerpc, but until it's merged, this patch will disable the old, non-building version. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7d57f4a25dc1..b49375abb5f4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1187,7 +1187,7 @@ config IBMVETH config IBM_EMAC tristate "PowerPC 4xx on-chip Ethernet support" - depends on 4xx + depends on 4xx && !PPC_MERGE help This driver supports the PowerPC 4xx EMAC family of on-chip Ethernet controllers. From ee5d1b7f2a01ce4d95ca247b5a499b72f31cdbe8 Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Thu, 28 Jun 2007 21:14:38 +1000 Subject: [PATCH 011/551] [POWERPC] Fix PMI breakage in cbe_cbufreq driver The recent change to cell_defconfig to enable cpufreq on Cell exposed the fact that the cbe_cpufreq driver currently needs the PMI interface code to compile, but Kconfig doesn't make sure that the PMI interface code gets built if cbe_cpufreq is enabled. In fact cbe_cpufreq can work without PMI, so this ifdefs out the code that deals with PMI. This is a minimal solution for 2.6.22; a more comprehensive solution will be merged for 2.6.23. Signed-off-by: Christian Krafft Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_cpufreq.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index ac445998d831..ab511d5b65a4 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -74,6 +74,7 @@ static unsigned int pmi_frequency_limit = 0; static struct of_device *pmi_dev; +#ifdef CONFIG_PPC_PMI static int set_pmode_pmi(int cpu, unsigned int pmode) { int ret; @@ -102,7 +103,7 @@ static int set_pmode_pmi(int cpu, unsigned int pmode) #endif return ret; } - +#endif static int get_pmode(int cpu) { @@ -157,9 +158,11 @@ static int set_pmode_reg(int cpu, unsigned int pmode) } static int set_pmode(int cpu, unsigned int slow_mode) { +#ifdef CONFIG_PPC_PMI if (pmi_dev) return set_pmode_pmi(cpu, slow_mode); else +#endif return set_pmode_reg(cpu, slow_mode); } @@ -323,26 +326,28 @@ static struct cpufreq_driver cbe_cpufreq_driver = { static int __init cbe_cpufreq_init(void) { +#ifdef CONFIG_PPC_PMI struct device_node *np; - +#endif if (!machine_is(cell)) return -ENODEV; - +#ifdef CONFIG_PPC_PMI np = of_find_node_by_type(NULL, "ibm,pmi"); pmi_dev = of_find_device_by_node(np); if (pmi_dev) pmi_register_handler(pmi_dev, &cbe_pmi_handler); - +#endif return cpufreq_register_driver(&cbe_cpufreq_driver); } static void __exit cbe_cpufreq_exit(void) { +#ifdef CONFIG_PPC_PMI if (pmi_dev) pmi_unregister_handler(pmi_dev, &cbe_pmi_handler); - +#endif cpufreq_unregister_driver(&cbe_cpufreq_driver); } From 9f7905812e5919862acb6ede63e10d3d1bb4958e Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 4 Jun 2007 14:47:04 +1000 Subject: [PATCH 012/551] [POWERPC] Uninline and export virq_to_hw() for the pasemi_mac driver Uninline virq_to_hw and export it so modules can use it. The alternative would be to export the irq_map array instead, but it's an infrequently called function, and keeping the array unexported seems considerably cleaner. This is needed so that the pasemi_mac driver can be compiled as a module. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 6 ++++++ include/asm-powerpc/irq.h | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 42c8ed6ed528..c2b84c64db20 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -412,6 +412,12 @@ struct irq_map_entry irq_map[NR_IRQS]; static unsigned int irq_virq_count = NR_IRQS; static struct irq_host *irq_default_host; +irq_hw_number_t virq_to_hw(unsigned int virq) +{ + return irq_map[virq].hwirq; +} +EXPORT_SYMBOL_GPL(virq_to_hw); + struct irq_host *irq_alloc_host(unsigned int revmap_type, unsigned int revmap_arg, struct irq_host_ops *ops, diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 4734cc178db5..05dd5a3eb3aa 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h @@ -138,10 +138,7 @@ struct irq_map_entry { extern struct irq_map_entry irq_map[NR_IRQS]; -static inline irq_hw_number_t virq_to_hw(unsigned int virq) -{ - return irq_map[virq].hwirq; -} +extern irq_hw_number_t virq_to_hw(unsigned int virq); /** * irq_alloc_host - Allocate a new irq_host data structure From 795bb15e0735bd2b0015ca333fa157399b72c168 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 2 Jul 2007 00:04:36 -0500 Subject: [PATCH 013/551] [POWERPC] Update defconfigs Signed-off-by: Kumar Gala --- arch/powerpc/configs/mpc7448_hpc2_defconfig | 216 ++++++------- arch/powerpc/configs/mpc8272_ads_defconfig | 297 +++++++++++------- arch/powerpc/configs/mpc8313_rdb_defconfig | 312 ++++++++++--------- arch/powerpc/configs/mpc832x_mds_defconfig | 178 +++++------ arch/powerpc/configs/mpc832x_rdb_defconfig | 229 ++++++-------- arch/powerpc/configs/mpc834x_itx_defconfig | 267 ++++++++-------- arch/powerpc/configs/mpc834x_itxgp_defconfig | 236 +++++++------- arch/powerpc/configs/mpc834x_mds_defconfig | 199 ++++++------ arch/powerpc/configs/mpc836x_mds_defconfig | 178 +++++------ arch/powerpc/configs/mpc8540_ads_defconfig | 205 ++++++------ arch/powerpc/configs/mpc8544_ds_defconfig | 193 +++++------- arch/powerpc/configs/mpc8560_ads_defconfig | 205 ++++++------ arch/powerpc/configs/mpc8568mds_defconfig | 195 +++++------- arch/powerpc/configs/mpc85xx_cds_defconfig | 210 ++++++------- arch/powerpc/configs/mpc8641_hpcn_defconfig | 204 ++++++------ arch/powerpc/configs/mpc866_ads_defconfig | 217 +++++++------ arch/powerpc/configs/mpc885_ads_defconfig | 226 +++++++------- 17 files changed, 1789 insertions(+), 1978 deletions(-) diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index fdf09eabe6e7..174a290ee7a9 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:20:53 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:54 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -34,9 +34,9 @@ CONFIG_CLASSIC32=y # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set # CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_6xx=y CONFIG_PPC_FPU=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_ALTIVEC is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -84,14 +88,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -126,8 +135,18 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_EMBEDDED6xx=y # CONFIG_APUS is not set # CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_LINKSTATION is not set +CONFIG_MPC7448HPC2=y +# CONFIG_PPC_HOLLY is not set +# CONFIG_PPC_PRPMC2800 is not set +CONFIG_TSI108_BRIDGE=y +CONFIG_MPIC=y +CONFIG_MPIC_WEIRD=y +# CONFIG_PPC_I8259 is not set # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set # CONFIG_PPC_MPC106 is not set @@ -136,36 +155,7 @@ CONFIG_EMBEDDED6xx=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_TAU is not set -# CONFIG_KATANA is not set -# CONFIG_WILLOW is not set -# CONFIG_CPCI690 is not set -# CONFIG_POWERPMC250 is not set -# CONFIG_CHESTNUT is not set -# CONFIG_SPRUCE is not set -# CONFIG_HDPU is not set -# CONFIG_EV64260 is not set -# CONFIG_LOPEC is not set -# CONFIG_MVME5100 is not set -# CONFIG_PPLUS is not set -# CONFIG_PRPMC750 is not set -# CONFIG_PRPMC800 is not set -# CONFIG_SANDPOINT is not set -# CONFIG_LINKSTATION is not set -CONFIG_MPC7448HPC2=y -# CONFIG_RADSTONE_PPC7D is not set -# CONFIG_PAL4 is not set -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set -# CONFIG_SBC82xx is not set -# CONFIG_SBS8260 is not set -# CONFIG_RPX8260 is not set -# CONFIG_TQM8260 is not set -# CONFIG_ADS8272 is not set -# CONFIG_PQ2FADS is not set -# CONFIG_EV64360 is not set -CONFIG_TSI108_BRIDGE=y -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_MPIC=y +# CONFIG_CPM2 is not set # # Kernel options @@ -193,31 +183,30 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -CONFIG_MPIC_WEIRD=y -# CONFIG_PPC_I8259 is not set # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -242,13 +231,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -282,20 +271,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -321,7 +298,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -339,10 +325,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -353,6 +335,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -371,19 +354,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -460,11 +440,8 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set @@ -480,10 +457,12 @@ CONFIG_SATA_MV=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -495,6 +474,7 @@ CONFIG_SATA_MV=y # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set @@ -532,18 +512,14 @@ CONFIG_SATA_MV=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -553,15 +529,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -615,10 +583,8 @@ CONFIG_8139TOO=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -635,29 +601,22 @@ CONFIG_8139TOO=y # CONFIG_BNX2 is not set CONFIG_TSI108_ETH=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -684,6 +643,7 @@ CONFIG_TSI108_ETH=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -700,6 +660,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -732,6 +693,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -740,16 +702,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -760,10 +717,7 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -776,35 +730,41 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -815,6 +775,7 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -832,10 +793,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -878,10 +835,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -967,6 +920,7 @@ CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -996,6 +950,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1006,6 +961,7 @@ CONFIG_MSDOS_PARTITION=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -1013,10 +969,13 @@ CONFIG_MSDOS_PARTITION=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1033,7 +992,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig index 2af45025082f..4a429294e4da 100644 --- a/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/arch/powerpc/configs/mpc8272_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc5 -# Fri Jul 14 20:36:35 2006 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:55 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -10,6 +10,7 @@ CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -21,25 +22,31 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y # CONFIG_PPC_UDBG_16550 is not set # CONFIG_GENERIC_TBSYNC is not set -# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFAULT_UIMAGE=y # # Processor support # # CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set CONFIG_PPC_82xx=y # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_6xx=y CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -55,14 +62,21 @@ CONFIG_LOCALVERSION="powerpc8272" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_EXTRA_PASS=y @@ -72,12 +86,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -87,6 +108,7 @@ CONFIG_BASE_SMALL=0 # # Block layer # +CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -103,17 +125,29 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PQ2ADS=y -CONFIG_8260=y -CONFIG_8272=y -CONFIG_CPM2=y -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y # # Platform support # -CONFIG_ADS8272=y +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +CONFIG_MPC82xx_ADS=y +CONFIG_PQ2ADS=y +CONFIG_8260=y +CONFIG_8272=y +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +CONFIG_CPM2=y # # Kernel options @@ -121,6 +155,7 @@ CONFIG_ADS8272=y # CONFIG_HIGHMEM is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y @@ -128,36 +163,36 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y -# CONFIG_PC_KEYBOARD is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set CONFIG_SECCOMP=y +# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -180,10 +215,11 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -201,15 +237,15 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set @@ -219,7 +255,12 @@ CONFIG_IPV6=y # CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -227,13 +268,16 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NF_CONNTRACK_ENABLED is not set +# CONFIG_NF_CONNTRACK is not set # CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration # -# CONFIG_IP_NF_CONNTRACK is not set # CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set @@ -253,7 +297,14 @@ CONFIG_NETFILTER=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -266,15 +317,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -285,6 +334,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -295,14 +345,15 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # -# ATA/ATAPI/MFM/RLL support +# Misc devices # +# CONFIG_BLINK is not set CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -314,14 +365,15 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes # # CONFIG_IDE_GENERIC is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set # 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 # @@ -329,29 +381,14 @@ CONFIG_BLK_DEV_IDEDISK=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -361,10 +398,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=y - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -375,6 +408,9 @@ CONFIG_DAVICOM_PHY=y # CONFIG_QSEMI_PHY is not set # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set # CONFIG_FIXED_PHY is not set # @@ -385,27 +421,14 @@ CONFIG_MII=y CONFIG_FS_ENET=y # CONFIG_FS_ENET_HAS_SCC is not set CONFIG_FS_ENET_HAS_FCC=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set CONFIG_PPP=y # CONFIG_PPP_FILTER is not set @@ -414,6 +437,7 @@ CONFIG_PPP_SYNC_TTY=y CONFIG_PPP_DEFLATE=y # CONFIG_PPP_BSDCOMP is not set # CONFIG_SLIP is not set +CONFIG_SLHC=y # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -431,6 +455,8 @@ CONFIG_PPP_DEFLATE=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -453,11 +479,19 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -485,6 +519,7 @@ CONFIG_SERIO_LIBPS2=y # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_CPM=y @@ -503,29 +538,16 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y # CONFIG_NVRAM 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_AGP is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # - -# -# I2C support -# # CONFIG_I2C is not set # @@ -538,38 +560,44 @@ CONFIG_LEGACY_PTY_COUNT=256 # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # -# Misc devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set +# CONFIG_FB_IBM_GXT4500 is not set # # Sound # # CONFIG_SOUND is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # @@ -586,6 +614,7 @@ CONFIG_VIDEO_V4L2=y # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_PXA2XX is not set # CONFIG_USB_GADGET_GOKU is not set @@ -594,10 +623,6 @@ CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -625,6 +650,19 @@ CONFIG_USB_GADGET=y # Real Time Clock # +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + # # File systems # @@ -645,9 +683,12 @@ CONFIG_XFS_FS=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -672,8 +713,10 @@ CONFIG_AUTOFS4_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -694,6 +737,7 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -727,6 +771,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -771,37 +816,55 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y +# CONFIG_UCC_SLOW is not set # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_KGDB_CONSOLE is not set CONFIG_BDI_SWITCH=y @@ -818,6 +881,9 @@ CONFIG_BDI_SWITCH=y # Cryptographic options # CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -827,7 +893,12 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -841,7 +912,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_CAMELLIA is not set # # Hardware crypto devices diff --git a/arch/powerpc/configs/mpc8313_rdb_defconfig b/arch/powerpc/configs/mpc8313_rdb_defconfig index f87523716c44..b7d3dffc981a 100644 --- a/arch/powerpc/configs/mpc8313_rdb_defconfig +++ b/arch/powerpc/configs/mpc8313_rdb_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Wed Feb 7 22:08:04 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:55 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -83,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -122,19 +131,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set CONFIG_MPC8313_RDB=y # CONFIG_MPC832x_MDS is not set -# CONFIG_MPC834x_SYS is not set +# CONFIG_MPC832x_RDB is not set +# CONFIG_MPC834x_MDS is not set # CONFIG_MPC834x_ITX is not set -# CONFIG_MPC8360E_PB is not set +# CONFIG_MPC836x_MDS is not set CONFIG_PPC_MPC831x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -162,33 +185,34 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -213,13 +237,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -253,20 +277,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -292,7 +304,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -305,16 +326,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -357,7 +375,6 @@ CONFIG_MTD_CFI_UTIL=y # 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 @@ -387,17 +404,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # 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 -# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -407,6 +420,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -426,19 +440,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -467,6 +478,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -514,10 +526,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -545,18 +553,14 @@ CONFIG_MD_RAID1=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -566,15 +570,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -624,10 +620,8 @@ CONFIG_E100=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -645,29 +639,32 @@ CONFIG_E100=y CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -694,6 +691,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -710,6 +708,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -742,6 +741,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -750,10 +750,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -776,7 +772,6 @@ CONFIG_83xx_WDT=y CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -787,11 +782,9 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -818,14 +811,15 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -859,21 +853,21 @@ CONFIG_SPI_MPC83xx=y # # SPI Protocol Masters # +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set # # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set @@ -897,6 +891,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -915,24 +910,31 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # CONFIG_USB_DABUSB is not set # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -943,6 +945,18 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set # # USB support @@ -957,7 +971,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -968,9 +982,15 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -1001,44 +1021,11 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -1060,6 +1047,7 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1070,6 +1058,7 @@ CONFIG_USB_MON=y # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # @@ -1082,6 +1071,7 @@ CONFIG_USB_MON=y CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_FSL_USB2 is not set CONFIG_USB_GADGET_NET2280=y CONFIG_USB_NET2280=y # CONFIG_USB_GADGET_PXA2XX is not set @@ -1098,10 +1088,6 @@ CONFIG_USB_ETH_RNDIS=y # CONFIG_USB_FILE_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -1142,25 +1128,38 @@ CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set # -# RTC drivers +# I2C RTC drivers # -# CONFIG_RTC_DRV_X1205 is not set CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set + +# +# SPI RTC drivers +# # CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_V3020 is not set +# +# on-CPU RTC drivers +# + # # DMA Engine support # @@ -1176,10 +1175,6 @@ CONFIG_NET_DMA=y # CONFIG_INTEL_IOATDMA=y -# -# Virtualization -# - # # File systems # @@ -1269,6 +1264,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1298,6 +1294,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1308,6 +1305,7 @@ CONFIG_MSDOS_PARTITION=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -1315,10 +1313,13 @@ CONFIG_MSDOS_PARTITION=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1335,15 +1336,15 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1353,12 +1354,13 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # @@ -1387,8 +1389,11 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_ECB is not set CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1402,6 +1407,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/powerpc/configs/mpc832x_mds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig index 83192c0dc5bb..75ce78139a11 100644 --- a/arch/powerpc/configs/mpc832x_mds_defconfig +++ b/arch/powerpc/configs/mpc832x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:09:16 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:55 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -70,6 +71,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -85,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -124,12 +131,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_QUICC_ENGINE=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8313_RDB is not set CONFIG_MPC832x_MDS=y # CONFIG_MPC832x_RDB is not set @@ -138,6 +148,17 @@ CONFIG_MPC832x_MDS=y # CONFIG_MPC836x_MDS is not set CONFIG_PPC_MPC832x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +CONFIG_QUICC_ENGINE=y +# CONFIG_CPM2 is not set # # Kernel options @@ -171,6 +192,8 @@ CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # @@ -178,22 +201,19 @@ CONFIG_ISA_DMA_API=y # CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -218,7 +238,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -259,20 +278,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -298,7 +305,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -316,10 +332,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -355,12 +367,10 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -389,6 +399,7 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -436,10 +447,6 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -458,18 +465,14 @@ CONFIG_SCSI_PROC_FS=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -479,15 +482,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -501,7 +496,6 @@ CONFIG_DAVICOM_PHY=y # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set # CONFIG_FIXED_PHY is not set # @@ -520,10 +514,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -535,6 +526,7 @@ CONFIG_MII=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_GIANFAR is not set @@ -542,33 +534,24 @@ CONFIG_UCC_GETH=y # CONFIG_UGETH_NAPI is not set # CONFIG_UGETH_MAGIC_PACKET is not set # CONFIG_UGETH_FILTERING is not set -# CONFIG_UGETH_TX_ON_DEMOND is not set +# CONFIG_UGETH_TX_ON_DEMAND is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -595,6 +578,7 @@ CONFIG_UCC_GETH=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -611,6 +595,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -652,10 +637,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -674,7 +655,6 @@ CONFIG_HW_RANDOM=y # 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -685,11 +665,9 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -714,9 +692,9 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -724,7 +702,6 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -752,13 +729,10 @@ CONFIG_I2C_MPC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -785,6 +759,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -812,16 +787,19 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -852,10 +830,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -898,14 +872,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -994,6 +960,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1019,6 +986,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1039,11 +1007,13 @@ CONFIG_UCC=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1060,7 +1030,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -1093,6 +1062,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/arch/powerpc/configs/mpc832x_rdb_defconfig b/arch/powerpc/configs/mpc832x_rdb_defconfig index 4a4da875fa4e..6a83b66dd99e 100644 --- a/arch/powerpc/configs/mpc832x_rdb_defconfig +++ b/arch/powerpc/configs/mpc832x_rdb_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:12:43 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:56 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -70,6 +71,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -85,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -124,12 +131,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_QUICC_ENGINE=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set CONFIG_MPC832x_RDB=y @@ -138,6 +148,17 @@ CONFIG_MPC832x_RDB=y # CONFIG_MPC836x_MDS is not set CONFIG_PPC_MPC832x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +CONFIG_QUICC_ENGINE=y +# CONFIG_CPM2 is not set # # Kernel options @@ -171,6 +192,8 @@ CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # @@ -178,22 +201,19 @@ CONFIG_ISA_DMA_API=y # CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -218,7 +238,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -259,20 +278,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -298,7 +305,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -316,10 +332,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -356,12 +368,10 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -390,6 +400,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -437,10 +448,6 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -459,18 +466,14 @@ CONFIG_BLK_DEV_SD=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -480,15 +483,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -502,7 +497,6 @@ CONFIG_PHYLIB=y # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set -CONFIG_ICPLUS_PHY=y # CONFIG_FIXED_PHY is not set # @@ -521,10 +515,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y @@ -538,6 +529,7 @@ CONFIG_E1000=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_GIANFAR is not set @@ -545,33 +537,34 @@ CONFIG_UCC_GETH=y CONFIG_UGETH_NAPI=y # CONFIG_UGETH_MAGIC_PACKET is not set # CONFIG_UGETH_FILTERING is not set -# CONFIG_UGETH_TX_ON_DEMOND is not set +# CONFIG_UGETH_TX_ON_DEMAND is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -598,6 +591,7 @@ CONFIG_UGETH_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -614,6 +608,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -655,10 +650,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -682,7 +673,6 @@ CONFIG_HW_RANDOM=y # 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -693,11 +683,9 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -722,17 +710,17 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -760,13 +748,10 @@ CONFIG_I2C_MPC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -793,6 +778,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -820,17 +806,20 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # CONFIG_USB_DABUSB is not set # # Graphics support # # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -845,6 +834,17 @@ CONFIG_HWMON=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + # # USB support # @@ -858,6 +858,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -907,45 +908,11 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -989,10 +956,6 @@ CONFIG_USB_MON=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -1035,14 +998,6 @@ CONFIG_USB_MON=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -1134,6 +1089,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1164,6 +1120,7 @@ CONFIG_LDM_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1223,11 +1180,13 @@ CONFIG_UCC=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1244,7 +1203,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -1277,6 +1235,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig index 23d8964846e0..85470b8cae09 100644 --- a/arch/powerpc/configs/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/mpc834x_itx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Wed Feb 7 13:12:18 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:56 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -83,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -122,18 +131,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set -# CONFIG_MPC834x_SYS is not set +# CONFIG_MPC832x_RDB is not set +# CONFIG_MPC834x_MDS is not set CONFIG_MPC834x_ITX=y -# CONFIG_MPC8360E_PB is not set +# CONFIG_MPC836x_MDS is not set CONFIG_MPC834x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -161,32 +185,33 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -211,13 +236,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -251,20 +276,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -290,7 +303,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -308,10 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -354,7 +372,6 @@ CONFIG_MTD_CFI_UTIL=y # 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 @@ -384,17 +401,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # 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 -# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -404,6 +417,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -423,19 +437,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set CONFIG_IDE=y CONFIG_IDE_MAX_HWIFS=4 # CONFIG_BLK_DEV_IDE is not set @@ -468,6 +479,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -516,10 +528,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set @@ -537,10 +545,12 @@ CONFIG_SATA_SIL=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -552,6 +562,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set @@ -598,18 +609,14 @@ CONFIG_MD_RAID1=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -619,15 +626,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -647,10 +646,7 @@ CONFIG_CICADA_PHY=y # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -662,34 +658,38 @@ CONFIG_CICADA_PHY=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -745,6 +745,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -753,10 +754,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -779,7 +776,6 @@ CONFIG_83xx_WDT=y CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -790,11 +786,9 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -821,14 +815,15 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -861,36 +856,40 @@ CONFIG_SPI_MPC83xx=y # # SPI Protocol Masters # +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set # # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -910,7 +909,7 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -921,6 +920,7 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_OHCI_HCD is not set # CONFIG_USB_UHCI_HCD is not set @@ -952,29 +952,11 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set -# -# USB Input Devices -# - -# -# USB HID Boot Protocol drivers -# - # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -996,6 +978,7 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1006,6 +989,7 @@ CONFIG_USB_MON=y # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # @@ -1016,10 +1000,6 @@ CONFIG_USB_MON=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -1060,25 +1040,38 @@ CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set # -# RTC drivers +# I2C RTC drivers # -# CONFIG_RTC_DRV_X1205 is not set CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set + +# +# SPI RTC drivers +# # CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_V3020 is not set +# +# on-CPU RTC drivers +# + # # DMA Engine support # @@ -1094,10 +1087,6 @@ CONFIG_NET_DMA=y # CONFIG_INTEL_IOATDMA=y -# -# Virtualization -# - # # File systems # @@ -1190,6 +1179,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1219,6 +1209,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1268,6 +1259,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -1275,10 +1267,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1295,10 +1290,8 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # @@ -1327,8 +1320,11 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_ECB is not set CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1342,6 +1338,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/powerpc/configs/mpc834x_itxgp_defconfig b/arch/powerpc/configs/mpc834x_itxgp_defconfig index 4aa666c9cb94..704ee8b285bf 100644 --- a/arch/powerpc/configs/mpc834x_itxgp_defconfig +++ b/arch/powerpc/configs/mpc834x_itxgp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Fri Feb 9 13:28:19 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:56 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -83,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -122,18 +131,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set -# CONFIG_MPC834x_SYS is not set +# CONFIG_MPC832x_RDB is not set +# CONFIG_MPC834x_MDS is not set CONFIG_MPC834x_ITX=y -# CONFIG_MPC8360E_PB is not set +# CONFIG_MPC836x_MDS is not set CONFIG_MPC834x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -161,32 +185,33 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -211,13 +236,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -251,20 +276,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -290,7 +303,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -308,10 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -354,7 +372,6 @@ CONFIG_MTD_CFI_UTIL=y # 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 @@ -384,17 +401,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # 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 -# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -404,6 +417,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -422,19 +436,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -463,6 +474,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -510,10 +522,6 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -532,18 +540,14 @@ CONFIG_SCSI_SPI_ATTRS=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -553,15 +557,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -581,10 +577,7 @@ CONFIG_CICADA_PHY=y # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -596,34 +589,28 @@ CONFIG_CICADA_PHY=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -679,6 +666,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -687,10 +675,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -708,7 +692,6 @@ CONFIG_83xx_WDT=y CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -719,11 +702,9 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -750,6 +731,7 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -757,7 +739,6 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -790,35 +771,39 @@ CONFIG_SPI_MPC83xx=y # # SPI Protocol Masters # +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set # # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -841,10 +826,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -885,25 +866,38 @@ CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set # -# RTC drivers +# I2C RTC drivers # -# CONFIG_RTC_DRV_X1205 is not set CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set + +# +# SPI RTC drivers +# # CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_V3020 is not set +# +# on-CPU RTC drivers +# + # # DMA Engine support # @@ -919,10 +913,6 @@ CONFIG_NET_DMA=y # CONFIG_INTEL_IOATDMA=y -# -# Virtualization -# - # # File systems # @@ -1015,6 +1005,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1044,6 +1035,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1093,6 +1085,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -1100,10 +1093,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1120,10 +1116,8 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # @@ -1152,8 +1146,11 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_ECB is not set CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1167,6 +1164,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/powerpc/configs/mpc834x_mds_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig index 2e3f8efb6ab1..c28b3ee3cb12 100644 --- a/arch/powerpc/configs/mpc834x_mds_defconfig +++ b/arch/powerpc/configs/mpc834x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Thu Feb 8 01:00:48 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:57 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -83,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -122,19 +131,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set +# CONFIG_MPC832x_RDB is not set CONFIG_MPC834x_MDS=y # CONFIG_MPC834x_ITX is not set -# CONFIG_MPC8360E_PB is not set +# CONFIG_MPC836x_MDS is not set CONFIG_MPC834x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -162,32 +185,33 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -212,13 +236,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -252,20 +276,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -291,7 +303,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -309,10 +330,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -323,6 +340,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -341,19 +359,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -362,10 +377,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -381,18 +392,14 @@ CONFIG_BLK_DEV_INITRD=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -402,15 +409,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -460,10 +459,8 @@ CONFIG_E100=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -481,29 +478,22 @@ CONFIG_E100=y CONFIG_GIANFAR=y # CONFIG_GFAR_NAPI is not set # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -529,6 +519,7 @@ CONFIG_GIANFAR=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -545,6 +536,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -577,6 +569,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -585,10 +578,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -607,7 +596,6 @@ CONFIG_83xx_WDT=y # 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -618,11 +606,9 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -649,6 +635,7 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -656,7 +643,6 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -684,16 +670,14 @@ CONFIG_I2C_MPC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set @@ -716,6 +700,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -734,23 +719,30 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -761,6 +753,7 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -778,10 +771,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -824,10 +813,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -916,6 +901,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -941,6 +927,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -951,6 +938,7 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -958,10 +946,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -978,10 +969,8 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # @@ -1010,8 +999,11 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1025,6 +1017,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/powerpc/configs/mpc836x_mds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig index 921a151dc778..bcbbc167f90d 100644 --- a/arch/powerpc/configs/mpc836x_mds_defconfig +++ b/arch/powerpc/configs/mpc836x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:14:05 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:57 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_MMIO is not set CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -70,6 +71,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -85,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -124,12 +131,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_QUICC_ENGINE=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set # CONFIG_MPC832x_RDB is not set @@ -138,6 +148,17 @@ CONFIG_QUICC_ENGINE=y CONFIG_MPC836x_MDS=y CONFIG_PPC_MPC836x=y # CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +CONFIG_QUICC_ENGINE=y +# CONFIG_CPM2 is not set # # Kernel options @@ -170,6 +191,8 @@ CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # @@ -177,22 +200,19 @@ CONFIG_ISA_DMA_API=y # CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -217,7 +237,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -258,20 +277,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -297,7 +304,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -315,10 +331,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -354,12 +366,10 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -388,6 +398,7 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -435,10 +446,6 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -457,18 +464,14 @@ CONFIG_SCSI_PROC_FS=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -478,15 +481,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -500,7 +495,6 @@ CONFIG_MARVELL_PHY=y # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set # CONFIG_FIXED_PHY is not set # @@ -519,10 +513,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -534,6 +525,7 @@ CONFIG_MII=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_GIANFAR is not set @@ -541,33 +533,24 @@ CONFIG_UCC_GETH=y # CONFIG_UGETH_NAPI is not set # CONFIG_UGETH_MAGIC_PACKET is not set # CONFIG_UGETH_FILTERING is not set -# CONFIG_UGETH_TX_ON_DEMOND is not set +# CONFIG_UGETH_TX_ON_DEMAND is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -594,6 +577,7 @@ CONFIG_UCC_GETH=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -610,6 +594,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -651,10 +636,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -673,7 +654,6 @@ CONFIG_HW_RANDOM=y # 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -684,11 +664,9 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -713,9 +691,9 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -723,7 +701,6 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -751,13 +728,10 @@ CONFIG_I2C_MPC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -784,6 +758,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -811,16 +786,19 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -851,10 +829,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -897,14 +871,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -993,6 +959,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1018,6 +985,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -1038,11 +1006,13 @@ CONFIG_UCC=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -1059,7 +1029,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -1092,6 +1061,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig index 17120c472304..faedcf8d64a7 100644 --- a/arch/powerpc/configs/mpc8540_ads_defconfig +++ b/arch/powerpc/configs/mpc8540_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:25:24 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:58 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y # CONFIG_PPC_83xx is not set CONFIG_PPC_85xx=y # CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_85xx=y CONFIG_E500=y @@ -46,6 +46,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -85,14 +89,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -119,17 +128,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set CONFIG_MPC8540_ADS=y # CONFIG_MPC8560_ADS is not set # CONFIG_MPC85xx_CDS is not set +# CONFIG_MPC85xx_MDS is not set +# CONFIG_MPC8544_DS is not set CONFIG_MPC8540=y -CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPC85xx=y CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -158,31 +183,31 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -205,13 +230,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -245,20 +270,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -284,7 +297,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -297,16 +319,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -317,6 +336,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -330,18 +350,13 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -350,35 +365,13 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -388,10 +381,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -412,29 +401,16 @@ CONFIG_PHYLIB=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y +CONFIG_NETDEV_10000=y # -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -458,6 +434,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -474,6 +451,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -497,6 +475,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support @@ -504,6 +483,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -512,16 +492,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM 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 # CONFIG_RAW_DRIVER is not set @@ -529,10 +504,6 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -545,35 +516,41 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -584,6 +561,7 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -600,10 +578,6 @@ CONFIG_HID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -645,10 +619,6 @@ CONFIG_HID=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -734,6 +704,7 @@ CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -759,6 +730,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -769,6 +741,7 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -776,10 +749,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -796,15 +772,15 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -813,7 +789,10 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set diff --git a/arch/powerpc/configs/mpc8544_ds_defconfig b/arch/powerpc/configs/mpc8544_ds_defconfig index b563513cc96c..c40a25a79cbb 100644 --- a/arch/powerpc/configs/mpc8544_ds_defconfig +++ b/arch/powerpc/configs/mpc8544_ds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Mon Mar 19 17:18:49 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:58 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -46,6 +46,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set # CONFIG_SPE is not set +# CONFIG_PPC_MM_SLICES is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -73,6 +74,7 @@ CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -90,14 +92,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -129,19 +136,32 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8540_ADS is not set # CONFIG_MPC8560_ADS is not set # CONFIG_MPC85xx_CDS is not set # CONFIG_MPC85xx_MDS is not set CONFIG_MPC8544_DS=y CONFIG_MPC85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -176,27 +196,25 @@ CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="root=/dev/sda3 rw console=ttyS0,115200" # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # CONFIG_ZONE_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -219,7 +237,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -270,25 +287,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set # CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -314,9 +319,18 @@ CONFIG_SCTP_HMAC_MD5=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set +# CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set + # # Device Drivers # @@ -334,10 +348,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -368,10 +378,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Misc devices # - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -400,6 +407,7 @@ CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -415,10 +423,6 @@ CONFIG_SCSI_LOGGING=y # # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_PATA_PLATFORM is not set @@ -427,25 +431,7 @@ CONFIG_ATA=y # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -455,10 +441,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -479,29 +461,16 @@ CONFIG_VITESSE_PHY=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y +CONFIG_NETDEV_10000=y # -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -525,6 +494,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -541,6 +511,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -571,6 +542,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support @@ -587,16 +559,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y CONFIG_GEN_RTC=y CONFIG_GEN_RTC_X=y -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set @@ -604,10 +571,6 @@ CONFIG_GEN_RTC_X=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -620,12 +583,7 @@ CONFIG_GEN_RTC_X=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # # Multifunction device drivers @@ -636,13 +594,9 @@ CONFIG_GEN_RTC_X=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -CONFIG_DVB=y CONFIG_DVB_CORE=m # CONFIG_DVB_CORE_ATTACH is not set +CONFIG_DVB_CAPTURE_DRIVERS=y # # Supported DVB Frontends @@ -676,11 +630,18 @@ CONFIG_DVB_CORE=m # # Miscellaneous devices # +CONFIG_DAB=y # # Graphics support # # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -716,10 +677,6 @@ CONFIG_HID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -759,16 +716,28 @@ CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set # -# RTC drivers +# I2C RTC drivers +# + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_V3020 is not set +# +# on-CPU RTC drivers +# + # # DMA Engine support # @@ -782,14 +751,6 @@ CONFIG_RTC_INTF_DEV=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -890,6 +851,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -919,6 +881,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -968,6 +931,7 @@ CONFIG_NLS_UTF8=m # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -975,12 +939,14 @@ CONFIG_NLS_UTF8=m CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -998,7 +964,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1020,6 +985,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set @@ -1054,6 +1020,7 @@ CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/arch/powerpc/configs/mpc8560_ads_defconfig b/arch/powerpc/configs/mpc8560_ads_defconfig index ecaa267a853c..a30bc6f6211c 100644 --- a/arch/powerpc/configs/mpc8560_ads_defconfig +++ b/arch/powerpc/configs/mpc8560_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:25:53 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:58 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -20,7 +20,7 @@ CONFIG_GENERIC_NVRAM=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set +CONFIG_PPC_UDBG_16550=y # CONFIG_GENERIC_TBSYNC is not set CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y @@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y # CONFIG_PPC_83xx is not set CONFIG_PPC_85xx=y # CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_85xx=y CONFIG_E500=y @@ -46,6 +46,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -85,14 +89,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -119,18 +128,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CPM2=y -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8540_ADS is not set CONFIG_MPC8560_ADS=y # CONFIG_MPC85xx_CDS is not set +# CONFIG_MPC85xx_MDS is not set +# CONFIG_MPC8544_DS is not set CONFIG_MPC8560=y -CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPC85xx=y CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +CONFIG_CPM2=y # # Kernel options @@ -148,7 +172,6 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y # CONFIG_MATH_EMULATION is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -# CONFIG_PC_KEYBOARD is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -160,32 +183,33 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 # CONFIG_PROC_DEVICETREE is not set # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set CONFIG_PCI_DEBUG=y # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -210,13 +234,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -250,20 +274,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -289,7 +301,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -302,16 +323,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -322,6 +340,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -340,19 +359,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -361,10 +377,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -380,18 +392,14 @@ CONFIG_BLK_DEV_INITRD=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -401,15 +409,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -444,10 +444,7 @@ CONFIG_MII=y CONFIG_FS_ENET=y # CONFIG_FS_ENET_HAS_SCC is not set CONFIG_FS_ENET_HAS_FCC=y - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y @@ -461,34 +458,28 @@ CONFIG_E1000_NAPI=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -514,6 +505,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -530,6 +522,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -573,16 +566,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -593,10 +581,7 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -609,35 +594,41 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -648,6 +639,7 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -665,10 +657,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -711,10 +699,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -800,6 +784,7 @@ CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -825,6 +810,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -835,6 +821,7 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -842,10 +829,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -862,15 +852,15 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -879,7 +869,10 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_KGDB_CONSOLE is not set # CONFIG_BDI_SWITCH is not set diff --git a/arch/powerpc/configs/mpc8568mds_defconfig b/arch/powerpc/configs/mpc8568mds_defconfig index 7b3800674cbf..6451d4dd28a0 100644 --- a/arch/powerpc/configs/mpc8568mds_defconfig +++ b/arch/powerpc/configs/mpc8568mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Sat Feb 17 16:26:53 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:59 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -46,6 +46,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -70,8 +71,10 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -84,14 +87,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -123,18 +131,32 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8540_ADS is not set # CONFIG_MPC8560_ADS is not set # CONFIG_MPC85xx_CDS is not set CONFIG_MPC85xx_MDS=y +# CONFIG_MPC8544_DS is not set CONFIG_MPC85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -168,28 +190,26 @@ CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set CONFIG_SECCOMP=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # CONFIG_ZONE_DMA=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -212,7 +232,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -253,20 +272,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -292,7 +299,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -312,10 +328,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -326,6 +338,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -339,17 +352,13 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -378,6 +387,7 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -393,35 +403,13 @@ CONFIG_SCSI_PROC_FS=y # # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -431,10 +419,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -455,29 +439,16 @@ CONFIG_MARVELL_PHY=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y +CONFIG_NETDEV_10000=y # -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -501,6 +472,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -517,6 +489,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -540,6 +513,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support @@ -556,10 +530,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -572,7 +542,6 @@ CONFIG_HW_RANDOM=y # 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 # CONFIG_RAW_DRIVER is not set @@ -580,11 +549,8 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y # @@ -600,8 +566,8 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -629,16 +595,14 @@ CONFIG_I2C_MPC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set @@ -661,6 +625,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SMSC47M1 is not set @@ -676,23 +641,30 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -720,10 +692,6 @@ CONFIG_HID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -765,14 +733,6 @@ CONFIG_HID=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -861,6 +821,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -886,6 +847,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -896,6 +858,7 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -903,11 +866,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -926,9 +891,9 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -943,8 +908,10 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set CONFIG_DEBUGGER=y # CONFIG_XMON is not set # CONFIG_BDI_SWITCH is not set @@ -958,6 +925,7 @@ CONFIG_PPC_EARLY_DEBUG=y # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set # CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set # CONFIG_PPC_EARLY_DEBUG_BEAT is not set +# CONFIG_PPC_EARLY_DEBUG_44x is not set # # Security options @@ -987,6 +955,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/arch/powerpc/configs/mpc85xx_cds_defconfig b/arch/powerpc/configs/mpc85xx_cds_defconfig index 1f61bce33e32..d9afe7009d99 100644 --- a/arch/powerpc/configs/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/mpc85xx_cds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:26:46 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:56:59 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y # CONFIG_PPC_83xx is not set CONFIG_PPC_85xx=y # CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_85xx=y CONFIG_E500=y @@ -46,6 +46,7 @@ CONFIG_BOOKE=y CONFIG_FSL_BOOKE=y # CONFIG_PHYS_64BIT is not set CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -63,14 +64,17 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -85,14 +89,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -119,17 +128,33 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set # CONFIG_MPC8540_ADS is not set # CONFIG_MPC8560_ADS is not set CONFIG_MPC85xx_CDS=y +# CONFIG_MPC85xx_MDS is not set +# CONFIG_MPC8544_DS is not set CONFIG_MPC8540=y -CONFIG_PPC_INDIRECT_PCI_BE=y +CONFIG_MPC85xx=y CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -158,32 +183,33 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +CONFIG_WANT_DEVICE_TREE=y +CONFIG_DEVICE_TREE="" CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -208,13 +234,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -248,20 +274,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -287,7 +301,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -300,16 +323,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -320,6 +340,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -338,19 +359,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set CONFIG_IDE=y CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y @@ -365,6 +383,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y # # IDE chipset support/bugfixes @@ -372,12 +391,13 @@ CONFIG_BLK_DEV_IDE=y CONFIG_IDE_GENERIC=y CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDEPCI_PCIBUS_ORDER=y # CONFIG_BLK_DEV_OFFBOARD is not set CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_BLK_DEV_AMD74XX is not set @@ -391,6 +411,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -401,10 +422,10 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_BLK_DEV_TC86C001 is not set # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set # @@ -413,10 +434,6 @@ CONFIG_BLK_DEV_IDEDMA=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -432,18 +449,14 @@ CONFIG_BLK_DEV_IDEDMA=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -453,15 +466,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -493,10 +498,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y @@ -510,34 +512,28 @@ CONFIG_E1000_NAPI=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_GIANFAR=y CONFIG_GFAR_NAPI=y # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -563,6 +559,7 @@ CONFIG_GFAR_NAPI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -579,6 +576,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -603,6 +601,7 @@ CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support @@ -611,6 +610,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -619,16 +619,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM 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 # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -639,10 +634,7 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -655,35 +647,41 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -694,6 +692,7 @@ CONFIG_FIRMWARE_EDID=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -711,10 +710,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -757,10 +752,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -846,6 +837,7 @@ CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -871,6 +863,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -881,6 +874,7 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -888,10 +882,13 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -908,15 +905,15 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -925,7 +922,10 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set diff --git a/arch/powerpc/configs/mpc8641_hpcn_defconfig b/arch/powerpc/configs/mpc8641_hpcn_defconfig index 53fcd6932f5b..1ac94a605b05 100644 --- a/arch/powerpc/configs/mpc8641_hpcn_defconfig +++ b/arch/powerpc/configs/mpc8641_hpcn_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:27:14 2007 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:57:00 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -24,7 +24,7 @@ CONFIG_PPC_UDBG_16550=y CONFIG_GENERIC_TBSYNC=y CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_DEFAULT_UIMAGE=y # # Processor support @@ -34,9 +34,9 @@ CONFIG_GENERIC_BUG=y # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set CONFIG_PPC_86xx=y +# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set -# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_6xx=y CONFIG_PPC_FPU=y @@ -45,6 +45,7 @@ CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -70,9 +71,11 @@ CONFIG_LOCALVERSION="" # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -87,14 +90,19 @@ CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -121,15 +129,28 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_PPC_INDIRECT_PCI_BE=y -CONFIG_MPIC=y # -# Platform Support +# Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set CONFIG_MPC8641_HPCN=y CONFIG_MPC8641=y +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +CONFIG_PPC_I8259=y +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -159,33 +180,34 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y -# CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_INDIRECT_PCI_BE=y CONFIG_FSL_SOC=y +CONFIG_FSL_PCIE=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -210,13 +232,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -234,7 +256,7 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set +CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y @@ -247,6 +269,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -262,20 +285,8 @@ CONFIG_IPV6_SIT=y # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -301,7 +312,16 @@ CONFIG_IPV6_SIT=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -314,16 +334,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -334,6 +351,7 @@ CONFIG_FW_LOADER=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -352,19 +370,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -373,10 +388,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -392,18 +403,14 @@ CONFIG_BLK_DEV_INITRD=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # # I2O device support # # CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -413,15 +420,7 @@ CONFIG_DUMMY=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -453,10 +452,7 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -468,34 +464,28 @@ CONFIG_MII=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_GIANFAR=y # CONFIG_GFAR_NAPI is not set # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_MLX4_CORE is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -521,6 +511,7 @@ CONFIG_GIANFAR=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -537,6 +528,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -581,6 +573,7 @@ CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set @@ -588,15 +581,10 @@ CONFIG_UNIX98_PTYS=y # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_AGP is not set @@ -607,11 +595,9 @@ CONFIG_UNIX98_PTYS=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_CHARDEV is not set # @@ -638,13 +624,13 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -672,27 +658,30 @@ CONFIG_SENSORS_EEPROM=y # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -702,7 +691,6 @@ CONFIG_FIRMWARE_EDID=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -713,6 +701,7 @@ CONFIG_DUMMY_CONSOLE=y # HID Devices # CONFIG_HID=y +# CONFIG_HID_DEBUG is not set # # USB support @@ -730,10 +719,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -776,10 +761,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Virtualization -# - # # File systems # @@ -869,6 +850,7 @@ CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -899,6 +881,7 @@ CONFIG_LDM_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -948,6 +931,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Distributed Lock Manager # # CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set # # Library routines @@ -955,10 +939,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -975,15 +962,15 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -993,7 +980,10 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set # CONFIG_BOOTX_TEXT is not set diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig index 539d9e3d3668..e6b18ea8f643 100644 --- a/arch/powerpc/configs/mpc866_ads_defconfig +++ b/arch/powerpc/configs/mpc866_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc6 -# Fri Nov 24 21:13:55 2006 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:57:00 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -10,6 +10,7 @@ CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -28,7 +29,6 @@ CONFIG_AUDIT_ARCH=y # Processor support # # CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set @@ -40,6 +40,7 @@ CONFIG_PPC_8xx=y CONFIG_8xx=y # CONFIG_PPC_DCR_NATIVE is not set # CONFIG_PPC_DCR_MMIO is not set +# CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -58,14 +59,17 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -78,14 +82,19 @@ CONFIG_PRINTK=y CONFIG_ELF_CORE=y # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y # CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set # # Loadable module support @@ -112,13 +121,14 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y -# CONFIG_MPIC is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set CONFIG_CPM1=y # CONFIG_MPC8XXFADS is not set CONFIG_MPC86XADS=y @@ -137,6 +147,18 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_USB_SOF_UCODE_PATCH is not set # CONFIG_I2C_SPI_UCODE_PATCH is not set # CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set +# CONFIG_PQ2ADS is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -144,6 +166,7 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_HIGHMEM is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y @@ -164,30 +187,28 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 # CONFIG_PROC_DEVICETREE is not set # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set # CONFIG_PCI_QSPAN is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -212,13 +233,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -246,25 +267,14 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -290,7 +300,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -307,10 +326,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -321,6 +336,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -331,18 +347,13 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -351,34 +362,13 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -388,10 +378,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -404,6 +390,7 @@ CONFIG_PHYLIB=y # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set CONFIG_FIXED_PHY=y CONFIG_FIXED_MII_10_FDX=y CONFIG_FIXED_MII_100_FDX=y @@ -417,27 +404,14 @@ CONFIG_MII=y CONFIG_FS_ENET=y CONFIG_FS_ENET_HAS_SCC=y CONFIG_FS_ENET_HAS_FEC=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -461,6 +435,7 @@ CONFIG_FS_ENET_HAS_FEC=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -486,9 +461,16 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -516,6 +498,7 @@ CONFIG_SERIO_LIBPS2=y # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_CPM=y @@ -533,31 +516,18 @@ CONFIG_UNIX98_PTYS=y # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # 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_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -570,39 +540,53 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set +# CONFIG_FB_IBM_GXT4500 is not set + # # Sound # # CONFIG_SOUND is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # @@ -618,10 +602,6 @@ CONFIG_FIRMWARE_EDID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -752,6 +732,7 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -781,21 +762,33 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support # # CONFIG_NLS is not set +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set + # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -809,11 +802,9 @@ CONFIG_PLIST=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig index e2c17d8da4fc..fc4f9b766aa7 100644 --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Fri Nov 10 21:30:40 2006 +# Linux kernel version: 2.6.22-rc7 +# Sun Jul 1 23:57:01 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -10,6 +10,7 @@ CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -28,7 +29,6 @@ CONFIG_AUDIT_ARCH=y # Processor support # # CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set # CONFIG_PPC_85xx is not set @@ -38,6 +38,9 @@ CONFIG_PPC_8xx=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_8xx=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +# CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -56,14 +59,17 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -76,14 +82,19 @@ CONFIG_PRINTK=y CONFIG_ELF_CORE=y # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y # CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set # # Loadable module support @@ -110,18 +121,26 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_EMBEDDEDBOOT=y -# CONFIG_MPIC is not set # # Platform support # +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set CONFIG_CPM1=y # CONFIG_MPC8XXFADS is not set # CONFIG_MPC86XADS is not set CONFIG_MPC885ADS=y +# +# Freescale Ethernet driver platform-specific options +# +CONFIG_MPC8xx_SECOND_ETH=y +CONFIG_MPC8xx_SECOND_ETH_FEC2=y +# CONFIG_MPC8xx_SECOND_ETH_SCC3 is not set + # # MPC8xx CPM Options # @@ -135,6 +154,18 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_USB_SOF_UCODE_PATCH is not set # CONFIG_I2C_SPI_UCODE_PATCH is not set # CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set +# CONFIG_PQ2ADS is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set # # Kernel options @@ -142,6 +173,7 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_HIGHMEM is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y @@ -162,30 +194,28 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 # CONFIG_PROC_DEVICETREE is not set # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set # CONFIG_SECCOMP is not set +# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_ZONE_DMA=y CONFIG_FSL_SOC=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set # CONFIG_PCI_QSPAN is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # # PCCARD (PCMCIA/CardBus) support # -# -# PCI Hotplug Support -# - # # Advanced setup # @@ -210,13 +240,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -244,25 +274,14 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -288,7 +307,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -305,10 +333,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -319,6 +343,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -329,18 +354,13 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -349,34 +369,13 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # # Multi-device support (RAID and LVM) # # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set +# CONFIG_MACINTOSH_DRIVERS is not set # # Network device support @@ -386,10 +385,6 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -402,6 +397,7 @@ CONFIG_DAVICOM_PHY=y # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set CONFIG_FIXED_PHY=y CONFIG_FIXED_MII_10_FDX=y # CONFIG_FIXED_MII_100_FDX is not set @@ -415,27 +411,14 @@ CONFIG_MII=y CONFIG_FS_ENET=y CONFIG_FS_ENET_HAS_SCC=y CONFIG_FS_ENET_HAS_FEC=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -459,6 +442,7 @@ CONFIG_FS_ENET_HAS_FEC=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -484,9 +468,16 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -514,6 +505,7 @@ CONFIG_SERIO_LIBPS2=y # # Non-8250 serial port support # +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_CPM=y @@ -531,31 +523,18 @@ CONFIG_UNIX98_PTYS=y # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # 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_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -568,39 +547,53 @@ CONFIG_GEN_RTC=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set +# CONFIG_FB_IBM_GXT4500 is not set + # # Sound # # CONFIG_SOUND is not set +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + # # USB support # @@ -616,10 +609,6 @@ CONFIG_FIRMWARE_EDID=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -750,6 +739,7 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -779,21 +769,33 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support # # CONFIG_NLS is not set +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set +# CONFIG_UCC_SLOW is not set + # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y # # Instrumentation Support @@ -807,11 +809,9 @@ CONFIG_PLIST=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set # CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set From 756813cac1d0172e1f93d977fe8bd1cd5086be21 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Tue, 26 Jun 2007 14:31:23 +0100 Subject: [PATCH 014/551] [ARM] 4454/1: Use word accesses in Versatile PCI config reads ARM Versatile PCI config reads of one byte width have the lowest two bits of the address cleared and result in reading from a wrong place in the config space. This change is to use word size accesses like it is done for halfword reads. Byte reads are used for retrieving the IRQ number of a PCI device and the problem was not exposed until 2.6.20 because the value read was discarded in drivers/pci/setup-irq.c (recently fixed). Signed-off-by: Andrzej Zaborowski Acked-by: Paul Brook Signed-off-by: Russell King --- arch/arm/mach-versatile/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index ba58223f12be..ca8290159432 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -117,7 +117,10 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh } else { switch (size) { case 1: - v = __raw_readb(addr); + v = __raw_readl(addr); + if (where & 2) v >>= 16; + if (where & 1) v >>= 8; + v &= 0xff; break; case 2: From 1f750a782c0e9593a8d0981ea972f22334980955 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 2 Jul 2007 10:19:07 +0100 Subject: [PATCH 015/551] [ARM] 4458/1: pxa: Fix CKEN usage and hence fix pxa suspend/resume The PXA CKEN changes broken syspend/resume on the pxa27x. This patch corrects the problem and fixes another couple of bad references. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/mach-pxa/pxa27x.c | 4 ++-- sound/arm/pxa2xx-ac97.c | 2 +- sound/soc/pxa/pxa2xx-ac97.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index c64bab49efc4..1939acc3f9f7 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_resume(void); if (state == PM_SUSPEND_STANDBY) - CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0; + CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | (1 << CKEN_LCD) | (1 << CKEN_PWM0); else - CKEN = CKEN_MEMC | CKEN_OSTIMER; + CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 19c65a8d86a7..7bc2767e1584 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -361,7 +361,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card); - if (CKEN & CKEN_AC97) { + if (CKEN & (1 << CKEN_AC97)) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); pxa_set_cken(CKEN_AC97, 0); diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index b222755763e7..129d851b3151 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -300,7 +300,7 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) return 0; err: - if (CKEN & CKEN_AC97) { + if (CKEN & (1 << CKEN_AC97)) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); pxa_set_cken(CKEN_AC97, 0); From 7b9c7b4d07fd8981193a2c4ecb650566f42d1219 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 4 Jul 2007 21:16:33 +0100 Subject: [PATCH 016/551] [ARM] Fix non-page aligned boot time mappings AT91SAM9260 stopped booting with the recent changes to MM initialisation - it was asking for a non-aligned virtual address which caused loops to be non-terminal. Fix this by rounding virtual addresses down, but remember to include the offset in the length, and round the length up to the following page. This means that asking for a mapping of 4K starting at 2K into a page maps two pages as one would expect. Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 02e050ae59f6..3b5e47dc0c97 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -527,9 +527,9 @@ void __init create_mapping(struct map_desc *md) return; } - addr = md->virtual; + addr = md->virtual & PAGE_MASK; phys = (unsigned long)__pfn_to_phys(md->pfn); - length = PAGE_ALIGN(md->length); + length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " From 2bcb1b7de9eeea969a25d5f2b4511195cca9f2a2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 4 Jul 2007 15:24:39 -0700 Subject: [PATCH 017/551] Remove the blink driver Yeah, we could have just disabled it, but there's work on a new one that isn't as fundamentally broken, so there really doesn't seem to be any point in keeping it around. The recent timer cleanup broke the only valid use, and when I say "valid", I obviously mean "totally broken". So it's not like it works, or really even can work in the current format that uses the unsafe "panic" LED blinking routines.. Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 8 -------- drivers/misc/Makefile | 1 - drivers/misc/blink.c | 45 ------------------------------------------- 3 files changed, 54 deletions(-) delete mode 100644 drivers/misc/blink.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2f2fbffafbe0..616eee9c04f1 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -187,13 +187,5 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. -config BLINK - tristate "Keyboard blink driver" - help - Driver that when loaded will blink the keyboard LEDs continuously. - This is useful for debugging and for kernels that cannot necessarily - output something to the screen like kexec kernels to give the user - a visual indication that the kernel is doing something. - endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5b6d46de005c..8abbf2f07a65 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o -obj-$(CONFIG_BLINK) += blink.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c deleted file mode 100644 index 97f7253ce2d3..000000000000 --- a/drivers/misc/blink.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include - -static void do_blink(unsigned long data); - -static DEFINE_TIMER(blink_timer, do_blink, 0 ,0); - -static void do_blink(unsigned long data) -{ - static long count; - if (panic_blink) - panic_blink(count++); - blink_timer.expires = jiffies + msecs_to_jiffies(1); - add_timer(&blink_timer); -} - -static int blink_panic_event(struct notifier_block *blk, - unsigned long event, void *arg) -{ - do_blink(0); - return 0; -} - -static struct notifier_block blink_notify = { - .notifier_call = blink_panic_event, -}; - -static __init int blink_init(void) -{ - printk(KERN_INFO "Enabling keyboard blinking\n"); - atomic_notifier_chain_register(&panic_notifier_list, &blink_notify); - return 0; -} - -static __exit void blink_remove(void) -{ - del_timer_sync(&blink_timer); - atomic_notifier_chain_unregister(&panic_notifier_list, &blink_notify); -} - -module_init(blink_init); -module_exit(blink_remove); - From 082f47a79bfc8a526b9a3e14a0ae9504fc09cc12 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 5 Jul 2007 19:59:51 +0100 Subject: [PATCH 018/551] [ARM] always allow dump_stack() to produce a backtrace Don't make this dependent on CONFIG_DEBUG_KERNEL - if we hit a WARN_ON we need the stack trace to work out how we got to that point. Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 1b68d365d0e1..237f4999b9a1 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -181,9 +181,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) void dump_stack(void) { -#ifdef CONFIG_DEBUG_ERRORS __backtrace(); -#endif } EXPORT_SYMBOL(dump_stack); From 87a927c715789853cc8331d76039a2fd657a832a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 4 Jul 2007 21:26:44 -0400 Subject: [PATCH 019/551] Fix slab redzone alignment Commit b46b8f19c9cd435ecac4d9d12b39d78c137ecd66 fixed a couple of bugs by switching the redzone to 64 bits. Unfortunately, it neglected to ensure that the _second_ redzone, after the slab object, is aligned correctly. This caused illegal instruction faults on sparc32, which for some reason not entirely clear to me are not trapped and fixed up. Two things need to be done to fix this: - increase the object size, rounding up to alignof(long long) so that the second redzone can be aligned correctly. - If SLAB_STORE_USER is set but alignof(long long)==8, allow a full 64 bits of space for the user word at the end of the buffer, even though we may not _use_ the whole 64 bits. This patch should be a no-op on any 64-bit architecture or any 32-bit architecture where alignof(long long) == 4. Of the others, it's tested on ppc32 by myself and a very similar patch was tested on sparc32 by Mark Fortescue, who reported the new problem. Also, fix the conditions for FORCED_DEBUG, which hadn't been adjusted to the new sizes. Again noticed by Mark. Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- mm/slab.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index a9c4472e9204..b344e6707128 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -137,6 +137,7 @@ /* Shouldn't this be in a header file somewhere? */ #define BYTES_PER_WORD sizeof(void *) +#define REDZONE_ALIGN max(BYTES_PER_WORD, __alignof__(unsigned long long)) #ifndef cache_line_size #define cache_line_size() L1_CACHE_BYTES @@ -547,7 +548,7 @@ static unsigned long long *dbg_redzone2(struct kmem_cache *cachep, void *objp) if (cachep->flags & SLAB_STORE_USER) return (unsigned long long *)(objp + cachep->buffer_size - sizeof(unsigned long long) - - BYTES_PER_WORD); + REDZONE_ALIGN); return (unsigned long long *) (objp + cachep->buffer_size - sizeof(unsigned long long)); } @@ -2178,7 +2179,8 @@ kmem_cache_create (const char *name, size_t size, size_t align, * above the next power of two: caches with object sizes just above a * power of two have a significant amount of internal fragmentation. */ - if (size < 4096 || fls(size - 1) == fls(size-1 + 3 * BYTES_PER_WORD)) + if (size < 4096 || fls(size - 1) == fls(size-1 + REDZONE_ALIGN + + 2 * sizeof(unsigned long long))) flags |= SLAB_RED_ZONE | SLAB_STORE_USER; if (!(flags & SLAB_DESTROY_BY_RCU)) flags |= SLAB_POISON; @@ -2219,12 +2221,20 @@ kmem_cache_create (const char *name, size_t size, size_t align, } /* - * Redzoning and user store require word alignment. Note this will be - * overridden by architecture or caller mandated alignment if either - * is greater than BYTES_PER_WORD. + * Redzoning and user store require word alignment or possibly larger. + * Note this will be overridden by architecture or caller mandated + * alignment if either is greater than BYTES_PER_WORD. */ - if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER) - ralign = __alignof__(unsigned long long); + if (flags & SLAB_STORE_USER) + ralign = BYTES_PER_WORD; + + if (flags & SLAB_RED_ZONE) { + ralign = REDZONE_ALIGN; + /* If redzoning, ensure that the second redzone is suitably + * aligned, by adjusting the object size accordingly. */ + size += REDZONE_ALIGN - 1; + size &= ~(REDZONE_ALIGN - 1); + } /* 2) arch mandated alignment */ if (ralign < ARCH_SLAB_MINALIGN) { @@ -2261,9 +2271,13 @@ kmem_cache_create (const char *name, size_t size, size_t align, } if (flags & SLAB_STORE_USER) { /* user store requires one word storage behind the end of - * the real object. + * the real object. But if the second red zone needs to be + * aligned to 64 bits, we must allow that much space. */ - size += BYTES_PER_WORD; + if (flags & SLAB_RED_ZONE) + size += REDZONE_ALIGN; + else + size += BYTES_PER_WORD; } #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) if (size >= malloc_sizes[INDEX_L3 + 1].cs_size From 3663c306609a9322a484fba28b3da66142c50ee9 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 3 Jul 2007 12:43:12 -0400 Subject: [PATCH 020/551] SCTP: Fix thinko in sctp_copy_laddrs() Correctly dereference bytes_copied in sctp_copy_laddrs(). I totally must have spaced when doing this. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 67861a8f00cb..1e788279bb22 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4170,7 +4170,7 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, to += addrlen; cnt ++; space_left -= addrlen; - bytes_copied += addrlen; + *bytes_copied += addrlen; } return cnt; From f50f95cab735ebe2993e8d1549f0615bad05f3f2 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 3 Jul 2007 12:47:40 -0400 Subject: [PATCH 021/551] SCTP: Check to make sure file is valid before setting timeout In-kernel sockets created with sock_create_kern don't usually have a file and file descriptor allocated to them. As a result, when SCTP tries to check the non-blocking flag, we Oops when dereferencing a NULL file pointer. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/socket.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 1e788279bb22..b1917f68723c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -980,6 +980,7 @@ static int __sctp_connect(struct sock* sk, union sctp_addr *sa_addr; void *addr_buf; unsigned short port; + unsigned int f_flags = 0; sp = sctp_sk(sk); ep = sp->ep; @@ -1106,7 +1107,14 @@ static int __sctp_connect(struct sock* sk, af->to_sk_daddr(&to, sk); sk->sk_err = 0; - timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); + /* in-kernel sockets don't generally have a file allocated to them + * if all they do is call sock_create_kern(). + */ + if (sk->sk_socket->file) + f_flags = sk->sk_socket->file->f_flags; + + timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); + err = sctp_wait_for_connect(asoc, &timeo); /* Don't free association on exit. */ From 1669d857a25d62c6d0a6d9216e01c21287a7c844 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 3 Jul 2007 14:29:23 -0400 Subject: [PATCH 022/551] SCTP: Add scope_id validation for link-local binds SCTP currently permits users to bind to link-local addresses, but doesn't verify that the scope id specified at bind matches the interface that the address is configured on. It was report that this can hang a system. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/ipv6.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 84cd53635fe8..2c29394fd92e 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -844,6 +844,10 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) dev = dev_get_by_index(addr->v6.sin6_scope_id); if (!dev) return 0; + if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { + dev_put(dev); + return 0; + } dev_put(dev); } af = opt->pf->af; From 2cd052e44329dd2b42eb958f8f346b053de6e2cd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 5 Jul 2007 17:03:09 -0700 Subject: [PATCH 023/551] [NET] skbuff: remove export of static symbol skb_clone_fraglist is static so it shouldn't be exported. Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- net/core/skbuff.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 27cfe5fe4bb9..3943c3ad9145 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2211,7 +2211,6 @@ EXPORT_SYMBOL(pskb_copy); EXPORT_SYMBOL(pskb_expand_head); EXPORT_SYMBOL(skb_checksum); EXPORT_SYMBOL(skb_clone); -EXPORT_SYMBOL(skb_clone_fraglist); EXPORT_SYMBOL(skb_copy); EXPORT_SYMBOL(skb_copy_and_csum_bits); EXPORT_SYMBOL(skb_copy_and_csum_dev); From 25845b5155b55cd77e42655ec24161ba3feffa47 Mon Sep 17 00:00:00 2001 From: Jing Min Zhao Date: Thu, 5 Jul 2007 17:05:01 -0700 Subject: [PATCH 024/551] [NETFILTER]: nf_conntrack_h323: add checking of out-of-range on choices' index values Choices' index values may be out of range while still encoded in the fixed length bit-field. This bug may cause access to undefined types (NULL pointers) and thus crashes (Reported by Zhongling Wen). This patch also adds checking of decode flag when decoding SEQUENCEs. Signed-off-by: Jing Min Zhao Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_h323_asn1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c index f6fad713d484..6b7eaa019d4c 100644 --- a/net/netfilter/nf_conntrack_h323_asn1.c +++ b/net/netfilter/nf_conntrack_h323_asn1.c @@ -518,7 +518,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) CHECK_BOUND(bs, 2); len = get_len(bs); CHECK_BOUND(bs, len); - if (!base) { + if (!base || !(son->attr & DECODE)) { PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name); bs->cur += len; @@ -704,6 +704,8 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) } else { ext = 0; type = get_bits(bs, f->sz); + if (type >= f->lb) + return H323_ERROR_RANGE; } /* Write Type */ From 94b83419e5b56a87410fd9c9939f0081fc155d65 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 5 Jul 2007 17:06:21 -0700 Subject: [PATCH 025/551] [NET]: net/core/netevent.c should #include Every file should include the headers containing the prototypes for its global functions. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- net/core/netevent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/netevent.c b/net/core/netevent.c index 35d02c38554e..95f81de87502 100644 --- a/net/core/netevent.c +++ b/net/core/netevent.c @@ -15,6 +15,7 @@ #include #include +#include static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain); From 25442cafb8cc3d979418caccabc91260707a0947 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Thu, 5 Jul 2007 17:42:44 -0700 Subject: [PATCH 026/551] [NETPOLL]: Fixups for 'fix soft lockup when removing module' >From my recent patch: > > #1 > > Until kernel ver. 2.6.21 (including) cancel_rearming_delayed_work() > > required a work function should always (unconditionally) rearm with > > delay > 0 - otherwise it would endlessly loop. This patch replaces > > this function with cancel_delayed_work(). Later kernel versions don't > > require this, so here it's only for uniformity. But Oleg Nesterov found: > But 2.6.22 doesn't need this change, why it was merged? > > In fact, I suspect this change adds a race, ... His description was right (thanks), so this patch reverts #1. Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/core/netpoll.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index cf40ff91ac01..a0efdd7a6b37 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -72,8 +72,7 @@ static void queue_process(struct work_struct *work) netif_tx_unlock(dev); local_irq_restore(flags); - if (atomic_read(&npinfo->refcnt)) - schedule_delayed_work(&npinfo->tx_work, HZ/10); + schedule_delayed_work(&npinfo->tx_work, HZ/10); return; } netif_tx_unlock(dev); @@ -786,8 +785,7 @@ void netpoll_cleanup(struct netpoll *np) if (atomic_dec_and_test(&npinfo->refcnt)) { skb_queue_purge(&npinfo->arp_tx); skb_queue_purge(&npinfo->txq); - cancel_delayed_work(&npinfo->tx_work); - flush_scheduled_work(); + cancel_rearming_delayed_work(&npinfo->tx_work); /* clean after last, unfinished work */ if (!skb_queue_empty(&npinfo->txq)) { From 5a1970959053143f6674f6d98c259452763a2f22 Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Fri, 23 Mar 2007 12:15:18 -0700 Subject: [PATCH 027/551] [MIPS] 64-bit TO_PHYS_MASK macro for RM9000 processors Signed-off-by: Andrew Sharp Signed-off-by: Ralf Baechle --- include/asm-mips/addrspace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h index c6275088cf65..964c5eddc21b 100644 --- a/include/asm-mips/addrspace.h +++ b/include/asm-mips/addrspace.h @@ -133,6 +133,7 @@ || defined (CONFIG_CPU_R4X00) \ || defined (CONFIG_CPU_R5000) \ || defined (CONFIG_CPU_RM7000) \ + || defined (CONFIG_CPU_RM9000) \ || defined (CONFIG_CPU_NEVADA) \ || defined (CONFIG_CPU_TX49XX) \ || defined (CONFIG_CPU_MIPS64) From 6fb88ce04f545ca7da15a7b447783bb7a4615511 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 7 Jun 2007 08:44:32 +0100 Subject: [PATCH 028/551] [MIPS] AP/SP: Avoid triggering the 34K E125 performance issue C0_status doesn't need to be initialized at this point anyway; the register will be initialized later. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vpe.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index c9ee9d2d5856..9e66354dee8b 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -1436,10 +1436,6 @@ static int __init vpe_module_init(void) write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); if (i != 0) { - write_vpe_c0_status((read_c0_status() & - ~(ST0_IM | ST0_IE | ST0_KSU)) - | ST0_CU0); - /* * Set config to be the same as vpe0, * particularly kseg0 coherency alg From c3e838a2cbb0f14af4d718160933523ac4c37adf Mon Sep 17 00:00:00 2001 From: Chris Dearman Date: Thu, 21 Jun 2007 12:59:57 +0100 Subject: [PATCH 029/551] [MIPS] Fix timer/performance interrupt detection Signed-off-by: Chris Dearman Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b1233644fcca..3ea7863c4519 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1372,12 +1372,12 @@ void __init per_cpu_trap_init(void) */ if (cpu_has_mips_r2) { cp0_compare_irq = (read_c0_intctl () >> 29) & 7; - cp0_perfcount_irq = -1; + cp0_perfcount_irq = (read_c0_intctl () >> 26) & 7; + if (cp0_perfcount_irq == cp0_compare_irq) + cp0_perfcount_irq = -1; } else { cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; - cp0_perfcount_irq = (read_c0_intctl () >> 26) & 7; - if (cp0_perfcount_irq != cp0_compare_irq) - cp0_perfcount_irq = -1; + cp0_perfcount_irq = -1; } #ifdef CONFIG_MIPS_MT_SMTC From f7c2778151f32581ea9ec567d01d5d85209fcfe6 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 26 Jun 2007 20:19:00 +0200 Subject: [PATCH 030/551] [MIPS] Change libgcc-style functions from lib-y to obj-y Reported by Eugene Surovegin . If only modules were users of these functions they did not get linked into the kernel proper, so later module loads would fail as well. Signed-off-by: Ralf Baechle --- arch/mips/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 5dad13efba7e..1c1aa9f92f6c 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -9,4 +9,4 @@ obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o # libgcc-style stuff needed in the kernel -lib-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o +obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o From 9349075a15a876f8e82f433ec84f99d19d3e77f9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 5 Jul 2007 17:39:48 +0100 Subject: [PATCH 031/551] [MIPS] SMTC: Fix cut'n'paste bug in Kconfig.debug This effectivly turned the SMTC_IDLE_HOOK_DEBUG debug option into a no-op. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 72d5c198e790..3efe117721aa 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -37,7 +37,7 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. -config CONFIG_SMTC_IDLE_HOOK_DEBUG +config SMTC_IDLE_HOOK_DEBUG bool "Enable additional debug checks before going into CPU idle loop" depends on DEBUG_KERNEL && MIPS_MT_SMTC help From 075c733e19ce7530b53b78151cc4d303c8f64548 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 5 Jul 2007 08:14:21 +0100 Subject: [PATCH 032/551] [MIPS] RM7000: Enable ICACHE_REFILLS_WORKAROUND_WAR. The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra opposes it being called that) where invalid instructions in the same I-cache line worth of instructions being fetched may case spurious exceptions. The workaround for this was only enabled for E9000 cores; enable it also for all RM7000-based platforms. Signed-off-by: Ralf Baechle --- include/asm-mips/war.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index 13a3502eef44..ec0eeebd8802 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -177,18 +177,22 @@ #endif /* - * The RM9000 has a bug (though PMC-Sierra opposes it being called that) - * where invalid instructions in the same I-cache line worth of instructions - * being fetched may case spurious exceptions. + * The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra + * opposes it being called that) where invalid instructions in the same + * I-cache line worth of instructions being fetched may case spurious + * exceptions. */ -#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_MOMENCO_OCELOT_3) || \ - defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_BASLER_EXCITE) +#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MOMENCO_JAGUAR_ATX) || \ + defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) || \ + defined(CONFIG_MOMENCO_OCELOT) || defined(CONFIG_MOMENCO_OCELOT_3) || \ + defined(CONFIG_MOMENCO_OCELOT_C) || defined(CONFIG_PMC_YOSEMITE) || \ + defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC) #define ICACHE_REFILLS_WORKAROUND_WAR 1 #endif /* - * ON the R10000 upto version 2.6 (not sure about 2.7) there is a bug that + * On the R10000 upto version 2.6 (not sure about 2.7) there is a bug that * may cause ll / sc and lld / scd sequences to execute non-atomically. */ #ifdef CONFIG_SGI_IP27 From fde97822a295da9dffa4af643b49a58ffc4516ad Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 6 Jul 2007 14:40:05 +0100 Subject: [PATCH 033/551] [MIPS] Add macros to encode processor revisions. Older processors used to encode processor version and revision in two 4-bit bitfields, the 4K seems to simply count up and even newer MTI cores have switched to use the 8-bits as 3:3:2 bitfield with the last field as the patch number. Signed-off-by: Ralf Baechle --- include/asm-mips/cpu.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index d38fdbf845b2..2924069075e0 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -124,6 +124,17 @@ #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ #define PRID_REV_VR4130 0x0080 +/* + * Older processors used to encode processor version and revision in two + * 4-bit bitfields, the 4K seems to simply count up and even newer MTI cores + * have switched to use the 8-bits as 3:3:2 bitfield with the last field as + * the patch number. *ARGH* + */ +#define PRID_REV_ENCODE_44(ver, rev) \ + ((ver) << 4 | (rev)) +#define PRID_REV_ENCODE_332(ver, rev, patch) \ + ((ver) << 5 | (rev) << 2 | (patch)) + /* * FPU implementation/revision register (CP1 control register 0). * From 4b3e975e4a06f1710693c5aa51b8f98facfa9863 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 21 Jun 2007 00:22:34 +0100 Subject: [PATCH 034/551] [MIPS] Fix scheduling latency issue on 24K, 34K and 74K cores The idle loop goes to sleep using the WAIT instruction if !need_resched(). This has is suffering from from a race condition that if if just after need_resched has returned 0 an interrupt might set TIF_NEED_RESCHED but we've just completed the test so go to sleep anyway. This would be trivial to fix by just disabling interrupts during that sequence as in: local_irq_disable(); if (!need_resched()) __asm__("wait"); local_irq_enable(); but the processor architecture leaves it undefined if a processor calling WAIT with interrupts disabled will ever restart its pipeline and indeed some processors have made use of the freedom provided by the architecture definition. This has been resolved and the Config7.WII bit indicates that the use of WAIT is safe on 24K, 24KE and 34K cores. It also is safe on 74K starting revision 2.1.0 so enable the use of WAIT with interrupts disabled for 74K based on a c0_prid of at least that. Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 19 +++++++++++++++---- include/asm-mips/mipsregs.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 0fc90ba16ae1..b12eeee0e974 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -137,13 +137,24 @@ static inline void check_wait(void) case CPU_4KEC: case CPU_4KSC: case CPU_5KC: - case CPU_24K: case CPU_25KF: - case CPU_34K: - case CPU_74K: - case CPU_PR4450: + case CPU_PR4450: cpu_wait = r4k_wait; break; + + case CPU_24K: + case CPU_34K: + cpu_wait = r4k_wait; + if (read_c0_config7() & MIPS_CONF7_WII) + cpu_wait = r4k_wait_irqoff; + break; + + case CPU_74K: + cpu_wait = r4k_wait; + if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) + cpu_wait = r4k_wait_irqoff; + break; + case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; break; diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 9985cb7c16e7..89c81922d47c 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -534,6 +534,8 @@ #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) #define MIPS_CONF3_DSP (_ULCAST_(1) << 10) +#define MIPS_CONF7_WII (_ULCAST_(1) << 31) + /* * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. */ From ef7320edb1dd2cf6c969d1dcef4a9499a42f24da Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 6 Jul 2007 02:39:49 -0700 Subject: [PATCH 035/551] Fix elf_core_dump() when writing arch specific notes (spu coredumps) elf_core_dump() supports dumping arch specific ELF notes, via the #define ELF_CORE_WRITE_EXTRA_NOTES. Currently the only user of this is the powerpc spu coredump code. There is a bug in the handling of foffset WRT the arch notes, which causes us to erroneously increment foffset by the size of the arch notes, leaving a block of zeroes in the file, and causing all subsequent data in the file to be at + . eg: LOAD 0x050000 0x00100000 0x00000000 0x20000 0x20000 R E 0x10000 Tells us we should have a chunk of data at 0x50000. The truth is the data is at 0x90dbc = 0x50000 + 0x40dbc (the size of the arch notes). This bug prevents gdb from reading the core file correctly. The simplest fix is to simply remember the size of the arch notes, and add it to foffset after we've written the arch notes. The only drawback is that if the arch code doesn't write as many bytes as it said it would, we end up with a broken core dump again. For now I think that's a reasonable requirement. Tested on a Cell blade, gdb no longer complains about the core file being bogus. While I'm here I should point out that the spu coredump code does not work if we're dumping to a pipe - we'll have to wait for 23 to fix that. Signed-off-by: Michael Ellerman Acked-by: Arnd Bergmann Acked-by: Benjamin Herrenschmidt Acked-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index fa8ea33ab0be..08e4414b8374 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1499,6 +1499,9 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) #endif int thread_status_size = 0; elf_addr_t *auxv; +#ifdef ELF_CORE_WRITE_EXTRA_NOTES + int extra_notes_size; +#endif /* * We no longer stop all VM operations. @@ -1628,7 +1631,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) sz += thread_status_size; #ifdef ELF_CORE_WRITE_EXTRA_NOTES - sz += ELF_CORE_EXTRA_NOTES_SIZE; + extra_notes_size = ELF_CORE_EXTRA_NOTES_SIZE; + sz += extra_notes_size; #endif fill_elf_note_phdr(&phdr, sz, offset); @@ -1674,6 +1678,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) #ifdef ELF_CORE_WRITE_EXTRA_NOTES ELF_CORE_WRITE_EXTRA_NOTES; + foffset += extra_notes_size; #endif /* write out the thread status notes section */ From 1e2e99f0e4aa6363e8515ed17011c210c8f1b52a Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Fri, 6 Jul 2007 02:39:50 -0700 Subject: [PATCH 036/551] i386: fix regression, endless loop in ptrace singlestep over an int80 The commit 635cf99a80f4ebee59d70eb64bb85ce829e4591f introduced a regression. Executing a ptrace single step after certain int80 accesses will infinitely loop and never advance the PC. The TIF_SINGLESTEP check should be done on the return from the syscall and not before it. I loops on each single step on the pop right after the int80 which writes out to the console. At that point you can issue as many single steps as you want and it will not advance any further. The test case is below: /* Test whether singlestep through an int80 syscall works. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include static int child, status; static struct user_regs_struct regs; static void do_child() { char str[80] = "child: int80 test\n"; ptrace(PTRACE_TRACEME, 0, 0, 0); kill(getpid(), SIGUSR1); write(fileno(stdout),str,strlen(str)); asm ("int $0x80" : : "a" (20)); /* getpid */ } static void do_parent() { unsigned long eip, expected = 0; again: waitpid(child, &status, 0); if (WIFEXITED(status) || WIFSIGNALED(status)) return; if (WIFSTOPPED(status)) { ptrace(PTRACE_GETREGS, child, 0, ®s); eip = regs.eip; if (expected) fprintf(stderr, "child stop @ %08lx, expected %08lx %s\n", eip, expected, eip == expected ? "" : " <== ERROR"); if (*(unsigned short *)eip == 0x80cd) { fprintf(stderr, "int 0x80 at %08x\n", (unsigned int)eip); expected = eip + 2; } else expected = 0; ptrace(PTRACE_SINGLESTEP, child, NULL, NULL); } goto again; } int main(int argc, char * const argv[]) { child = fork(); if (child) do_parent(); else do_child(); return 0; } Signed-off-by: Jason Wessel Cc: Jeremy Fitzhardinge Cc: Cc: Chuck Ebbert <76306.1226@compuserve.com> Acked-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/entry.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index b1f16ee65e4d..3c3c220488c9 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -367,10 +367,6 @@ ENTRY(system_call) CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) - testl $TF_MASK,PT_EFLAGS(%esp) - jz no_singlestep - orl $_TIF_SINGLESTEP,TI_flags(%ebp) -no_singlestep: # system call tracing in operation / emulation /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) @@ -385,6 +381,10 @@ syscall_exit: # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF + testl $TF_MASK,PT_EFLAGS(%esp) # If tracing set singlestep flag on exit + jz no_singlestep + orl $_TIF_SINGLESTEP,TI_flags(%ebp) +no_singlestep: movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx # current->work jne syscall_exit_work From d25c1ba2fa1a9a1a4f68bef8edb0efefd79f0012 Mon Sep 17 00:00:00 2001 From: Loic Prylli Date: Fri, 6 Jul 2007 02:39:52 -0700 Subject: [PATCH 037/551] MTRR: Fix race causing set_mtrr to go into infinite loop Processors synchronization in set_mtrr requires the .gate field to be set after .count field is properly initialized. Without an explicit barrier, the compiler was reordering those memory stores. That was sometimes causing a processor (in ipi_handler) to see the .gate change and decrement .count before the latter is set by set_mtrr() (which then hangs in a infinite loop with irqs disabled). Signed-off-by: Loic Prylli Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mtrr/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 55b005152a11..75dc6d5214bc 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -229,6 +229,8 @@ static void set_mtrr(unsigned int reg, unsigned long base, data.smp_size = size; data.smp_type = type; atomic_set(&data.count, num_booting_cpus() - 1); + /* make sure data.count is visible before unleashing other CPUs */ + smp_wmb(); atomic_set(&data.gate,0); /* Start the ball rolling on other CPUs */ @@ -242,6 +244,7 @@ static void set_mtrr(unsigned int reg, unsigned long base, /* ok, reset count and toggle gate */ atomic_set(&data.count, num_booting_cpus() - 1); + smp_wmb(); atomic_set(&data.gate,1); /* do our MTRR business */ @@ -260,6 +263,7 @@ static void set_mtrr(unsigned int reg, unsigned long base, cpu_relax(); atomic_set(&data.count, num_booting_cpus() - 1); + smp_wmb(); atomic_set(&data.gate,0); /* From 0db19c412ce260a293b06b4bab66550b84411bfc Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 6 Jul 2007 02:39:52 -0700 Subject: [PATCH 038/551] x86_64: fix headers_install A bug in headers_install for ARCH=x86_64 yields an asm/ directory full of files all of which are using the same #ifdef guard, "__ASM_STUB_" with no postfix. So the second and later asm files #included in the same C file (often through standard headers like ioctl.h) yields no symbols. Strangeness with the Ubuntu 'tell me if I support something that's not explcitly mentioned in POSIX, and I'll strip it out' shell, I believe. We don't need the 'export' but we do need a semicolon at the end of the FNAME line: Signed-off-by: David Woodhouse Signed-off-by: Rob Landley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/Makefile.headersinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 8cd63014a0d1..f98d772aac80 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -108,7 +108,7 @@ quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) quiet_cmd_gen = GEN $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) cmd_gen = \ -FNAME=$(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$@) \ +FNAME=$(patsubst $(INSTALL_HDR_PATH)/$(_dst)/%,%,$@); \ STUBDEF=__ASM_STUB_`echo $$FNAME | tr a-z.- A-Z__`; \ (echo "/* File autogenerated by 'make headers_install' */" ; \ echo "\#ifndef $$STUBDEF" ; \ From d57d973101e87b2e30ccfa899fe36c4b2e32d217 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 6 Jul 2007 02:39:53 -0700 Subject: [PATCH 039/551] fix logic error in ipc compat semctl() When calling a semctl(IPC_STAT) without IPC_64 the check if the memory is unevaluated. This patch fixes this. Signed-off-by: Alexander Graf Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/compat.c b/ipc/compat.c index 8b44aa9a7c95..ab76fb0ef844 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -225,7 +225,7 @@ static inline int put_compat_semid_ds(struct semid64_ds *s, int err; if (!access_ok (VERIFY_WRITE, up, sizeof(*up))) - err = -EFAULT; + return -EFAULT; err = __put_compat_ipc_perm(&s->sem_perm, &up->sem_perm); err |= __put_user(s->sem_otime, &up->sem_otime); err |= __put_user(s->sem_ctime, &up->sem_ctime); From 41a5311465b9de6d18e78b733a2c6e1b33e89be8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 6 Jul 2007 02:39:54 -0700 Subject: [PATCH 040/551] PNP SMCf010 quirk: work around Toshiba Portege 4000 ACPI issues When we enable the SMCf010 IR device, the Toshiba Portege 4000 BIOS claims the device is working, but it really isn't configured correctly. The BIOS *will* configure it, but only if we call _SRS after (1) reversing the order of the SIR and FIR I/O port regions and (2) changing the IRQ from active-high to active-low. This patch addresses the 2.6.22 regression: "no irda0 interface (2.6.21 was OK), smsc does not find chip" I tested this on a Portege 4000. The smsc-ircc2 driver correctly detects the device, and "irattach irda0 -s && irdadump" shows transmitted and received packets. Signed-off-by: Bjorn Helgaas Cc: Andrey Borzenkov Cc: Samuel Ortiz Cc: "Linus Walleij (LD/EAB)" Cc: Michal Piotrowski Cc: Adam Belay Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/quirks.c | 63 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 967a8e22b2da..7c3236690cc3 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -136,11 +136,10 @@ static int quirk_smc_fir_enabled(struct pnp_dev *dev) static void quirk_smc_enable(struct pnp_dev *dev) { - /* - * If the BIOS left the device disabled, or it is enabled and - * responding correctly, we're in good shape. - */ - if (!dev->active || quirk_smc_fir_enabled(dev)) + struct resource fir, sir, irq; + + pnp_activate_dev(dev); + if (quirk_smc_fir_enabled(dev)) return; /* @@ -152,16 +151,62 @@ static void quirk_smc_enable(struct pnp_dev *dev) * this. Fortunately, they do fix things up if we auto-configure * the device using its _PRS and _SRS methods. */ - dev_err(&dev->dev, "%s device not responding, auto-configuring " - "resources\n", dev->id->id); + dev_err(&dev->dev, "%s not responding at SIR 0x%lx, FIR 0x%lx; " + "auto-configuring\n", dev->id->id, + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); pnp_disable_dev(dev); pnp_init_resource_table(&dev->res); pnp_auto_config_dev(dev); pnp_activate_dev(dev); + if (quirk_smc_fir_enabled(dev)) { + dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + return; + } - if (!quirk_smc_fir_enabled(dev)) - dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n"); + /* + * The Toshiba Portege 4000 _CRS reports the FIR region first, + * followed by the SIR region. The BIOS will configure the bridge, + * but only if we call _SRS with SIR first, then FIR. It also + * reports the IRQ as active high, when it is really active low. + */ + dev_err(&dev->dev, "not responding at SIR 0x%lx, FIR 0x%lx; " + "swapping SIR/FIR and reconfiguring\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + + /* + * Clear IORESOURCE_AUTO so pnp_activate_dev() doesn't reassign + * these resources any more. + */ + fir = dev->res.port_resource[0]; + sir = dev->res.port_resource[1]; + fir.flags &= ~IORESOURCE_AUTO; + sir.flags &= ~IORESOURCE_AUTO; + + irq = dev->res.irq_resource[0]; + irq.flags &= ~IORESOURCE_AUTO; + irq.flags &= ~IORESOURCE_BITS; + irq.flags |= IORESOURCE_IRQ_LOWEDGE; + + pnp_disable_dev(dev); + dev->res.port_resource[0] = sir; + dev->res.port_resource[1] = fir; + dev->res.irq_resource[0] = irq; + pnp_activate_dev(dev); + + if (quirk_smc_fir_enabled(dev)) { + dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + return; + } + + dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\" and " + "email bjorn.helgaas@hp.com\n"); } From 071922c08cef62e194d83db1cc4fa75892c69651 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Fri, 6 Jul 2007 02:39:55 -0700 Subject: [PATCH 041/551] i386: es7000 build breakage fix o Commit 1833d6bc72893265f22addd79cf52e6987496e0f broke the build if compiled with CONFIG_ES7000=y and CONFIG_X86_GENERICARCH=n arch/i386/kernel/built-in.o(.init.text+0x4fa9): In function `acpi_parse_madt': : undefined reference to `acpi_madt_oem_check' arch/i386/kernel/built-in.o(.init.text+0x7406): In function `smp_read_mpc': : undefined reference to `mps_oem_check' arch/i386/kernel/built-in.o(.init.text+0x8990): In function `connect_bsp_APIC': : undefined reference to `enable_apic_mode' make: *** [.tmp_vmlinux1] Error 1 o Fix the build issue. Provided the definitions of missing functions. o Don't have ES7000 machine. Only compile tested. Cc: Len Brown Cc: Natalie Protasevich Cc: Roland Dreier Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mach-es7000/es7000plat.c | 48 +++++++++++++++++++++ include/asm-i386/mach-es7000/mach_apic.h | 4 ++ include/asm-i386/mach-es7000/mach_mpparse.h | 6 +++ 3 files changed, 58 insertions(+) diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c index 9be6ceabf042..ab99072d3f9a 100644 --- a/arch/i386/mach-es7000/es7000plat.c +++ b/arch/i386/mach-es7000/es7000plat.c @@ -40,6 +40,7 @@ #include #include #include "es7000.h" +#include /* * ES7000 Globals @@ -174,6 +175,53 @@ find_unisys_acpi_oem_table(unsigned long *oem_addr) } #endif +/* + * This file also gets compiled if CONFIG_X86_GENERICARCH is set. Generic + * arch already has got following function definitions (asm-generic/es7000.c) + * hence no need to define these for that case. + */ +#ifndef CONFIG_X86_GENERICARCH +void es7000_sw_apic(void); +void __init enable_apic_mode(void) +{ + es7000_sw_apic(); + return; +} + +__init int mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (mpc->mpc_oemptr) { + struct mp_config_oemtable *oem_table = + (struct mp_config_oemtable *)mpc->mpc_oemptr; + if (!strncmp(oem, "UNISYS", 6)) + return parse_unisys_oem((char *)oem_table); + } + return 0; +} +#ifdef CONFIG_ACPI +/* Hook from generic ACPI tables.c */ +int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + unsigned long oem_addr; + if (!find_unisys_acpi_oem_table(&oem_addr)) { + if (es7000_check_dsdt()) + return parse_unisys_oem((char *)oem_addr); + else { + setup_unisys(); + return 1; + } + } + return 0; +} +#else +int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + return 0; +} +#endif +#endif /* COFIG_X86_GENERICARCH */ + static void es7000_spin(int n) { diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index 2d978928a395..caec64be516d 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h @@ -73,6 +73,10 @@ static inline void init_apic_ldr(void) apic_write_around(APIC_LDR, val); } +#ifndef CONFIG_X86_GENERICARCH +extern void enable_apic_mode(void); +#endif + extern int apic_version [MAX_APICS]; static inline void setup_apic_routing(void) { diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h index b9fb784e1fd5..8aa10547b4b1 100644 --- a/include/asm-i386/mach-es7000/mach_mpparse.h +++ b/include/asm-i386/mach-es7000/mach_mpparse.h @@ -18,6 +18,12 @@ extern int parse_unisys_oem (char *oemptr); extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); extern void setup_unisys(void); +#ifndef CONFIG_X86_GENERICARCH +extern int acpi_madt_oem_check(char *oem_id, char *oem_table_id); +extern int mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid); +#endif + #ifdef CONFIG_ACPI static inline int es7000_check_dsdt(void) From 0da2f0f164f098bb4447c714b552ac1681b2d6e8 Mon Sep 17 00:00:00 2001 From: Yoann Padioleau Date: Fri, 6 Jul 2007 02:39:56 -0700 Subject: [PATCH 042/551] potential compiler error, irqfunc caller sites update In 7d12e780e003f93433d49ce78cfedf4b4c52adc5 David Howells performed this evolution: "IRQ: Maintain regs pointer globally rather than passing to IRQ handlers" He correctly updated many of the function definitions that were using this extra regs pointer parameter but forgot to update some caller sites of those functions. The reason the modifications was not properly done on all drivers is that some drivers were rarely compiled because they are for AMIGA, or that some code sites were inside #ifdefs where the option is not set or inside #if 0. Here is the semantic patch that found the occurences and fixed the problem. @ rule1 @ identifier fn; identifier irq, dev_id; typedef irqreturn_t; @@ static irqreturn_t fn(int irq, void *dev_id) { ... } @@ identifier rule1.fn; expression E1, E2, E3; @@ fn(E1, E2 - ,E3 ) Signed-off-by: Yoann Padioleau Cc: "David S. Miller" Cc: Jeff Garzik Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/atm/firestream.c | 2 +- drivers/net/arm/am79c961a.c | 2 +- drivers/net/ixp2000/ixpdev.c | 2 +- drivers/net/sb1250-mac.c | 2 +- drivers/usb/misc/uss720.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 7f6d02ce1b5f..38b688f9f6a9 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -1654,7 +1654,7 @@ static void fs_poll (unsigned long data) { struct fs_dev *dev = (struct fs_dev *) data; - fs_irq (0, dev, NULL); + fs_irq (0, dev); dev->timer.expires = jiffies + FS_POLL_FREQ; add_timer (&dev->timer); } diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 8f0d7ce503c9..2143eeb7a2b0 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -634,7 +634,7 @@ static void am79c961_poll_controller(struct net_device *dev) { unsigned long flags; local_irq_save(flags); - am79c961_interrupt(dev->irq, dev, NULL); + am79c961_interrupt(dev->irq, dev); local_irq_restore(flags); } #endif diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 6683afc02aaa..d5f694fc4a21 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -222,7 +222,7 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id) static void ixpdev_poll_controller(struct net_device *dev) { disable_irq(IRQ_IXP2000_THDA0); - ixpdev_interrupt(IRQ_IXP2000_THDA0, dev, NULL); + ixpdev_interrupt(IRQ_IXP2000_THDA0, dev); enable_irq(IRQ_IXP2000_THDA0); } #endif diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 132e2148b21c..e7fdcf15b5a7 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -1159,7 +1159,7 @@ static void sbmac_netpoll(struct net_device *netdev) __raw_writeq(0, sc->sbm_imr); - sbmac_intr(irq, netdev, NULL); + sbmac_intr(irq, netdev); #ifdef CONFIG_SBMAC_COALESCE __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 70250252ae2a..1a60f9c473ad 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -336,7 +336,7 @@ static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id) memcpy(priv->reg, buffer, 4); /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ if (priv->reg[2] & priv->reg[1] & 0x10) - parport_generic_irq(0, pp, NULL); + parport_generic_irq(0, pp); return 1; } #endif From 23c1fb52961bc24bd3a8078eefc49eed533b2b38 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 6 Jul 2007 13:35:34 +0200 Subject: [PATCH 043/551] mm: fixup /proc/vmstat output Line up the vmstat_text with zone_stat_item enum zone_stat_item { /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, NR_INACTIVE, NR_ACTIVE, We current have nr_active and nr_inactive reversed. [ "OK with patch, though using initializers canbe handy to prevent such things in future: static const char * const vmstat_text[] = { [NR_FREE_PAGES] = "nr_free_pages", ..." - Alexey ] Signed-off-by: Peter Zijlstra Acked-by: Alexey Dobriyan Signed-off-by: Linus Torvalds --- mm/vmstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmstat.c b/mm/vmstat.c index 38254297a494..eceaf496210f 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -477,8 +477,8 @@ const struct seq_operations fragmentation_op = { static const char * const vmstat_text[] = { /* Zoned VM counters */ "nr_free_pages", - "nr_active", "nr_inactive", + "nr_active", "nr_anon_pages", "nr_mapped", "nr_file_pages", From 95069f89e80bb49ecc1b135bf85747e8dc6681f9 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Fri, 6 Jul 2007 11:17:30 -0700 Subject: [PATCH 044/551] GEODE: reboot fixup for geode machines with CS5536 boards Writing to MSR 0x51400017 forces a hard reset on CS5536-based machines, this has the reboot fixup do just that if such a board is detected. Acked-by: Jordan Crouse Signed-off-by: Andres Salomon Cc: Alan Cox Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 4 ++-- arch/i386/kernel/reboot_fixups.c | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d2f6a247414d..b1b2b30b1b8e 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -441,8 +441,8 @@ config X86_REBOOTFIXUPS this config is intended, is when reboot ends with a stalled/hung system. - Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1. - combination. + Currently, the only fixup is for the Geode machines using + CS5530A and CS5536 chipsets. Say Y if you want to enable the fixup. Currently, it's safe to enable this option even if you don't need it. diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c index 2d78d918340f..03e1cce58f49 100644 --- a/arch/i386/kernel/reboot_fixups.c +++ b/arch/i386/kernel/reboot_fixups.c @@ -5,12 +5,14 @@ * * List of supported fixups: * geode-gx1/cs5530a - Jaya Kumar + * geode-gx/lx/cs5536 - Andres Salomon * */ #include #include #include +#include static void cs5530a_warm_reset(struct pci_dev *dev) { @@ -21,6 +23,16 @@ static void cs5530a_warm_reset(struct pci_dev *dev) return; } +static void cs5536_warm_reset(struct pci_dev *dev) +{ + /* + * 6.6.2.12 Soft Reset (DIVIL_SOFT_RESET) + * writing 1 to the LSB of this MSR causes a hard reset. + */ + wrmsrl(0x51400017, 1ULL); + udelay(50); /* shouldn't get here but be safe and spin a while */ +} + struct device_fixup { unsigned int vendor; unsigned int device; @@ -29,6 +41,7 @@ struct device_fixup { static struct device_fixup fixups_table[] = { { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset }, +{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset }, }; /* From c3000e031cf6a1f58228357d7c317f66e670627f Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Fri, 6 Jul 2007 11:17:32 -0700 Subject: [PATCH 045/551] MAINTAINERS new kernel janitors ml davem kindly moved the list from osdl to vger. Signed-of-by: maximilian attems Cc: Alexey Dobriyan Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 23a04f431283..df40a4ec87fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2101,7 +2101,7 @@ S: Maintained KERNEL JANITORS P: Several -L: kernel-janitors@lists.linux-foundation.org +L: kernel-janitors@vger.kernel.org W: http://www.kerneljanitors.org/ S: Maintained From d23cf676d0e9d1fdc066d2dcb7f8bc0e2d4c75bd Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 6 Jul 2007 11:17:32 -0700 Subject: [PATCH 046/551] slub: remove useless EXPORT_SYMBOL kmem_cache_open is static. EXPORT_SYMBOL was leftover from some earlier time period where kmem_cache_open was usable outside of slub. (Fixes powerpc build error) Signed-off-by: Chrsitoph Lameter Cc: Johannes Berg Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slub.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index 0437f2f09986..e0cf6213abc0 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2020,7 +2020,6 @@ error: s->offset, flags); return 0; } -EXPORT_SYMBOL(kmem_cache_open); /* * Check if a given pointer is valid From 1c39858b5dd46004b12c5acd26d8df346bef8a10 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 7 Jul 2007 14:58:39 -0400 Subject: [PATCH 047/551] Fix use-after-free oops in Bluetooth HID. When cleaning up HIDP sessions, we currently close the ACL connection before deregistering the input device. Closing the ACL connection schedules a workqueue to remove the associated objects from sysfs, but the input device still refers to them -- and if the workqueue happens to run before the input device removal, the kernel will oops when trying to look up PHYSDEVPATH for the removed input device. Fix this by deregistering the input device before closing the connections. Signed-off-by: David Woodhouse Acked-by: Marcel Holtmann Signed-off-by: Linus Torvalds --- net/bluetooth/hidp/core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index ceadfcf457c1..450eb0244bbf 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -581,15 +581,6 @@ static int hidp_session(void *arg) hidp_del_timer(session); - fput(session->intr_sock->file); - - wait_event_timeout(*(ctrl_sk->sk_sleep), - (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); - - fput(session->ctrl_sock->file); - - __hidp_unlink_session(session); - if (session->input) { input_unregister_device(session->input); session->input = NULL; @@ -601,6 +592,15 @@ static int hidp_session(void *arg) hid_free_device(session->hid); } + fput(session->intr_sock->file); + + wait_event_timeout(*(ctrl_sk->sk_sleep), + (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); + + fput(session->ctrl_sock->file); + + __hidp_unlink_session(session); + up_write(&hidp_session_sem); kfree(session); From 40e48eed84e65f909f5ac3d7a39547b70aacf90f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 7 Jul 2007 00:54:09 +0200 Subject: [PATCH 048/551] include/linux/kallsyms.h must #include This patch fixes the following 2.6.22 regression with CONFIG_KALLSYMS=n: <-- snip --> ... CC arch/m32r/kernel/traps.o In file included from /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/arch/m32r/kernel/traps.c:14: /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h: In function 'lookup_symbol_name': /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h:66: error: 'ERANGE' undeclared (first use in this function) /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h:66: error: (Each undeclared identifier is reported only once /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h:66: error: for each function it appears in.) /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h: In function 'lookup_symbol_attrs': /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/include/linux/kallsyms.h:71: error: 'ERANGE' undeclared (first use in this function) make[2]: *** [arch/m32r/kernel/traps.o] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- include/linux/kallsyms.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 12178d2c882b..5f06527dca21 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -5,6 +5,7 @@ #ifndef _LINUX_KALLSYMS_H #define _LINUX_KALLSYMS_H +#include #define KSYM_NAME_LEN 127 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \ From 38377be88ab878f44c687dbd704d4d044b000c97 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 6 Jul 2007 14:59:43 -0400 Subject: [PATCH 049/551] Clean up E7520/7320/7525 quirk printk. The printk level in this printk is bogus, as the previous printk didn't have a terminating \n resulting in .. Intel E7520/7320/7525 detected.<6>Disabling irq balancing and affinity It also never printed a \n at all in the case where we didn't do the quirk. Change it to only make noise if it actually does something useful. Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- arch/i386/kernel/quirks.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index 9f6ab1789bb0..6722469c2633 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -20,8 +20,6 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) if (rev > 0x9) return; - printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space*/ pci_read_config_byte(dev, 0xf4, &config); pci_write_config_byte(dev, 0xf4, config|0x2); @@ -30,7 +28,8 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); if (!(word & (1 << 13))) { - printk(KERN_INFO "Disabling irq balancing and affinity\n"); + printk(KERN_INFO "Intel E7520/7320/7525 detected. " + "Disabling irq balancing and affinity\n"); #ifdef CONFIG_IRQBALANCE irqbalance_disable(""); #endif From 95511ad4342cd094e62c807f6631b9a19cc6b129 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 7 Jul 2007 06:14:02 +0200 Subject: [PATCH 050/551] DLM must depend on SYSFS The dependency of DLM on SYSFS got lost in commit 6ed7257b46709e87d79ac2b6b819b7e0c9184998 resulting in the following compile error with CONFIG_DLM=y, CONFIG_SYSFS=n: <-- snip --> ... LD .tmp_vmlinux1 fs/built-in.o: In function `dlm_lockspace_init': /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/fs/dlm/lockspace.c:231: undefined reference to `kernel_subsys' fs/built-in.o: In function `configfs_init': /home/bunk/linux/kernel-2.6/linux-2.6.22-rc6-mm1/fs/configfs/mount.c:143: undefined reference to `kernel_subsys' make[1]: *** [.tmp_vmlinux1] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- fs/dlm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig index 69a94690e493..54bcc00ec8df 100644 --- a/fs/dlm/Kconfig +++ b/fs/dlm/Kconfig @@ -3,7 +3,7 @@ menu "Distributed Lock Manager" config DLM tristate "Distributed Lock Manager (DLM)" - depends on IPV6 || IPV6=n + depends on SYSFS && (IPV6 || IPV6=n) select CONFIGFS_FS select IP_SCTP help From 4c6c914e4c2e0f91775ce4051b5a800c55175462 Mon Sep 17 00:00:00 2001 From: Uwe Koziolek Date: Sun, 8 Jul 2007 15:21:58 +0200 Subject: [PATCH 051/551] sis5513: adding PCI-ID The SiS966 has one additional PCI-ID 1180. If the chipset is using this PCI-ID, the primary channel is connected to the first PATA-port. The secondary channel is connected to SATA-ports in IDE emulation mode. The legacy IO-ports are used. The including of the PCI-ID into pata_sis is not sufficient, because the legacy driver in drivers/ide is initialized before pata_sis. Signed-off-by: Uwe Koziolek Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sis5513.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index bb6cc4aedd63..ec0adad9ef61 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -872,6 +872,7 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi static struct pci_device_id sis5513_pci_tbl[] = { { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9a03b47da603..5b1c9994f89a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -661,6 +661,7 @@ #define PCI_DEVICE_ID_SI_965 0x0965 #define PCI_DEVICE_ID_SI_966 0x0966 #define PCI_DEVICE_ID_SI_968 0x0968 +#define PCI_DEVICE_ID_SI_1180 0x1180 #define PCI_DEVICE_ID_SI_5511 0x5511 #define PCI_DEVICE_ID_SI_5513 0x5513 #define PCI_DEVICE_ID_SI_5517 0x5517 From 4660897e6c2daa198fc8e3f47ae2a4aef69c80b0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 8 Jul 2007 15:21:58 +0200 Subject: [PATCH 052/551] qd65xx: fix PIO mode selection PIO4 is a maximum PIO mode supported by a driver. Using "255" as a max_mode argument to ide_get_best_pio_mode() could result in wrong timings being used by a driver (for "pio" equal to 5) or OOPS (for "pio" values > 5 && < 255). Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov Reviewed-by: Alan Cox --- drivers/ide/legacy/qd65xx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index d1414a75b523..7783745dd167 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -258,8 +258,7 @@ static void qd6580_tune_drive (ide_drive_t *drive, u8 pio) int recovery_time = 415; /* worst case values from the dos driver */ if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { - pio = ide_get_best_pio_mode(drive, pio, 255, &d); - pio = min_t(u8, pio, 4); + pio = ide_get_best_pio_mode(drive, pio, 4, &d); switch (pio) { case 0: break; From 4e99325b462ba18075768582621af74a6b79d2a5 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 8 Jul 2007 01:13:06 -0700 Subject: [PATCH 053/551] mm: double mark_page_accessed() in read_cache_page_async() Fix a post-2.6.21 regression. read_cache_page_async() has two invocations of mark_page_accessed() which will launch pages right onto the active list. Remove the first one, keeping the latter one. This avoids marking unwanted pages active (in the retry loop). Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index edb1b0b5cc8d..d1d9814f99dd 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1786,7 +1786,6 @@ retry: page = __read_cache_page(mapping, index, filler, data); if (IS_ERR(page)) return page; - mark_page_accessed(page); if (PageUptodate(page)) goto out; From 1e5de2837c166535f9bb4232bfe97ea1f9fc7a1c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 8 Jul 2007 12:02:55 -0700 Subject: [PATCH 054/551] Fix permission checking for the new utimensat() system call Commit 1c710c896eb461895d3c399e15bb5f20b39c9073 added the utimensat() system call, but didn't handle the case of checking for the writability of the target right, when the target was a file descriptor, not a filename. We cannot use vfs_permission(MAY_WRITE) for that case, and need to simply check whether the file descriptor is writable. The oops from using the wrong function was noticed and narrowed down by Markus Trippelsdorf. Cc: Ulrich Drepper Cc: Markus Trippelsdorf Cc: Andrew Morton Acked-by: Al Viro Signed-off-by: Linus Torvalds --- fs/utimes.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/utimes.c b/fs/utimes.c index 480f7c8c29da..b3c88952465f 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -106,9 +106,16 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (IS_IMMUTABLE(inode)) goto dput_and_out; - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; + if (current->fsuid != inode->i_uid) { + if (f) { + if (!(f->f_mode & FMODE_WRITE)) + goto dput_and_out; + } else { + error = vfs_permission(&nd, MAY_WRITE); + if (error) + goto dput_and_out; + } + } } mutex_lock(&inode->i_mutex); error = notify_change(dentry, &newattrs); From 7dcca30a32aadb0520417521b0c44f42d09fe05c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 8 Jul 2007 16:32:17 -0700 Subject: [PATCH 055/551] Linux 2.6.22 Woo-hoo. I'm sure somebody will report a "this doesn't compile, and I have a new root exploit" five minutes after release, but it still feels good ;) Signed-off-by: Linus Torvalds --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c6f7b71eae81..de4f8f7d396c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 22 -EXTRAVERSION = -rc7 +EXTRAVERSION = NAME = Holy Dancing Manatees, Batman! # *DOCUMENTATION* From 9467d64b0e88763914c01f71ddf591b166c4f526 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 11 May 2007 15:59:40 -0400 Subject: [PATCH 056/551] [PATCH] Add 93cx6 eeprom library This patch adds a library for reading from 93cx6 eeproms. Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- drivers/misc/Kconfig | 6 +- drivers/misc/Makefile | 1 + drivers/misc/eeprom_93cx6.c | 229 +++++++++++++++++++++++++++++++++++ include/linux/eeprom_93cx6.h | 72 +++++++++++ 4 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 drivers/misc/eeprom_93cx6.c create mode 100644 include/linux/eeprom_93cx6.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 616eee9c04f1..bd601efa7bd1 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -34,6 +34,11 @@ config PHANTOM If you choose to build module, its name will be phantom. If unsure, say N here. +config EEPROM_93CX6 + tristate "EEPROM 93CX6 support" + ---help--- + This is a driver for the EEPROM chipsets 93c46 and 93c66. + The driver supports both read as well as write commands. If unsure, say N. @@ -187,5 +192,4 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. - endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 8abbf2f07a65..b5ce0e3dba86 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o +obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c new file mode 100644 index 000000000000..bfcb43424dcd --- /dev/null +++ b/drivers/misc/eeprom_93cx6.c @@ -0,0 +1,229 @@ +/* + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + Module: eeprom_93cx6 + Abstract: EEPROM reader routines for 93cx6 chipsets. + Supported chipsets: 93c46 & 93c66. + */ + +#include +#include +#include +#include +#include + +MODULE_AUTHOR("http://rt2x00.serialmonkey.com"); +MODULE_VERSION("1.0"); +MODULE_DESCRIPTION("EEPROM 93cx6 chip driver"); +MODULE_LICENSE("GPL"); + +static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom) +{ + eeprom->reg_data_clock = 1; + eeprom->register_write(eeprom); + udelay(1); +} + +static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) +{ + eeprom->reg_data_clock = 0; + eeprom->register_write(eeprom); + udelay(1); +} + +static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom) +{ + /* + * Clear all flags, and enable chip select. + */ + eeprom->register_read(eeprom); + eeprom->reg_data_in = 0; + eeprom->reg_data_out = 0; + eeprom->reg_data_clock = 0; + eeprom->reg_chip_select = 1; + eeprom->register_write(eeprom); + + /* + * kick a pulse. + */ + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); +} + +static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom) +{ + /* + * Clear chip_select and data_in flags. + */ + eeprom->register_read(eeprom); + eeprom->reg_data_in = 0; + eeprom->reg_chip_select = 0; + eeprom->register_write(eeprom); + + /* + * kick a pulse. + */ + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); +} + +static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom, + const u16 data, const u16 count) +{ + unsigned int i; + + eeprom->register_read(eeprom); + + /* + * Clear data flags. + */ + eeprom->reg_data_in = 0; + eeprom->reg_data_out = 0; + + /* + * Start writing all bits. + */ + for (i = count; i > 0; i--) { + /* + * Check if this bit needs to be set. + */ + eeprom->reg_data_in = !!(data & (1 << (i - 1))); + + /* + * Write the bit to the eeprom register. + */ + eeprom->register_write(eeprom); + + /* + * Kick a pulse. + */ + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); + } + + eeprom->reg_data_in = 0; + eeprom->register_write(eeprom); +} + +static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom, + u16 *data, const u16 count) +{ + unsigned int i; + u16 buf = 0; + + eeprom->register_read(eeprom); + + /* + * Clear data flags. + */ + eeprom->reg_data_in = 0; + eeprom->reg_data_out = 0; + + /* + * Start reading all bits. + */ + for (i = count; i > 0; i--) { + eeprom_93cx6_pulse_high(eeprom); + + eeprom->register_read(eeprom); + + /* + * Clear data_in flag. + */ + eeprom->reg_data_in = 0; + + /* + * Read if the bit has been set. + */ + if (eeprom->reg_data_out) + buf |= (1 << (i - 1)); + + eeprom_93cx6_pulse_low(eeprom); + } + + *data = buf; +} + +/** + * eeprom_93cx6_read - Read multiple words from eeprom + * @eeprom: Pointer to eeprom structure + * @word: Word index from where we should start reading + * @data: target pointer where the information will have to be stored + * + * This function will read the eeprom data as host-endian word + * into the given data pointer. + */ +void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word, + u16 *data) +{ + u16 command; + + /* + * Initialize the eeprom register + */ + eeprom_93cx6_startup(eeprom); + + /* + * Select the read opcode and the word to be read. + */ + command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word; + eeprom_93cx6_write_bits(eeprom, command, + PCI_EEPROM_WIDTH_OPCODE + eeprom->width); + + /* + * Read the requested 16 bits. + */ + eeprom_93cx6_read_bits(eeprom, data, 16); + + /* + * Cleanup eeprom register. + */ + eeprom_93cx6_cleanup(eeprom); +} +EXPORT_SYMBOL_GPL(eeprom_93cx6_read); + +/** + * eeprom_93cx6_multiread - Read multiple words from eeprom + * @eeprom: Pointer to eeprom structure + * @word: Word index from where we should start reading + * @data: target pointer where the information will have to be stored + * @words: Number of words that should be read. + * + * This function will read all requested words from the eeprom, + * this is done by calling eeprom_93cx6_read() multiple times. + * But with the additional change that while the eeprom_93cx6_read + * will return host ordered bytes, this method will return little + * endian words. + */ +void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word, + __le16 *data, const u16 words) +{ + unsigned int i; + u16 tmp; + + for (i = 0; i < words; i++) { + tmp = 0; + eeprom_93cx6_read(eeprom, word + i, &tmp); + data[i] = cpu_to_le16(tmp); + } +} +EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); + diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h new file mode 100644 index 000000000000..d774b7778c91 --- /dev/null +++ b/include/linux/eeprom_93cx6.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + Module: eeprom_93cx6 + Abstract: EEPROM reader datastructures for 93cx6 chipsets. + Supported chipsets: 93c46 & 93c66. + */ + +/* + * EEPROM operation defines. + */ +#define PCI_EEPROM_WIDTH_93C46 6 +#define PCI_EEPROM_WIDTH_93C66 8 +#define PCI_EEPROM_WIDTH_OPCODE 3 +#define PCI_EEPROM_WRITE_OPCODE 0x05 +#define PCI_EEPROM_READ_OPCODE 0x06 +#define PCI_EEPROM_EWDS_OPCODE 0x10 +#define PCI_EEPROM_EWEN_OPCODE 0x13 + +/** + * struct eeprom_93cx6 - control structure for setting the commands + * for reading the eeprom data. + * @data: private pointer for the driver. + * @register_read(struct eeprom_93cx6 *eeprom): handler to + * read the eeprom register, this function should set all reg_* fields. + * @register_write(struct eeprom_93cx6 *eeprom): handler to + * write to the eeprom register by using all reg_* fields. + * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines + * @reg_data_in: register field to indicate data input + * @reg_data_out: register field to indicate data output + * @reg_data_clock: register field to set the data clock + * @reg_chip_select: register field to set the chip select + * + * This structure is used for the communication between the driver + * and the eeprom_93cx6 handlers for reading the eeprom. + */ +struct eeprom_93cx6 { + void *data; + + void (*register_read)(struct eeprom_93cx6 *eeprom); + void (*register_write)(struct eeprom_93cx6 *eeprom); + + int width; + + char reg_data_in; + char reg_data_out; + char reg_data_clock; + char reg_chip_select; +}; + +extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, + const u8 word, u16 *data); +extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, + const u8 word, __le16 *data, const u16 words); From 4b914dc0493edff19ff698a18198a173a14ba9d2 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 14 May 2007 23:06:01 +0200 Subject: [PATCH 057/551] [PATCH] eeprom_93cx6: Add comment for 1us delay after pulse This will add a comment for the 1us delay which is taken after the pulse has been switched. The 1us delay is based on the specifications so that should be made clear. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/misc/eeprom_93cx6.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c index bfcb43424dcd..0d6d742d42c3 100644 --- a/drivers/misc/eeprom_93cx6.c +++ b/drivers/misc/eeprom_93cx6.c @@ -39,6 +39,12 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom) { eeprom->reg_data_clock = 1; eeprom->register_write(eeprom); + + /* + * Add a short delay for the pulse to work. + * According to the specifications the minimal time + * should be 450ns so a 1us delay is sufficient. + */ udelay(1); } @@ -46,6 +52,12 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) { eeprom->reg_data_clock = 0; eeprom->register_write(eeprom); + + /* + * Add a short delay for the pulse to work. + * According to the specifications the minimal time + * should be 450ns so a 1us delay is sufficient. + */ udelay(1); } From 605bebe23bf6ac66c0a717e663a7baa2f981294d Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Mon, 14 May 2007 01:41:02 -0400 Subject: [PATCH 058/551] [PATCH] Add rtl8187 wireless driver This patch adds a mac80211 based wireless driver for the rtl8187 USB wireless card. Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- MAINTAINERS | 10 + drivers/net/wireless/Kconfig | 12 + drivers/net/wireless/Makefile | 3 + drivers/net/wireless/rtl8187.h | 131 +++++ drivers/net/wireless/rtl8187_dev.c | 731 ++++++++++++++++++++++++ drivers/net/wireless/rtl8187_rtl8225.c | 744 +++++++++++++++++++++++++ drivers/net/wireless/rtl8187_rtl8225.h | 30 + drivers/net/wireless/rtl818x.h | 212 +++++++ 8 files changed, 1873 insertions(+) create mode 100644 drivers/net/wireless/rtl8187.h create mode 100644 drivers/net/wireless/rtl8187_dev.c create mode 100644 drivers/net/wireless/rtl8187_rtl8225.c create mode 100644 drivers/net/wireless/rtl8187_rtl8225.h create mode 100644 drivers/net/wireless/rtl818x.h diff --git a/MAINTAINERS b/MAINTAINERS index df40a4ec87fb..2c1dfb271613 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3049,6 +3049,16 @@ S: Maintained RISCOM8 DRIVER S: Orphan +RTL818X WIRELESS DRIVER +P: Michael Wu +M: flamingice@sourmilk.net +P: Andrea Merello +M: andreamrl@tiscali.it +L: linux-wireless@vger.kernel.org +W: http://linuxwireless.org/ +T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git +S: Maintained + S3 SAVAGE FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@gmail.com diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index fa2399cbd5ca..ae27af0141c0 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -546,6 +546,18 @@ config USB_ZD1201 To compile this driver as a module, choose M here: the module will be called zd1201. +config RTL8187 + tristate "Realtek 8187 USB support" + depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL + select EEPROM_93CX6 + ---help--- + This is a driver for RTL8187 based cards. + These are USB based chips found in cards such as: + + Netgear WG111v2 + + Thanks to Realtek for their support! + source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/bcm43xx/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index d2124602263b..ef35bc6c4a22 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -44,3 +44,6 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o obj-$(CONFIG_USB_ZD1201) += zd1201.o obj-$(CONFIG_LIBERTAS_USB) += libertas/ + +rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o +obj-$(CONFIG_RTL8187) += rtl8187.o diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h new file mode 100644 index 000000000000..41d0aac3e27e --- /dev/null +++ b/drivers/net/wireless/rtl8187.h @@ -0,0 +1,131 @@ +#ifndef RTL8187_H +#define RTL8187_H + +#include "rtl818x.h" + +#define RTL8187_EEPROM_TXPWR_BASE 0x05 +#define RTL8187_EEPROM_MAC_ADDR 0x07 +#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ +#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ + +#define RTL8187_REQT_READ 0xC0 +#define RTL8187_REQT_WRITE 0x40 +#define RTL8187_REQ_GET_REG 0x05 +#define RTL8187_REQ_SET_REG 0x05 + +#define RTL8187_MAX_RX 0x9C4 + +struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +}; + +struct rtl8187_rx_hdr { + __le16 len; + __le16 rate; + u8 noise; + u8 signal; + u8 agc; + u8 reserved; + __le64 mac_time; +} __attribute__((packed)); + +struct rtl8187_tx_info { + struct ieee80211_tx_control *control; + struct urb *urb; + struct ieee80211_hw *dev; +}; + +struct rtl8187_tx_hdr { + __le32 flags; +#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15) +#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17) +#define RTL8187_TX_FLAG_CTS (1 << 18) +#define RTL8187_TX_FLAG_RTS (1 << 23) + __le16 rts_duration; + __le16 len; + __le32 retry; +} __attribute__((packed)); + +struct rtl8187_priv { + /* common between rtl818x drivers */ + struct rtl818x_csr *map; + void (*rf_init)(struct ieee80211_hw *); + int mode; + + /* rtl8187 specific */ + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_hw_mode modes[2]; + struct usb_device *udev; + u8 *hwaddr; + u16 txpwr_base; + u8 asic_rev; + struct sk_buff_head rx_queue; +}; + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); + +static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr) +{ + u8 val; + + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); + + return val; +} + +static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr) +{ + __le16 val; + + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); + + return le16_to_cpu(val); +} + +static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) +{ + __le32 val; + + usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), + RTL8187_REQ_GET_REG, RTL8187_REQT_READ, + (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); + + return le32_to_cpu(val); +} + +static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, + u8 *addr, u8 val) +{ + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); +} + +static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, + __le16 *addr, u16 val) +{ + __le16 buf = cpu_to_le16(val); + + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2); +} + +static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, + __le32 *addr, u32 val) +{ + __le32 buf = cpu_to_le32(val); + + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2); +} + +#endif /* RTL8187_H */ diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c new file mode 100644 index 000000000000..83656107b97e --- /dev/null +++ b/drivers/net/wireless/rtl8187_dev.c @@ -0,0 +1,731 @@ + +/* + * Linux device driver for RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8187_rtl8225.h" + +MODULE_AUTHOR("Michael Wu "); +MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("RTL8187 USB wireless driver"); +MODULE_LICENSE("GPL"); + +static struct usb_device_id rtl8187_table[] __devinitdata = { + /* Realtek */ + {USB_DEVICE(0x0bda, 0x8187)}, + /* Netgear */ + {USB_DEVICE(0x0846, 0x6100)}, + {USB_DEVICE(0x0846, 0x6a00)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8187_table); + +void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) +{ + struct rtl8187_priv *priv = dev->priv; + + data <<= 8; + data |= addr | 0x80; + + rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF); + rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF); + + msleep(1); +} + +static void rtl8187_tx_cb(struct urb *urb) +{ + struct ieee80211_tx_status status = { {0} }; + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb; + + usb_free_urb(info->urb); + if (info->control) + memcpy(&status.control, info->control, sizeof(status.control)); + kfree(info->control); + skb_pull(skb, sizeof(struct rtl8187_tx_hdr)); + status.flags |= IEEE80211_TX_STATUS_ACK; + ieee80211_tx_status_irqsafe(info->dev, skb, &status); +} + +static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, + struct ieee80211_tx_control *control) +{ + struct rtl8187_priv *priv = dev->priv; + struct rtl8187_tx_hdr *hdr; + struct rtl8187_tx_info *info; + struct urb *urb; + u32 tmp; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree_skb(skb); + return 0; + } + + hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); + tmp = skb->len - sizeof(*hdr); + tmp |= RTL8187_TX_FLAG_NO_ENCRYPT; + tmp |= control->rts_cts_rate << 19; + tmp |= control->tx_rate << 24; + if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb)) + tmp |= RTL8187_TX_FLAG_MORE_FRAG; + if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { + tmp |= RTL8187_TX_FLAG_RTS; + hdr->rts_duration = + ieee80211_rts_duration(dev, skb->len, control); + } + if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) + tmp |= RTL8187_TX_FLAG_CTS; + hdr->flags = cpu_to_le32(tmp); + hdr->len = 0; + tmp = control->retry_limit << 8; + hdr->retry = cpu_to_le32(tmp); + + info = (struct rtl8187_tx_info *)skb->cb; + info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC); + info->urb = urb; + info->dev = dev; + usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), + hdr, skb->len, rtl8187_tx_cb, skb); + usb_submit_urb(urb, GFP_ATOMIC); + + return 0; +} + +static void rtl8187_rx_cb(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; + struct ieee80211_hw *dev = info->dev; + struct rtl8187_priv *priv = dev->priv; + struct rtl8187_rx_hdr *hdr; + struct ieee80211_rx_status rx_status = { 0 }; + int rate, signal; + + spin_lock(&priv->rx_queue.lock); + if (skb->next) + __skb_unlink(skb, &priv->rx_queue); + else { + spin_unlock(&priv->rx_queue.lock); + return; + } + spin_unlock(&priv->rx_queue.lock); + + if (unlikely(urb->status)) { + usb_free_urb(urb); + dev_kfree_skb_irq(skb); + return; + } + + skb_put(skb, urb->actual_length); + hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr)); + skb_trim(skb, le16_to_cpu(hdr->len) & 0x0FFF); + + signal = hdr->agc >> 1; + rate = (le16_to_cpu(hdr->rate) >> 4) & 0xF; + if (rate > 3) { /* OFDM rate */ + if (signal > 90) + signal = 90; + else if (signal < 25) + signal = 25; + signal = 90 - signal; + } else { /* CCK rate */ + if (signal > 95) + signal = 95; + else if (signal < 30) + signal = 30; + signal = 95 - signal; + } + + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.signal = 64 - min(hdr->noise, (u8)64); + rx_status.ssi = signal; + rx_status.rate = rate; + rx_status.freq = dev->conf.freq; + rx_status.channel = dev->conf.channel; + rx_status.phymode = dev->conf.phymode; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + ieee80211_rx_irqsafe(dev, skb, &rx_status); + + skb = dev_alloc_skb(RTL8187_MAX_RX); + if (unlikely(!skb)) { + usb_free_urb(urb); + /* TODO check rx queue length and refill *somewhere* */ + return; + } + + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = urb; + info->dev = dev; + urb->transfer_buffer = skb_tail_pointer(skb); + urb->context = skb; + skb_queue_tail(&priv->rx_queue, skb); + + usb_submit_urb(urb, GFP_ATOMIC); +} + +static int rtl8187_init_urbs(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct urb *entry; + struct sk_buff *skb; + struct rtl8187_rx_info *info; + + while (skb_queue_len(&priv->rx_queue) < 8) { + skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); + if (!skb) + break; + entry = usb_alloc_urb(0, GFP_KERNEL); + if (!entry) { + kfree_skb(skb); + break; + } + usb_fill_bulk_urb(entry, priv->udev, + usb_rcvbulkpipe(priv->udev, 1), + skb_tail_pointer(skb), + RTL8187_MAX_RX, rtl8187_rx_cb, skb); + info = (struct rtl8187_rx_info *)skb->cb; + info->urb = entry; + info->dev = dev; + skb_queue_tail(&priv->rx_queue, skb); + usb_submit_urb(entry, GFP_KERNEL); + } + + return 0; +} + +static int rtl8187_init_hw(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u8 reg; + int i; + + /* reset */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + msleep(200); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11); + rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00); + msleep(200); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= (1 << 1); + reg |= RTL818X_CMD_RESET; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + i = 10; + do { + msleep(2); + if (!(rtl818x_ioread8(priv, &priv->map->CMD) & + RTL818X_CMD_RESET)) + break; + } while (--i); + + if (!i) { + printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy)); + return -ETIMEDOUT; + } + + /* reload registers from eeprom */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); + + i = 10; + do { + msleep(4); + if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) & + RTL818X_EEPROM_CMD_CONFIG)) + break; + } while (--i); + + if (!i) { + printk(KERN_ERR "%s: eeprom reset timeout!\n", + wiphy_name(dev->wiphy)); + return -ETIMEDOUT; + } + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + /* setup card */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO, 0); + + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO, 1); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->MAC[i], priv->hwaddr[i]); + + rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG1); + reg &= 0x3F; + reg |= 0x80; + rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); + + // TODO: set RESP_RATE and BRSR properly + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + + /* host_usb_init */ + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); + rtl818x_iowrite8(priv, &priv->map->GPIO, 0); + reg = rtl818x_ioread8(priv, (u8 *)0xFE53); + rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8)); + rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80); + msleep(100); + + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); + msleep(100); + + priv->rf_init(dev); + + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); + reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe; + rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1); + rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); + rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); + rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); + rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); + + return 0; +} + +static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel) +{ + u32 reg; + struct rtl8187_priv *priv = dev->priv; + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + /* Enable TX loopback on MAC level to avoid TX during channel + * changes, as this has be seen to causes problems and the + * card will stop work until next reset + */ + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + reg | RTL818X_TX_CONF_LOOPBACK_MAC); + msleep(10); + rtl8225_rf_set_channel(dev, channel); + msleep(10); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); +} + +static int rtl8187_open(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + u32 reg; + int ret; + + ret = rtl8187_init_hw(dev); + if (ret) + return ret; + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + + rtl8187_init_urbs(dev); + + reg = RTL818X_RX_CONF_ONLYERLPKT | + RTL818X_RX_CONF_RX_AUTORESETPHY | + RTL818X_RX_CONF_BSSID | + RTL818X_RX_CONF_MGMT | + RTL818X_RX_CONF_CTRL | + RTL818X_RX_CONF_DATA | + (7 << 13 /* RX FIFO threshold NONE */) | + (7 << 10 /* MAX RX DMA */) | + RTL818X_RX_CONF_BROADCAST | + RTL818X_RX_CONF_MULTICAST | + RTL818X_RX_CONF_NICMAC; + if (priv->mode == IEEE80211_IF_TYPE_MNTR) + reg |= RTL818X_RX_CONF_MONITOR; + + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); + reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; + reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; + reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT; + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); + + reg = RTL818X_TX_CONF_CW_MIN | + (7 << 21 /* MAX TX DMA */) | + RTL818X_TX_CONF_NO_ICV; + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg |= RTL818X_CMD_TX_ENABLE; + reg |= RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + return 0; +} + +static int rtl8187_stop(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + struct rtl8187_rx_info *info; + struct sk_buff *skb; + u32 reg; + + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + + reg = rtl818x_ioread8(priv, &priv->map->CMD); + reg &= ~RTL818X_CMD_TX_ENABLE; + reg &= ~RTL818X_CMD_RX_ENABLE; + rtl818x_iowrite8(priv, &priv->map->CMD, reg); + + rtl8225_rf_stop(dev); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + while ((skb = skb_dequeue(&priv->rx_queue))) { + info = (struct rtl8187_rx_info *)skb->cb; + usb_kill_urb(info->urb); + kfree_skb(skb); + } + return 0; +} + +static int rtl8187_add_interface(struct ieee80211_hw *dev, + struct ieee80211_if_init_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + + /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */ + if (priv->mode != IEEE80211_IF_TYPE_MGMT) + return -1; + + switch (conf->type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_MNTR: + priv->mode = conf->type; + break; + default: + return -EOPNOTSUPP; + } + + priv->hwaddr = conf->mac_addr; + + return 0; +} + +static void rtl8187_remove_interface(struct ieee80211_hw *dev, + struct ieee80211_if_init_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + priv->mode = IEEE80211_IF_TYPE_MGMT; +} + +static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + rtl8187_set_channel(dev, conf->channel); + + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); + + if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); + } else { + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); + rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); + } + + rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); + rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); + rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); + return 0; +} + +static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id, + struct ieee80211_if_conf *conf) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + for (i = 0; i < ETH_ALEN; i++) + rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); + + if (is_valid_ether_addr(conf->bssid)) + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA); + else + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK); + + return 0; +} + +static const struct ieee80211_ops rtl8187_ops = { + .tx = rtl8187_tx, + .open = rtl8187_open, + .stop = rtl8187_stop, + .add_interface = rtl8187_add_interface, + .remove_interface = rtl8187_remove_interface, + .config = rtl8187_config, + .config_interface = rtl8187_config_interface, +}; + +static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); + + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; +} + +static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ieee80211_hw *dev = eeprom->data; + struct rtl8187_priv *priv = dev->priv; + u8 reg = RTL818X_EEPROM_CMD_PROGRAM; + + if (eeprom->reg_data_in) + reg |= RTL818X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL818X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL818X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL818X_EEPROM_CMD_CS; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); + udelay(10); +} + +static int __devinit rtl8187_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct ieee80211_hw *dev; + struct rtl8187_priv *priv; + struct eeprom_93cx6 eeprom; + struct ieee80211_channel *channel; + u16 txpwr, reg; + int err, i; + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); + if (!dev) { + printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n"); + return -ENOMEM; + } + + priv = dev->priv; + + SET_IEEE80211_DEV(dev, &intf->dev); + usb_set_intfdata(intf, dev); + priv->udev = udev; + + usb_get_dev(udev); + + skb_queue_head_init(&priv->rx_queue); + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); + priv->map = (struct rtl818x_csr *)0xFF00; + priv->modes[0].mode = MODE_IEEE80211G; + priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); + priv->modes[0].rates = priv->rates; + priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); + priv->modes[0].channels = priv->channels; + priv->modes[1].mode = MODE_IEEE80211B; + priv->modes[1].num_rates = 4; + priv->modes[1].rates = priv->rates; + priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); + priv->modes[1].channels = priv->channels; + priv->mode = IEEE80211_IF_TYPE_MGMT; + dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_WEP_INCLUDE_IV | + IEEE80211_HW_DATA_NULLFUNC_ACK; + dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); + dev->queues = 1; + dev->max_rssi = 65; + dev->max_signal = 64; + + for (i = 0; i < 2; i++) + if ((err = ieee80211_register_hwmode(dev, &priv->modes[i]))) + goto err_free_dev; + + eeprom.data = dev; + eeprom.register_read = rtl8187_eeprom_register_read; + eeprom.register_write = rtl8187_eeprom_register_write; + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) + eeprom.width = PCI_EEPROM_WIDTH_93C66; + else + eeprom.width = PCI_EEPROM_WIDTH_93C46; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + udelay(10); + + eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, + (__le16 __force *)dev->wiphy->perm_addr, 3); + if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { + printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " + "generated MAC address\n"); + random_ether_addr(dev->wiphy->perm_addr); + } + + channel = priv->channels; + for (i = 0; i < 3; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, + &txpwr); + (*channel++).val = txpwr & 0xFF; + (*channel++).val = txpwr >> 8; + } + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, + &txpwr); + (*channel++).val = txpwr & 0xFF; + (*channel++).val = txpwr >> 8; + } + for (i = 0; i < 2; i++) { + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, + &txpwr); + (*channel++).val = txpwr & 0xFF; + (*channel++).val = txpwr >> 8; + } + + eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, + &priv->txpwr_base); + + reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1); + /* 0 means asic B-cut, we should use SW 3 wire + * bit-by-bit banging for radio. 1 means we can use + * USB specific request to write radio registers */ + priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; + rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write(dev, 0, 0x1B7); + + if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700) + priv->rf_init = rtl8225_rf_init; + else + priv->rf_init = rtl8225z2_rf_init; + + rtl8225_write(dev, 0, 0x0B7); + + err = ieee80211_register_hw(dev); + if (err) { + printk(KERN_ERR "rtl8187: Cannot register device\n"); + goto err_free_dev; + } + + printk(KERN_INFO "%s: hwaddr " MAC_FMT ", rtl8187 V%d + %s\n", + wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr), + priv->asic_rev, priv->rf_init == rtl8225_rf_init ? + "rtl8225" : "rtl8225z2"); + + return 0; + + err_free_dev: + ieee80211_free_hw(dev); + usb_set_intfdata(intf, NULL); + usb_put_dev(udev); + return err; +} + +static void __devexit rtl8187_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *dev = usb_get_intfdata(intf); + struct rtl8187_priv *priv; + + if (!dev) + return; + + ieee80211_unregister_hw(dev); + + priv = dev->priv; + usb_put_dev(interface_to_usbdev(intf)); + ieee80211_free_hw(dev); +} + +static struct usb_driver rtl8187_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8187_table, + .probe = rtl8187_probe, + .disconnect = rtl8187_disconnect, +}; + +static int __init rtl8187_init(void) +{ + return usb_register(&rtl8187_driver); +} + +static void __exit rtl8187_exit(void) +{ + usb_deregister(&rtl8187_driver); +} + +module_init(rtl8187_init); +module_exit(rtl8187_exit); diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c new file mode 100644 index 000000000000..c3f5bf543c90 --- /dev/null +++ b/drivers/net/wireless/rtl8187_rtl8225.c @@ -0,0 +1,744 @@ + +/* + * Radio tuning for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * Thanks to Realtek for their support! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8187_rtl8225.h" + +static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg84, reg82; + u32 bangdata; + int i; + + bangdata = (data << 4) | (addr & 0xf); + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); + + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + for (i = 15; i >= 0; i--) { + u16 reg = reg80 | (bangdata & (1 << i)) >> i; + + if (i & 1) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); + + if (!(i & 1)) + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + msleep(2); +} + +static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~(0x3 << 2); + reg84 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(10); + + usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), + RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, + addr, 0x8225, &data, sizeof(data), HZ / 2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(10); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + msleep(2); +} + +void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +{ + struct rtl8187_priv *priv = dev->priv; + + if (priv->asic_rev) + rtl8225_write_8051(dev, addr, data); + else + rtl8225_write_bitbang(dev, addr, data); +} + +u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +{ + struct rtl8187_priv *priv = dev->priv; + u16 reg80, reg82, reg84, out; + int i; + + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); + + reg80 &= ~0xF; + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); + udelay(4); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); + udelay(5); + + for (i = 4; i >= 0; i--) { + u16 reg = reg80 | ((addr >> i) & 1); + + if (!(i & 1)) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg | (1 << 1)); + udelay(2); + + if (i & 1) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); + udelay(1); + } + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + + out = 0; + for (i = 11; i >= 0; i--) { + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(1); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 1)); + udelay(2); + + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) + out |= 1 << i; + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3)); + udelay(2); + } + + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, + reg80 | (1 << 3) | (1 << 2)); + udelay(2); + + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); + + return out; +} + +static const u16 rtl8225bcd_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb +}; + +static const u8 rtl8225_agc[] = { + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const u8 rtl8225_gain[] = { + 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */ + 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */ + 0x33, 0x80, 0x79, 0xc5, /* -78dBm */ + 0x43, 0x78, 0x76, 0xc5, /* -74dBm */ + 0x53, 0x60, 0x73, 0xc5, /* -70dBm */ + 0x63, 0x58, 0x70, 0xc5, /* -66dBm */ +}; + +static const u8 rtl8225_threshold[] = { + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd +}; + +static const u8 rtl8225_tx_gain_cck_ofdm[] = { + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e +}; + +static const u8 rtl8225_tx_power_cck[] = { + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 +}; + +static const u8 rtl8225_tx_power_cck_ch14[] = { + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225_tx_power_ofdm[] = { + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 +}; + +static const u32 rtl8225_chan[] = { + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 +}; + +static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].val & 0xF; + ofdm_power = priv->channels[channel - 1].val >> 4; + + cck_power = min(cck_power, (u8)11); + ofdm_power = min(ofdm_power, (u8)35); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); + + if (channel == 14) + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; + else + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + msleep(1); // FIXME: optional? + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 6, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x00); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1); + + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; + + rtl8225_write_phy_ofdm(dev, 5, *tmp); + rtl8225_write_phy_ofdm(dev, 7, *tmp); + + msleep(1); +} + +void rtl8225_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x067); msleep(1); + rtl8225_write(dev, 0x1, 0xFE0); msleep(1); + rtl8225_write(dev, 0x2, 0x44D); msleep(1); + rtl8225_write(dev, 0x3, 0x441); msleep(1); + rtl8225_write(dev, 0x4, 0x486); msleep(1); + rtl8225_write(dev, 0x5, 0xBC0); msleep(1); + rtl8225_write(dev, 0x6, 0xAE6); msleep(1); + rtl8225_write(dev, 0x7, 0x82A); msleep(1); + rtl8225_write(dev, 0x8, 0x01F); msleep(1); + rtl8225_write(dev, 0x9, 0x334); msleep(1); + rtl8225_write(dev, 0xA, 0xFD4); msleep(1); + rtl8225_write(dev, 0xB, 0x391); msleep(1); + rtl8225_write(dev, 0xC, 0x050); msleep(1); + rtl8225_write(dev, 0xD, 0x6DB); msleep(1); + rtl8225_write(dev, 0xE, 0x029); msleep(1); + rtl8225_write(dev, 0xF, 0x914); msleep(100); + + rtl8225_write(dev, 0x2, 0xC4D); msleep(200); + rtl8225_write(dev, 0x2, 0x44D); msleep(200); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0c4d); + msleep(200); + rtl8225_write(dev, 0x02, 0x044d); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", + wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); + } + + rtl8225_write(dev, 0x0, 0x127); + + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); + } + + rtl8225_write(dev, 0x0, 0x027); + rtl8225_write(dev, 0x0, 0x22F); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); + + rtl8225_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); + + /* set sensitivity */ + rtl8225_write(dev, 0x0c, 0x50); + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]); + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]); + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); +} + +static const u8 rtl8225z2_tx_power_cck_ch14[] = { + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 rtl8225z2_tx_power_cck[] = { + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 +}; + +static const u8 rtl8225z2_tx_power_ofdm[] = { + 0x42, 0x00, 0x40, 0x00, 0x40 +}; + +static const u8 rtl8225z2_tx_gain_cck_ofdm[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 +}; + +static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + u8 cck_power, ofdm_power; + const u8 *tmp; + u32 reg; + int i; + + cck_power = priv->channels[channel - 1].val & 0xF; + ofdm_power = priv->channels[channel - 1].val >> 4; + + cck_power = min(cck_power, (u8)15); + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + + ofdm_power = min(ofdm_power, (u8)15); + ofdm_power += priv->txpwr_base >> 4; + ofdm_power = min(ofdm_power, (u8)35); + + if (channel == 14) + tmp = rtl8225z2_tx_power_cck_ch14; + else + tmp = rtl8225z2_tx_power_cck; + + for (i = 0; i < 8; i++) + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225z2_tx_gain_cck_ofdm[cck_power]); + msleep(1); + + /* anaparam2 on */ + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + + rtl8225_write_phy_ofdm(dev, 2, 0x42); + rtl8225_write_phy_ofdm(dev, 5, 0x00); + rtl8225_write_phy_ofdm(dev, 6, 0x40); + rtl8225_write_phy_ofdm(dev, 7, 0x00); + rtl8225_write_phy_ofdm(dev, 8, 0x40); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, + rtl8225z2_tx_gain_cck_ofdm[ofdm_power]); + msleep(1); +} + +static const u16 rtl8225z2_rxgain[] = { + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb +}; + +static const u8 rtl8225z2_gain_bg[] = { + 0x23, 0x15, 0xa5, /* -82-1dBm */ + 0x23, 0x15, 0xb5, /* -82-2dBm */ + 0x23, 0x15, 0xc5, /* -82-3dBm */ + 0x33, 0x15, 0xc5, /* -78dBm */ + 0x43, 0x15, 0xc5, /* -74dBm */ + 0x53, 0x15, 0xc5, /* -70dBm */ + 0x63, 0x15, 0xc5 /* -66dBm */ +}; + +void rtl8225z2_rf_init(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + int i; + + rtl8225_write(dev, 0x0, 0x2BF); msleep(1); + rtl8225_write(dev, 0x1, 0xEE0); msleep(1); + rtl8225_write(dev, 0x2, 0x44D); msleep(1); + rtl8225_write(dev, 0x3, 0x441); msleep(1); + rtl8225_write(dev, 0x4, 0x8C3); msleep(1); + rtl8225_write(dev, 0x5, 0xC72); msleep(1); + rtl8225_write(dev, 0x6, 0x0E6); msleep(1); + rtl8225_write(dev, 0x7, 0x82A); msleep(1); + rtl8225_write(dev, 0x8, 0x03F); msleep(1); + rtl8225_write(dev, 0x9, 0x335); msleep(1); + rtl8225_write(dev, 0xa, 0x9D4); msleep(1); + rtl8225_write(dev, 0xb, 0x7BB); msleep(1); + rtl8225_write(dev, 0xc, 0x850); msleep(1); + rtl8225_write(dev, 0xd, 0xCDF); msleep(1); + rtl8225_write(dev, 0xe, 0x02B); msleep(1); + rtl8225_write(dev, 0xf, 0x114); msleep(100); + + rtl8225_write(dev, 0x0, 0x1B7); + + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + rtl8225_write(dev, 0x1, i + 1); + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); + } + + rtl8225_write(dev, 0x3, 0x080); + rtl8225_write(dev, 0x5, 0x004); + rtl8225_write(dev, 0x0, 0x0B7); + rtl8225_write(dev, 0x2, 0xc4D); + + msleep(200); + rtl8225_write(dev, 0x2, 0x44D); + msleep(100); + + if (!(rtl8225_read(dev, 6) & (1 << 7))) { + rtl8225_write(dev, 0x02, 0x0C4D); + msleep(200); + rtl8225_write(dev, 0x02, 0x044D); + msleep(100); + if (!(rtl8225_read(dev, 6) & (1 << 7))) + printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", + wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); + } + + msleep(200); + + rtl8225_write(dev, 0x0, 0x2BF); + + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); + msleep(1); + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); + msleep(1); + } + + msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x11, 0x07); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x21, 0x17); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); //FIXME: not needed? + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x25, 0x00); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); + + rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]); + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]); + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]); + rtl8225_write_phy_ofdm(dev, 0x21, 0x37); + + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); + rtl8225_write_phy_cck(dev, 0x13, 0xd0); + rtl8225_write_phy_cck(dev, 0x19, 0x00); + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); + rtl8225_write_phy_cck(dev, 0x1b, 0x08); + rtl8225_write_phy_cck(dev, 0x40, 0x86); + rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); + rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1); + rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1); + rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1); + rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1); + rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1); + rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1); + rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1); + rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1); + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); + + rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1); + + rtl8225z2_rf_set_tx_power(dev, 1); + + /* RX antenna default to A */ + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ + + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ + msleep(1); + rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); +} + +void rtl8225_rf_stop(struct ieee80211_hw *dev) +{ + u8 reg; + struct rtl8187_priv *priv = dev->priv; + + rtl8225_write(dev, 0x4, 0x1f); msleep(1); + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); +} + +void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel) +{ + struct rtl8187_priv *priv = dev->priv; + + if (priv->rf_init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, channel); + else + rtl8225z2_rf_set_tx_power(dev, channel); + + rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]); + msleep(10); +} diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h new file mode 100644 index 000000000000..ed28118653c7 --- /dev/null +++ b/drivers/net/wireless/rtl8187_rtl8225.h @@ -0,0 +1,30 @@ +#ifndef RTL8187_RTL8225_H +#define RTL8187_RTL8225_H + +#define RTL8225_ANAPARAM_ON 0xa0000a59 +#define RTL8225_ANAPARAM2_ON 0x860c7312 +#define RTL8225_ANAPARAM_OFF 0xa00beb59 +#define RTL8225_ANAPARAM2_OFF 0x840dec11 + +void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data); +u16 rtl8225_read(struct ieee80211_hw *, u8 addr); + +void rtl8225_rf_init(struct ieee80211_hw *); +void rtl8225z2_rf_init(struct ieee80211_hw *); +void rtl8225_rf_stop(struct ieee80211_hw *); +void rtl8225_rf_set_channel(struct ieee80211_hw *, int); + + +static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data); +} + +static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, + u8 addr, u32 data) +{ + rtl8187_write_phy(dev, addr, data | 0x10000); +} + +#endif /* RTL8187_RTL8225_H */ diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h new file mode 100644 index 000000000000..e4ee946e1d90 --- /dev/null +++ b/drivers/net/wireless/rtl818x.h @@ -0,0 +1,212 @@ +#ifndef RTL818X_H +#define RTL818X_H + +struct rtl818x_csr { + u8 MAC[6]; + u8 reserved_0[2]; + __le32 MAR[2]; + u8 RX_FIFO_COUNT; + u8 reserved_1; + u8 TX_FIFO_COUNT; + u8 BQREQ; + u8 reserved_2[4]; + __le32 TSFT[2]; + __le32 TLPDA; + __le32 TNPDA; + __le32 THPDA; + __le16 BRSR; + u8 BSSID[6]; + u8 RESP_RATE; + u8 EIFS; + u8 reserved_3[1]; + u8 CMD; +#define RTL818X_CMD_TX_ENABLE (1 << 2) +#define RTL818X_CMD_RX_ENABLE (1 << 3) +#define RTL818X_CMD_RESET (1 << 4) + u8 reserved_4[4]; + __le16 INT_MASK; + __le16 INT_STATUS; +#define RTL818X_INT_RX_OK (1 << 0) +#define RTL818X_INT_RX_ERR (1 << 1) +#define RTL818X_INT_TXL_OK (1 << 2) +#define RTL818X_INT_TXL_ERR (1 << 3) +#define RTL818X_INT_RX_DU (1 << 4) +#define RTL818X_INT_RX_FO (1 << 5) +#define RTL818X_INT_TXN_OK (1 << 6) +#define RTL818X_INT_TXN_ERR (1 << 7) +#define RTL818X_INT_TXH_OK (1 << 8) +#define RTL818X_INT_TXH_ERR (1 << 9) +#define RTL818X_INT_TXB_OK (1 << 10) +#define RTL818X_INT_TXB_ERR (1 << 11) +#define RTL818X_INT_ATIM (1 << 12) +#define RTL818X_INT_BEACON (1 << 13) +#define RTL818X_INT_TIME_OUT (1 << 14) +#define RTL818X_INT_TX_FO (1 << 15) + __le32 TX_CONF; +#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) +#define RTL818X_TX_CONF_NO_ICV (1 << 19) +#define RTL818X_TX_CONF_DISCW (1 << 20) +#define RTL818X_TX_CONF_R8180_ABCD (2 << 25) +#define RTL818X_TX_CONF_R8180_F (3 << 25) +#define RTL818X_TX_CONF_R8185_ABC (4 << 25) +#define RTL818X_TX_CONF_R8185_D (5 << 25) +#define RTL818X_TX_CONF_HWVER_MASK (7 << 25) +#define RTL818X_TX_CONF_CW_MIN (1 << 31) + __le32 RX_CONF; +#define RTL818X_RX_CONF_MONITOR (1 << 0) +#define RTL818X_RX_CONF_NICMAC (1 << 1) +#define RTL818X_RX_CONF_MULTICAST (1 << 2) +#define RTL818X_RX_CONF_BROADCAST (1 << 3) +#define RTL818X_RX_CONF_DATA (1 << 18) +#define RTL818X_RX_CONF_CTRL (1 << 19) +#define RTL818X_RX_CONF_MGMT (1 << 20) +#define RTL818X_RX_CONF_BSSID (1 << 23) +#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28) +#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31) + __le32 INT_TIMEOUT; + __le32 TBDA; + u8 EEPROM_CMD; +#define RTL818X_EEPROM_CMD_READ (1 << 0) +#define RTL818X_EEPROM_CMD_WRITE (1 << 1) +#define RTL818X_EEPROM_CMD_CK (1 << 2) +#define RTL818X_EEPROM_CMD_CS (1 << 3) +#define RTL818X_EEPROM_CMD_NORMAL (0 << 6) +#define RTL818X_EEPROM_CMD_LOAD (1 << 6) +#define RTL818X_EEPROM_CMD_PROGRAM (2 << 6) +#define RTL818X_EEPROM_CMD_CONFIG (3 << 6) + u8 CONFIG0; + u8 CONFIG1; + u8 CONFIG2; + __le32 ANAPARAM; + u8 MSR; +#define RTL818X_MSR_NO_LINK (0 << 2) +#define RTL818X_MSR_ADHOC (1 << 2) +#define RTL818X_MSR_INFRA (2 << 2) + u8 CONFIG3; +#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6) + u8 CONFIG4; +#define RTL818X_CONFIG4_POWEROFF (1 << 6) +#define RTL818X_CONFIG4_VCOOFF (1 << 7) + u8 TESTR; + u8 reserved_9[2]; + __le16 PGSELECT; + __le32 ANAPARAM2; + u8 reserved_10[12]; + __le16 BEACON_INTERVAL; + __le16 ATIM_WND; + __le16 BEACON_INTERVAL_TIME; + __le16 ATIMTR_INTERVAL; + u8 reserved_11[4]; + u8 PHY[4]; + __le16 RFPinsOutput; + __le16 RFPinsEnable; + __le16 RFPinsSelect; + __le16 RFPinsInput; + __le32 RF_PARA; + __le32 RF_TIMING; + u8 GP_ENABLE; + u8 GPIO; + u8 reserved_12[10]; + u8 TX_AGC_CTL; +#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0) +#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1) +#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2) + u8 TX_GAIN_CCK; + u8 TX_GAIN_OFDM; + u8 TX_ANTENNA; + u8 reserved_13[16]; + u8 WPA_CONF; + u8 reserved_14[3]; + u8 SIFS; + u8 DIFS; + u8 SLOT; + u8 reserved_15[5]; + u8 CW_CONF; +#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0) +#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1) + u8 CW_VAL; + u8 RATE_FALLBACK; + u8 reserved_16[25]; + u8 CONFIG5; + u8 TX_DMA_POLLING; + u8 reserved_17[2]; + __le16 CWR; + u8 RETRY_CTR; + u8 reserved_18[5]; + __le32 RDSAR; + u8 reserved_19[18]; + u16 TALLY_CNT; + u8 TALLY_SEL; +} __attribute__((packed)); + +static const struct ieee80211_rate rtl818x_rates[] = { + { .rate = 10, + .val = 0, + .flags = IEEE80211_RATE_CCK }, + { .rate = 20, + .val = 1, + .flags = IEEE80211_RATE_CCK }, + { .rate = 55, + .val = 2, + .flags = IEEE80211_RATE_CCK }, + { .rate = 110, + .val = 3, + .flags = IEEE80211_RATE_CCK }, + { .rate = 60, + .val = 4, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 90, + .val = 5, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 120, + .val = 6, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 180, + .val = 7, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 240, + .val = 8, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 360, + .val = 9, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 480, + .val = 10, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 540, + .val = 11, + .flags = IEEE80211_RATE_OFDM }, +}; + +static const struct ieee80211_channel rtl818x_channels[] = { + { .chan = 1, + .freq = 2412}, + { .chan = 2, + .freq = 2417}, + { .chan = 3, + .freq = 2422}, + { .chan = 4, + .freq = 2427}, + { .chan = 5, + .freq = 2432}, + { .chan = 6, + .freq = 2437}, + { .chan = 7, + .freq = 2442}, + { .chan = 8, + .freq = 2447}, + { .chan = 9, + .freq = 2452}, + { .chan = 10, + .freq = 2457}, + { .chan = 11, + .freq = 2462}, + { .chan = 12, + .freq = 2467}, + { .chan = 13, + .freq = 2472}, + { .chan = 14, + .freq = 2484} +}; + +#endif /* RTL818X_H */ From 7e9400f178d291b2208c4ed9aac0f425c1364000 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 11 Jun 2007 21:37:46 -0400 Subject: [PATCH 059/551] [PATCH] eeprom_93cx6: shorten pulse timing to match spec 93cx6 datasheet available here: http://ww1.microchip.com/downloads/en/DeviceDoc/21749F.pdf Figure 1-1 and Table 1-2 on pages 4-5 indicate that both Clock High Time and Clock Low Time have largest minimum times of 450ns. Signed-off-by: John W. Linville --- drivers/misc/eeprom_93cx6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c index 0d6d742d42c3..ac515b0ef67c 100644 --- a/drivers/misc/eeprom_93cx6.c +++ b/drivers/misc/eeprom_93cx6.c @@ -42,10 +42,10 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom) /* * Add a short delay for the pulse to work. - * According to the specifications the minimal time - * should be 450ns so a 1us delay is sufficient. + * According to the specifications the "maximum minimum" + * time should be 450ns. */ - udelay(1); + ndelay(450); } static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) From 0aec00ae1c39b0adaa6e958a4e0119cfc12d884b Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 12 Jun 2007 22:11:42 -0400 Subject: [PATCH 060/551] [PATCH] rtl8187: add header blocks and indicate origin of magic values Add top-of-file comment blocks to rtl818x headers and attribute origin of magic values to original r8187 driver. Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8187.h | 14 ++++++++++++++ drivers/net/wireless/rtl8187_dev.c | 4 ++-- drivers/net/wireless/rtl8187_rtl8225.c | 5 +++-- drivers/net/wireless/rtl8187_rtl8225.h | 14 ++++++++++++++ drivers/net/wireless/rtl818x.h | 14 ++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 41d0aac3e27e..6124e467b156 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h @@ -1,3 +1,17 @@ +/* + * Definitions for RTL8187 hardware + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #ifndef RTL8187_H #define RTL8187_H diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 83656107b97e..cea85894b7f2 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -1,4 +1,3 @@ - /* * Linux device driver for RTL8187 * @@ -8,7 +7,8 @@ * Based on the r8187 driver, which is: * Copyright 2005 Andrea Merello , et al. * - * Thanks to Realtek for their support! + * Magic delays and register offsets below are taken from the original + * r8187 driver sources. Thanks to Realtek for their support! * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index c3f5bf543c90..e25a09f1b068 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c @@ -1,4 +1,3 @@ - /* * Radio tuning for RTL8225 on RTL8187 * @@ -8,7 +7,9 @@ * Based on the r8187 driver, which is: * Copyright 2005 Andrea Merello , et al. * - * Thanks to Realtek for their support! + * Magic delays, register offsets, and phy value tables below are + * taken from the original r8187 driver sources. Thanks to Realtek + * for their support! * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h index ed28118653c7..798ba4a97376 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.h +++ b/drivers/net/wireless/rtl8187_rtl8225.h @@ -1,3 +1,17 @@ +/* + * Radio tuning definitions for RTL8225 on RTL8187 + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #ifndef RTL8187_RTL8225_H #define RTL8187_RTL8225_H diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h index e4ee946e1d90..283de30628e1 100644 --- a/drivers/net/wireless/rtl818x.h +++ b/drivers/net/wireless/rtl818x.h @@ -1,3 +1,17 @@ +/* + * Definitions for RTL818x hardware + * + * Copyright 2007 Michael Wu + * Copyright 2007 Andrea Merello + * + * Based on the r8187 driver, which is: + * Copyright 2005 Andrea Merello , et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + #ifndef RTL818X_H #define RTL818X_H From a9eea9ae6e82d1b0f453c24103a84ce7af5d1e15 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 24 May 2007 01:06:29 +0100 Subject: [PATCH 061/551] [PATCH] zd1211rw: Add ID for ZyXEL G-200v2 Tested by Guy Gallagher zd1211 chip 0586:3407 v4721 high 00-13-49 AL2230_RF pa0 g--- FCC ID SI5WUB200Z Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 8459549d0cee..740a2194fdde 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -54,6 +54,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, From 9c8fc71ddd1b42c0c632036333790f230cea815d Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 24 May 2007 01:06:41 +0100 Subject: [PATCH 062/551] [PATCH] zd1211rw: Extend RF layer These changes are needed for UW2453 RF support: Add pointer which RF drivers can use to store private RF data Add exit hook so that RF drivers can free private data Allow RF's to disable the generic TX power integration handling code Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 3 +++ drivers/net/wireless/zd1211rw/zd_rf.c | 6 ++++++ drivers/net/wireless/zd1211rw/zd_rf.h | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 95b4a2a26707..4a2ceb93aaad 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1253,6 +1253,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, { int r; + if (!zd_rf_should_update_pwr_int(&chip->rf)) + return 0; + r = update_pwr_int(chip, channel); if (r) return r; diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c index 549c23bcd6cc..c4981ad2f9ea 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.c +++ b/drivers/net/wireless/zd1211rw/zd_rf.c @@ -52,10 +52,16 @@ const char *zd_rf_name(u8 type) void zd_rf_init(struct zd_rf *rf) { memset(rf, 0, sizeof(*rf)); + + /* default to update channel integration, as almost all RF's do want + * this */ + rf->update_channel_int = 1; } void zd_rf_clear(struct zd_rf *rf) { + if (rf->clear) + rf->clear(rf); ZD_MEMCLEAR(rf, sizeof(*rf)); } diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h index aa9cc105ce60..c204f9ae7128 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/drivers/net/wireless/zd1211rw/zd_rf.h @@ -48,12 +48,20 @@ struct zd_rf { u8 channel; + /* whether channel integration and calibration should be updated + * defaults to 1 (yes) */ + u8 update_channel_int:1; + + /* private RF driver data */ + void *priv; + /* RF-specific functions */ int (*init_hw)(struct zd_rf *rf); int (*set_channel)(struct zd_rf *rf, u8 channel); int (*switch_radio_on)(struct zd_rf *rf); int (*switch_radio_off)(struct zd_rf *rf); int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel); + void (*clear)(struct zd_rf *rf); }; const char *zd_rf_name(u8 type); @@ -71,6 +79,11 @@ int zd_switch_radio_off(struct zd_rf *rf); int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel); int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel); +static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf) +{ + return rf->update_channel_int; +} + /* Functions for individual RF chips */ int zd_rf_init_rf2959(struct zd_rf *rf); From 4481d6093e62e168ab06e9bbb4e67a9bebb8c7f7 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 24 May 2007 01:06:53 +0100 Subject: [PATCH 063/551] [PATCH] zd1211rw: Add UW2453 RF support This patch adds support for another radio appearing in new devices: the Ubec UW2453. It's more complicated than the other RF's we support, but Ubec publish full tech specs so we're able to understand the vendor code relatively well. Now that we support UW2453, we also support Atheros' new USB chip: the AR5007UG. From the little info we have, this appears to be just a rebranded ZD1211B. This RF code doesn't work very well -- lots more TX/RX errors than the other RFs. However, the vendor driver doesn't do any better, so this is all we can do for now. [kune@deine-taler.de: bug fixes] Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/Makefile | 2 +- drivers/net/wireless/zd1211rw/zd_chip.h | 3 + drivers/net/wireless/zd1211rw/zd_rf.c | 15 +- drivers/net/wireless/zd1211rw/zd_rf.h | 1 + drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 534 +++++++++++++++++++ 5 files changed, 547 insertions(+), 8 deletions(-) create mode 100644 drivers/net/wireless/zd1211rw/zd_rf_uw2453.c diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile index 6603ad5be63d..4d505903352c 100644 --- a/drivers/net/wireless/zd1211rw/Makefile +++ b/drivers/net/wireless/zd1211rw/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw.o zd1211rw-objs := zd_chip.o zd_ieee80211.o \ zd_mac.o zd_netdev.o \ zd_rf_al2230.o zd_rf_rf2959.o \ - zd_rf_al7230b.o \ + zd_rf_al7230b.o zd_rf_uw2453.o \ zd_rf.o zd_usb.o zd_util.o ifeq ($(CONFIG_ZD1211RW_DEBUG),y) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index ce0a5f6da0d2..79d0288c193a 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -608,6 +608,9 @@ enum { #define CR_ZD1211B_TXOP CTL_REG(0x0b20) #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) +/* Used to detect PLL lock */ +#define UW2453_INTR_REG ((zd_addr_t)0x85c1) + #define CWIN_SIZE 0x007f043f diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c index c4981ad2f9ea..7407409b60b1 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.c +++ b/drivers/net/wireless/zd1211rw/zd_rf.c @@ -67,25 +67,23 @@ void zd_rf_clear(struct zd_rf *rf) int zd_rf_init_hw(struct zd_rf *rf, u8 type) { - int r, t; + int r = 0; + int t; struct zd_chip *chip = zd_rf_to_chip(rf); ZD_ASSERT(mutex_is_locked(&chip->mutex)); switch (type) { case RF2959_RF: r = zd_rf_init_rf2959(rf); - if (r) - return r; break; case AL2230_RF: r = zd_rf_init_al2230(rf); - if (r) - return r; break; case AL7230B_RF: r = zd_rf_init_al7230b(rf); - if (r) - return r; + break; + case UW2453_RF: + r = zd_rf_init_uw2453(rf); break; default: dev_err(zd_chip_dev(chip), @@ -94,6 +92,9 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type) return -ENODEV; } + if (r) + return r; + rf->type = type; r = zd_chip_lock_phy_regs(chip); diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h index c204f9ae7128..6dced2ae5a11 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/drivers/net/wireless/zd1211rw/zd_rf.h @@ -89,5 +89,6 @@ static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf) int zd_rf_init_rf2959(struct zd_rf *rf); int zd_rf_init_al2230(struct zd_rf *rf); int zd_rf_init_al7230b(struct zd_rf *rf); +int zd_rf_init_uw2453(struct zd_rf *rf); #endif /* _ZD_RF_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c new file mode 100644 index 000000000000..414e40d571ab --- /dev/null +++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c @@ -0,0 +1,534 @@ +/* zd_rf_uw2453.c: Functions for the UW2453 RF controller + * + * 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 "zd_rf.h" +#include "zd_usb.h" +#include "zd_chip.h" + +/* This RF programming code is based upon the code found in v2.16.0.0 of the + * ZyDAS vendor driver. Unlike other RF's, Ubec publish full technical specs + * for this RF on their website, so we're able to understand more than + * usual as to what is going on. Thumbs up for Ubec for doing that. */ + +/* The 3-wire serial interface provides access to 8 write-only registers. + * The data format is a 4 bit register address followed by a 20 bit value. */ +#define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff)) + +/* For channel tuning, we have to configure registers 1 (synthesizer), 2 (synth + * fractional divide ratio) and 3 (VCO config). + * + * We configure the RF to produce an interrupt when the PLL is locked onto + * the configured frequency. During initialization, we run through a variety + * of different VCO configurations on channel 1 until we detect a PLL lock. + * When this happens, we remember which VCO configuration produced the lock + * and use it later. Actually, we use the configuration *after* the one that + * produced the lock, which seems odd, but it works. + * + * If we do not see a PLL lock on any standard VCO config, we fall back on an + * autocal configuration, which has a fixed (as opposed to per-channel) VCO + * config and different synth values from the standard set (divide ratio + * is still shared with the standard set). */ + +/* The per-channel synth values for all standard VCO configurations. These get + * written to register 1. */ +static const u8 uw2453_std_synth[] = { + RF_CHANNEL( 1) = 0x47, + RF_CHANNEL( 2) = 0x47, + RF_CHANNEL( 3) = 0x67, + RF_CHANNEL( 4) = 0x67, + RF_CHANNEL( 5) = 0x67, + RF_CHANNEL( 6) = 0x67, + RF_CHANNEL( 7) = 0x57, + RF_CHANNEL( 8) = 0x57, + RF_CHANNEL( 9) = 0x57, + RF_CHANNEL(10) = 0x57, + RF_CHANNEL(11) = 0x77, + RF_CHANNEL(12) = 0x77, + RF_CHANNEL(13) = 0x77, + RF_CHANNEL(14) = 0x4f, +}; + +/* This table stores the synthesizer fractional divide ratio for *all* VCO + * configurations (both standard and autocal). These get written to register 2. + */ +static const u16 uw2453_synth_divide[] = { + RF_CHANNEL( 1) = 0x999, + RF_CHANNEL( 2) = 0x99b, + RF_CHANNEL( 3) = 0x998, + RF_CHANNEL( 4) = 0x99a, + RF_CHANNEL( 5) = 0x999, + RF_CHANNEL( 6) = 0x99b, + RF_CHANNEL( 7) = 0x998, + RF_CHANNEL( 8) = 0x99a, + RF_CHANNEL( 9) = 0x999, + RF_CHANNEL(10) = 0x99b, + RF_CHANNEL(11) = 0x998, + RF_CHANNEL(12) = 0x99a, + RF_CHANNEL(13) = 0x999, + RF_CHANNEL(14) = 0xccc, +}; + +/* Here is the data for all the standard VCO configurations. We shrink our + * table a little by observing that both channels in a consecutive pair share + * the same value. We also observe that the high 4 bits ([0:3] in the specs) + * are all 'Reserved' and are always set to 0x4 - we chop them off in the data + * below. */ +#define CHAN_TO_PAIRIDX(a) ((a - 1) / 2) +#define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)] +static const u16 uw2453_std_vco_cfg[][7] = { + { /* table 1 */ + RF_CHANPAIR( 1, 2) = 0x664d, + RF_CHANPAIR( 3, 4) = 0x604d, + RF_CHANPAIR( 5, 6) = 0x6675, + RF_CHANPAIR( 7, 8) = 0x6475, + RF_CHANPAIR( 9, 10) = 0x6655, + RF_CHANPAIR(11, 12) = 0x6455, + RF_CHANPAIR(13, 14) = 0x6665, + }, + { /* table 2 */ + RF_CHANPAIR( 1, 2) = 0x666d, + RF_CHANPAIR( 3, 4) = 0x606d, + RF_CHANPAIR( 5, 6) = 0x664d, + RF_CHANPAIR( 7, 8) = 0x644d, + RF_CHANPAIR( 9, 10) = 0x6675, + RF_CHANPAIR(11, 12) = 0x6475, + RF_CHANPAIR(13, 14) = 0x6655, + }, + { /* table 3 */ + RF_CHANPAIR( 1, 2) = 0x665d, + RF_CHANPAIR( 3, 4) = 0x605d, + RF_CHANPAIR( 5, 6) = 0x666d, + RF_CHANPAIR( 7, 8) = 0x646d, + RF_CHANPAIR( 9, 10) = 0x664d, + RF_CHANPAIR(11, 12) = 0x644d, + RF_CHANPAIR(13, 14) = 0x6675, + }, + { /* table 4 */ + RF_CHANPAIR( 1, 2) = 0x667d, + RF_CHANPAIR( 3, 4) = 0x607d, + RF_CHANPAIR( 5, 6) = 0x665d, + RF_CHANPAIR( 7, 8) = 0x645d, + RF_CHANPAIR( 9, 10) = 0x666d, + RF_CHANPAIR(11, 12) = 0x646d, + RF_CHANPAIR(13, 14) = 0x664d, + }, + { /* table 5 */ + RF_CHANPAIR( 1, 2) = 0x6643, + RF_CHANPAIR( 3, 4) = 0x6043, + RF_CHANPAIR( 5, 6) = 0x667d, + RF_CHANPAIR( 7, 8) = 0x647d, + RF_CHANPAIR( 9, 10) = 0x665d, + RF_CHANPAIR(11, 12) = 0x645d, + RF_CHANPAIR(13, 14) = 0x666d, + }, + { /* table 6 */ + RF_CHANPAIR( 1, 2) = 0x6663, + RF_CHANPAIR( 3, 4) = 0x6063, + RF_CHANPAIR( 5, 6) = 0x6643, + RF_CHANPAIR( 7, 8) = 0x6443, + RF_CHANPAIR( 9, 10) = 0x667d, + RF_CHANPAIR(11, 12) = 0x647d, + RF_CHANPAIR(13, 14) = 0x665d, + }, + { /* table 7 */ + RF_CHANPAIR( 1, 2) = 0x6653, + RF_CHANPAIR( 3, 4) = 0x6053, + RF_CHANPAIR( 5, 6) = 0x6663, + RF_CHANPAIR( 7, 8) = 0x6463, + RF_CHANPAIR( 9, 10) = 0x6643, + RF_CHANPAIR(11, 12) = 0x6443, + RF_CHANPAIR(13, 14) = 0x667d, + }, + { /* table 8 */ + RF_CHANPAIR( 1, 2) = 0x6673, + RF_CHANPAIR( 3, 4) = 0x6073, + RF_CHANPAIR( 5, 6) = 0x6653, + RF_CHANPAIR( 7, 8) = 0x6453, + RF_CHANPAIR( 9, 10) = 0x6663, + RF_CHANPAIR(11, 12) = 0x6463, + RF_CHANPAIR(13, 14) = 0x6643, + }, + { /* table 9 */ + RF_CHANPAIR( 1, 2) = 0x664b, + RF_CHANPAIR( 3, 4) = 0x604b, + RF_CHANPAIR( 5, 6) = 0x6673, + RF_CHANPAIR( 7, 8) = 0x6473, + RF_CHANPAIR( 9, 10) = 0x6653, + RF_CHANPAIR(11, 12) = 0x6453, + RF_CHANPAIR(13, 14) = 0x6663, + }, + { /* table 10 */ + RF_CHANPAIR( 1, 2) = 0x666b, + RF_CHANPAIR( 3, 4) = 0x606b, + RF_CHANPAIR( 5, 6) = 0x664b, + RF_CHANPAIR( 7, 8) = 0x644b, + RF_CHANPAIR( 9, 10) = 0x6673, + RF_CHANPAIR(11, 12) = 0x6473, + RF_CHANPAIR(13, 14) = 0x6653, + }, + { /* table 11 */ + RF_CHANPAIR( 1, 2) = 0x665b, + RF_CHANPAIR( 3, 4) = 0x605b, + RF_CHANPAIR( 5, 6) = 0x666b, + RF_CHANPAIR( 7, 8) = 0x646b, + RF_CHANPAIR( 9, 10) = 0x664b, + RF_CHANPAIR(11, 12) = 0x644b, + RF_CHANPAIR(13, 14) = 0x6673, + }, + +}; + +/* The per-channel synth values for autocal. These get written to register 1. */ +static const u16 uw2453_autocal_synth[] = { + RF_CHANNEL( 1) = 0x6847, + RF_CHANNEL( 2) = 0x6847, + RF_CHANNEL( 3) = 0x6867, + RF_CHANNEL( 4) = 0x6867, + RF_CHANNEL( 5) = 0x6867, + RF_CHANNEL( 6) = 0x6867, + RF_CHANNEL( 7) = 0x6857, + RF_CHANNEL( 8) = 0x6857, + RF_CHANNEL( 9) = 0x6857, + RF_CHANNEL(10) = 0x6857, + RF_CHANNEL(11) = 0x6877, + RF_CHANNEL(12) = 0x6877, + RF_CHANNEL(13) = 0x6877, + RF_CHANNEL(14) = 0x684f, +}; + +/* The VCO configuration for autocal (all channels) */ +static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662; + +/* TX gain settings. The array index corresponds to the TX power integration + * values found in the EEPROM. The values get written to register 7. */ +static u32 uw2453_txgain[] = { + [0x00] = 0x0e313, + [0x01] = 0x0fb13, + [0x02] = 0x0e093, + [0x03] = 0x0f893, + [0x04] = 0x0ea93, + [0x05] = 0x1f093, + [0x06] = 0x1f493, + [0x07] = 0x1f693, + [0x08] = 0x1f393, + [0x09] = 0x1f35b, + [0x0a] = 0x1e6db, + [0x0b] = 0x1ff3f, + [0x0c] = 0x1ffff, + [0x0d] = 0x361d7, + [0x0e] = 0x37fbf, + [0x0f] = 0x3ff8b, + [0x10] = 0x3ff33, + [0x11] = 0x3fb3f, + [0x12] = 0x3ffff, +}; + +/* RF-specific structure */ +struct uw2453_priv { + /* index into synth/VCO config tables where PLL lock was found + * -1 means autocal */ + int config; +}; + +#define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv) + +static int uw2453_synth_set_channel(struct zd_chip *chip, int channel, + bool autocal) +{ + int r; + int idx = channel - 1; + u32 val; + + if (autocal) + val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]); + else + val = UW2453_REGWRITE(1, uw2453_std_synth[idx]); + + r = zd_rfwrite_locked(chip, val, RF_RV_BITS); + if (r) + return r; + + return zd_rfwrite_locked(chip, + UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS); +} + +static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value) +{ + /* vendor driver always sets these upper bits even though the specs say + * they are reserved */ + u32 val = 0x40000 | value; + return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS); +} + +static int uw2453_init_mode(struct zd_chip *chip) +{ + static const u32 rv[] = { + UW2453_REGWRITE(0, 0x25f98), /* enter IDLE mode */ + UW2453_REGWRITE(0, 0x25f9a), /* enter CAL_VCO mode */ + UW2453_REGWRITE(0, 0x25f94), /* enter RX/TX mode */ + UW2453_REGWRITE(0, 0x27fd4), /* power down RSSI circuit */ + }; + + return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); +} + +static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel) +{ + u8 int_value = chip->pwr_int_values[channel - 1]; + + if (int_value >= ARRAY_SIZE(uw2453_txgain)) { + dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for " + "int value %x on channel %d\n", int_value, channel); + return 0; + } + + return zd_rfwrite_locked(chip, + UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS); +} + +static int uw2453_init_hw(struct zd_rf *rf) +{ + int i, r; + int found_config = -1; + u16 intr_status; + struct zd_chip *chip = zd_rf_to_chip(rf); + + static const struct zd_ioreq16 ioreqs[] = { + { CR10, 0x89 }, { CR15, 0x20 }, + { CR17, 0x28 }, /* 6112 no change */ + { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 }, + { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 }, + { CR33, 0x28 }, { CR34, 0x30 }, + { CR35, 0x43 }, /* 6112 3e->43 */ + { CR41, 0x24 }, { CR44, 0x32 }, + { CR46, 0x92 }, /* 6112 96->92 */ + { CR47, 0x1e }, + { CR48, 0x04 }, /* 5602 Roger */ + { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 }, + { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, + { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d }, + { CR99, 0x28 }, { CR100, 0x02 }, + { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */ + { CR102, 0x27 }, + { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */ + { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */ + { CR109, 0x13 }, + { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */ + { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 }, + { CR114, 0x23 }, /* 6221 27->23 */ + { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */ + { CR116, 0x24 }, /* 6220 1c->24 */ + { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */ + { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */ + { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */ + { CR120, 0x4f }, + { CR121, 0x1f }, /* 6220 4f->1f */ + { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad }, + { CR126, 0x6c }, { CR127, 0x03 }, + { CR128, 0x14 }, /* 6302 12->11 */ + { CR129, 0x12 }, /* 6301 10->0f */ + { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 }, + { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff }, + { CR253, 0xff }, + }; + + static const u32 rv[] = { + UW2453_REGWRITE(4, 0x2b), /* configure reciever gain */ + UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */ + UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */ + UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */ + + /* enter CAL_FIL mode, TX gain set by registers, RX gain set by pins, + * RSSI circuit powered down, reduced RSSI range */ + UW2453_REGWRITE(0, 0x25f9c), /* 5d01 cal_fil */ + + /* synthesizer configuration for channel 1 */ + UW2453_REGWRITE(1, 0x47), + UW2453_REGWRITE(2, 0x999), + + /* disable manual VCO band selection */ + UW2453_REGWRITE(3, 0x7602), + + /* enable manual VCO band selection, configure current level */ + UW2453_REGWRITE(3, 0x46063), + }; + + r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + if (r) + return r; + + r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); + if (r) + return r; + + r = uw2453_init_mode(chip); + if (r) + return r; + + /* Try all standard VCO configuration settings on channel 1 */ + for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) { + /* Configure synthesizer for channel 1 */ + r = uw2453_synth_set_channel(chip, 1, false); + if (r) + return r; + + /* Write VCO config */ + r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]); + if (r) + return r; + + /* ack interrupt event */ + r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG); + if (r) + return r; + + /* check interrupt status */ + r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG); + if (r) + return r; + + if (!intr_status & 0xf) { + dev_dbg_f(zd_chip_dev(chip), + "PLL locked on configuration %d\n", i); + found_config = i; + break; + } + } + + if (found_config == -1) { + /* autocal */ + dev_dbg_f(zd_chip_dev(chip), + "PLL did not lock, using autocal\n"); + + r = uw2453_synth_set_channel(chip, 1, true); + if (r) + return r; + + r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG); + if (r) + return r; + } + + /* To match the vendor driver behaviour, we use the configuration after + * the one that produced a lock. */ + UW2453_PRIV(rf)->config = found_config + 1; + + return zd_iowrite16_locked(chip, 0x06, CR203); +} + +static int uw2453_set_channel(struct zd_rf *rf, u8 channel) +{ + int r; + u16 vco_cfg; + int config = UW2453_PRIV(rf)->config; + bool autocal = (config == -1); + struct zd_chip *chip = zd_rf_to_chip(rf); + + static const struct zd_ioreq16 ioreqs[] = { + { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, + { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, + }; + + r = uw2453_synth_set_channel(chip, channel, autocal); + if (r) + return r; + + if (autocal) + vco_cfg = UW2453_AUTOCAL_VCO_CFG; + else + vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)]; + + r = uw2453_write_vco_cfg(chip, vco_cfg); + if (r) + return r; + + r = uw2453_init_mode(chip); + if (r) + return r; + + r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + if (r) + return r; + + r = uw2453_set_tx_gain_level(chip, channel); + if (r) + return r; + + return zd_iowrite16_locked(chip, 0x06, CR203); +} + +static int uw2453_switch_radio_on(struct zd_rf *rf) +{ + int r; + struct zd_chip *chip = zd_rf_to_chip(rf); + struct zd_ioreq16 ioreqs[] = { + { CR11, 0x00 }, { CR251, 0x3f }, + }; + + /* enter RXTX mode */ + r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS); + if (r) + return r; + + if (chip->is_zd1211b) + ioreqs[1].value = 0x7f; + + return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); +} + +static int uw2453_switch_radio_off(struct zd_rf *rf) +{ + int r; + struct zd_chip *chip = zd_rf_to_chip(rf); + static const struct zd_ioreq16 ioreqs[] = { + { CR11, 0x04 }, { CR251, 0x2f }, + }; + + /* enter IDLE mode */ + /* FIXME: shouldn't we go to SLEEP? sent email to zydas */ + r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS); + if (r) + return r; + + return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); +} + +static void uw2453_clear(struct zd_rf *rf) +{ + kfree(rf->priv); +} + +int zd_rf_init_uw2453(struct zd_rf *rf) +{ + rf->init_hw = uw2453_init_hw; + rf->set_channel = uw2453_set_channel; + rf->switch_radio_on = uw2453_switch_radio_on; + rf->switch_radio_off = uw2453_switch_radio_off; + rf->patch_6m_band_edge = zd_rf_generic_patch_6m; + rf->clear = uw2453_clear; + /* we have our own TX integration code */ + rf->update_channel_int = 0; + + rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL); + if (rf->priv == NULL) + return -ENOMEM; + + return 0; +} + From aaf83d4fc4a596929306c894d341e17fbdfba758 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 24 May 2007 01:07:15 +0100 Subject: [PATCH 064/551] [PATCH] zd1211rw: Make CCK gain patching conditional on RF type The vendor driver code suggests that CR47 patching happens on every channel change for every RF (depending on bit 8 in POD). Due to a bug in their driver (upper bits of RF_Mode get zeroed out, then are examined for 1s when setting some other flags), this isn't actually what happens, and their generic CCK patching routine never takes effect. Some of their RF configurations do include explicit (duplicated) code for CR47 patching though. This patch makes zd1211rw match that behaviour. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 2 +- drivers/net/wireless/zd1211rw/zd_rf.h | 14 ++++++++++++++ drivers/net/wireless/zd1211rw/zd_rf_al2230.c | 1 + drivers/net/wireless/zd1211rw/zd_rf_al7230b.c | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 4a2ceb93aaad..5b624bfc01a6 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1286,7 +1286,7 @@ static int patch_cck_gain(struct zd_chip *chip) int r; u32 value; - if (!chip->patch_cck_gain) + if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf)) return 0; ZD_ASSERT(mutex_is_locked(&chip->mutex)); diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h index 6dced2ae5a11..c6dfd8227f6e 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/drivers/net/wireless/zd1211rw/zd_rf.h @@ -52,6 +52,12 @@ struct zd_rf { * defaults to 1 (yes) */ u8 update_channel_int:1; + /* whether CR47 should be patched from the EEPROM, if the appropriate + * flag is set in the POD. The vendor driver suggests that this should + * be done for all RF's, but a bug in their code prevents but their + * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */ + u8 patch_cck_gain:1; + /* private RF driver data */ void *priv; @@ -84,6 +90,14 @@ static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf) return rf->update_channel_int; } +static inline int zd_rf_should_patch_cck_gain(struct zd_rf *rf) +{ + return rf->patch_cck_gain; +} + +int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel); +int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel); + /* Functions for individual RF chips */ int zd_rf_init_rf2959(struct zd_rf *rf); diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c index 511392acfedf..e7a4ecf7b6e2 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c @@ -432,5 +432,6 @@ int zd_rf_init_al2230(struct zd_rf *rf) rf->switch_radio_on = zd1211_al2230_switch_radio_on; } rf->patch_6m_band_edge = zd_rf_generic_patch_6m; + rf->patch_cck_gain = 1; return 0; } diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c index 5e5e9ddc6a74..f4e8b6ada854 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c @@ -483,6 +483,7 @@ int zd_rf_init_al7230b(struct zd_rf *rf) rf->switch_radio_on = zd1211_al7230b_switch_radio_on; rf->set_channel = zd1211_al7230b_set_channel; rf->patch_6m_band_edge = zd_rf_generic_patch_6m; + rf->patch_cck_gain = 1; } rf->switch_radio_off = al7230b_switch_radio_off; From 77548f58070894cf5970a110981e511ffe793369 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 26 May 2007 22:21:29 -0500 Subject: [PATCH 065/551] [PATCH] bcm43xx: Fix deviation from specifications in set_baseband_attenuation A disagreement between the specifications and the bcm43xx code has just been discovered and is hereby fixed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index b37f1e348700..d779199c30d0 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1638,7 +1638,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, return; } - if (phy->analog > 1) { + if (phy->analog == 1) { value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; value |= (baseband_attenuation << 2) & 0x003C; } else { From 67c4f7aa9e64d37f32eb44d6d093b7028f1060bb Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 27 May 2007 23:27:40 +0900 Subject: [PATCH 066/551] [PATCH] softmac: use list_for_each_entry Cleanup using list_for_each_entry. Cc: Johannes Berg Cc: Joe Jezak Cc: Daniel Drake Signed-off-by: Akinobu Mita Signed-off-by: John W. Linville --- .../softmac/ieee80211softmac_module.c | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index c308756c2f9d..6398e6e67493 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c @@ -456,18 +456,13 @@ void ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *add_net) { - struct list_head *list_ptr; - struct ieee80211softmac_network *softmac_net = NULL; + struct ieee80211softmac_network *softmac_net; - list_for_each(list_ptr, &mac->network_list) { - softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); + list_for_each_entry(softmac_net, &mac->network_list, list) { if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN)) - break; - else - softmac_net = NULL; + return; } - if(softmac_net == NULL) - list_add(&(add_net->list), &mac->network_list); + list_add(&(add_net->list), &mac->network_list); } /* Add a network to the list, with locking */ @@ -506,16 +501,13 @@ struct ieee80211softmac_network * ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac, u8 *bssid) { - struct list_head *list_ptr; - struct ieee80211softmac_network *softmac_net = NULL; - list_for_each(list_ptr, &mac->network_list) { - softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); + struct ieee80211softmac_network *softmac_net; + + list_for_each_entry(softmac_net, &mac->network_list, list) { if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN)) - break; - else - softmac_net = NULL; + return softmac_net; } - return softmac_net; + return NULL; } /* Get a network from the list by BSSID with locking */ @@ -537,11 +529,9 @@ struct ieee80211softmac_network * ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid) { - struct list_head *list_ptr; - struct ieee80211softmac_network *softmac_net = NULL; + struct ieee80211softmac_network *softmac_net; - list_for_each(list_ptr, &mac->network_list) { - softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list); + list_for_each_entry(softmac_net, &mac->network_list, list) { if (softmac_net->essid.len == essid->len && !memcmp(softmac_net->essid.data, essid->data, essid->len)) return softmac_net; From b918099030fe6cc093a7d60a88039bd98f16538e Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Mon, 28 May 2007 09:38:47 -0700 Subject: [PATCH 067/551] [PATCH] hostap: Suppress broadcast if no stations are associated This may be useful in mesh setups when most stations act as repeaters only. Signed-off-by: Pavel Roskin Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_ap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 5b3abd54d0e5..d169529b90bc 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -2704,6 +2704,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) if (hdr->addr1[0] & 0x01) { /* broadcast/multicast frame - no AP related processing */ + if (local->ap->num_sta <= 0) + ret = AP_TX_DROP; goto out; } From c15057313725942c6af8dcb60b4d4322101316d9 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 28 May 2007 09:38:48 -0700 Subject: [PATCH 068/551] [PATCH] hostap: Use list_for_each_entry Use list_for_each_entry() instead of manual iteration and substitute some list_for_each() loops with list_for_each_entry(). Signed-off-by: Matthias Kaehlcke Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_ap.c | 32 ++++++++----------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index d169529b90bc..90900525379c 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -326,7 +326,6 @@ static int ap_control_proc_read(char *page, char **start, off_t off, char *p = page; struct ap_data *ap = (struct ap_data *) data; char *policy_txt; - struct list_head *ptr; struct mac_entry *entry; if (off != 0) { @@ -352,14 +351,12 @@ static int ap_control_proc_read(char *page, char **start, off_t off, p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries); p += sprintf(p, "MAC list:\n"); spin_lock_bh(&ap->mac_restrictions.lock); - for (ptr = ap->mac_restrictions.mac_list.next; - ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) { + list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) { if (p - page > PAGE_SIZE - 80) { p += sprintf(p, "All entries did not fit one page.\n"); break; } - entry = list_entry(ptr, struct mac_entry, list); p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr)); } spin_unlock_bh(&ap->mac_restrictions.lock); @@ -413,7 +410,6 @@ int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac) static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions, u8 *mac) { - struct list_head *ptr; struct mac_entry *entry; int found = 0; @@ -421,10 +417,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions, return 0; spin_lock_bh(&mac_restrictions->lock); - for (ptr = mac_restrictions->mac_list.next; - ptr != &mac_restrictions->mac_list; ptr = ptr->next) { - entry = list_entry(ptr, struct mac_entry, list); - + list_for_each_entry(entry, &mac_restrictions->mac_list, list) { if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { found = 1; break; @@ -519,7 +512,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off, { char *p = page; struct ap_data *ap = (struct ap_data *) data; - struct list_head *ptr; + struct sta_info *sta; int i; if (off > PROC_LIMIT) { @@ -529,9 +522,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off, p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); spin_lock_bh(&ap->sta_table_lock); - for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; - + list_for_each_entry(sta, &ap->sta_list, list) { if (!sta->ap) continue; @@ -861,7 +852,7 @@ void hostap_init_ap_proc(local_info_t *local) void hostap_free_data(struct ap_data *ap) { - struct list_head *n, *ptr; + struct sta_info *n, *sta; if (ap == NULL || !ap->initialized) { printk(KERN_DEBUG "hostap_free_data: ap has not yet been " @@ -875,8 +866,7 @@ void hostap_free_data(struct ap_data *ap) ap->crypt = ap->crypt_priv = NULL; #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - list_for_each_safe(ptr, n, &ap->sta_list) { - struct sta_info *sta = list_entry(ptr, struct sta_info, list); + list_for_each_entry_safe(sta, n, &ap->sta_list, list) { ap_sta_hash_del(ap, sta); list_del(&sta->list); if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) @@ -3200,15 +3190,14 @@ int hostap_update_rx_stats(struct ap_data *ap, void hostap_update_rates(local_info_t *local) { - struct list_head *ptr; + struct sta_info *sta; struct ap_data *ap = local->ap; if (!ap) return; spin_lock_bh(&ap->sta_table_lock); - for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; + list_for_each_entry(sta, &ap->sta_list, list) { prism2_check_tx_rates(sta); } spin_unlock_bh(&ap->sta_table_lock); @@ -3244,11 +3233,10 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, void hostap_add_wds_links(local_info_t *local) { struct ap_data *ap = local->ap; - struct list_head *ptr; + struct sta_info *sta; spin_lock_bh(&ap->sta_table_lock); - list_for_each(ptr, &ap->sta_list) { - struct sta_info *sta = list_entry(ptr, struct sta_info, list); + list_for_each_entry(sta, &ap->sta_list, list) { if (sta->ap) hostap_wds_link_oper(local, sta->addr, WDS_ADD); } From bd5824f138153f407e300728919e814ab7dcfadb Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 28 May 2007 09:38:49 -0700 Subject: [PATCH 069/551] [PATCH] hostap: Remove driver version number The driver version number has not been updated since the driver was included in the main kernel tree and there is no plan on updating this in the future either. At this point, the only correct way to refer to the version is to use the kernel version. The 0.4.4 version is confusing since there are external version with higher version number even though they are not actually any newer than the in-tree version. Let's get rid of the version number in the kernel tree in order to avoid this kind of confusion. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_config.h | 2 -- drivers/net/wireless/hostap/hostap_cs.c | 4 ---- drivers/net/wireless/hostap/hostap_ioctl.c | 2 -- drivers/net/wireless/hostap/hostap_main.c | 1 - drivers/net/wireless/hostap/hostap_pci.c | 5 ----- drivers/net/wireless/hostap/hostap_plx.c | 5 ----- 6 files changed, 19 deletions(-) diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h index c090a5aebb58..30acd39d76a2 100644 --- a/drivers/net/wireless/hostap/hostap_config.h +++ b/drivers/net/wireless/hostap/hostap_config.h @@ -1,8 +1,6 @@ #ifndef HOSTAP_CONFIG_H #define HOSTAP_CONFIG_H -#define PRISM2_VERSION "0.4.4-kernel" - /* In the previous versions of Host AP driver, support for user space version * of IEEE 802.11 management (hostapd) used to be disabled in the default * configuration. From now on, support for hostapd is always included and it is diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index ee1532b62e42..30e723f65979 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -22,7 +22,6 @@ #include "hostap_wlan.h" -static char *version = PRISM2_VERSION " (Jouni Malinen )"; static dev_info_t dev_info = "hostap_cs"; MODULE_AUTHOR("Jouni Malinen"); @@ -30,7 +29,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " "cards (PC Card)."); MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)"); MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); static int ignore_cis_vcc; @@ -910,14 +908,12 @@ static struct pcmcia_driver hostap_driver = { static int __init init_prism2_pccard(void) { - printk(KERN_INFO "%s: %s\n", dev_info, version); return pcmcia_register_driver(&hostap_driver); } static void __exit exit_prism2_pccard(void) { pcmcia_unregister_driver(&hostap_driver); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index cdea7f71b9eb..8c71077d653c 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -3893,8 +3893,6 @@ static void prism2_get_drvinfo(struct net_device *dev, local = iface->local; strncpy(info->driver, "hostap", sizeof(info->driver) - 1); - strncpy(info->version, PRISM2_VERSION, - sizeof(info->version) - 1); snprintf(info->fw_version, sizeof(info->fw_version) - 1, "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff, (local->sta_fw_ver >> 8) & 0xff, diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 4743426cf6ad..446de51bab74 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -37,7 +37,6 @@ MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Host AP common routines"); MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); #define TX_TIMEOUT (2 * HZ) diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index db4899ed4bb1..0cd48d151f5e 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -20,7 +20,6 @@ #include "hostap_wlan.h" -static char *version = PRISM2_VERSION " (Jouni Malinen )"; static char *dev_info = "hostap_pci"; @@ -29,7 +28,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN " "PCI cards."); MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards"); MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); /* struct local_info::hw_priv */ @@ -462,8 +460,6 @@ static struct pci_driver prism2_pci_drv_id = { static int __init init_prism2_pci(void) { - printk(KERN_INFO "%s: %s\n", dev_info, version); - return pci_register_driver(&prism2_pci_drv_id); } @@ -471,7 +467,6 @@ static int __init init_prism2_pci(void) static void __exit exit_prism2_pci(void) { pci_unregister_driver(&prism2_pci_drv_id); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index f0fd5ecdb24d..0183df757b3e 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -23,7 +23,6 @@ #include "hostap_wlan.h" -static char *version = PRISM2_VERSION " (Jouni Malinen )"; static char *dev_info = "hostap_plx"; @@ -32,7 +31,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " "cards (PLX)."); MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)"); MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); static int ignore_cis; @@ -623,8 +621,6 @@ static struct pci_driver prism2_plx_drv_id = { static int __init init_prism2_plx(void) { - printk(KERN_INFO "%s: %s\n", dev_info, version); - return pci_register_driver(&prism2_plx_drv_id); } @@ -632,7 +628,6 @@ static int __init init_prism2_plx(void) static void __exit exit_prism2_plx(void) { pci_unregister_driver(&prism2_plx_drv_id); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } From d796fdb708fc5b10112934cba43e832c36ce4923 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 14 May 2007 18:37:30 -0500 Subject: [PATCH 070/551] s2io: add PCI error recovery support This patch adds PCI error recovery support to the s2io 10-Gigabit ethernet device driver. Third revision, blocks interrupts and the watchdog. Tested, seems to work well. Signed-off-by: Linas Vepstas Acked-by: Ramkrishna Vepa Cc: Raghavendra Koushik Cc: Wen Xiong Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 116 +++++++++++++++++++++++++++++++++++++++++++-- drivers/net/s2io.h | 5 ++ 2 files changed, 116 insertions(+), 5 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 09078ff84cd2..392ad4a42291 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -469,11 +469,18 @@ static struct pci_device_id s2io_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, s2io_tbl); +static struct pci_error_handlers s2io_err_handler = { + .error_detected = s2io_io_error_detected, + .slot_reset = s2io_io_slot_reset, + .resume = s2io_io_resume, +}; + static struct pci_driver s2io_driver = { .name = "S2IO", .id_table = s2io_tbl, .probe = s2io_init_nic, .remove = __devexit_p(s2io_rem_nic), + .err_handler = &s2io_err_handler, }; /* A simplifier macro used both by init and free shared_mem Fns(). */ @@ -2689,6 +2696,9 @@ static void s2io_netpoll(struct net_device *dev) u64 val64 = 0xFFFFFFFFFFFFFFFFULL; int i; + if (pci_channel_offline(nic->pdev)) + return; + disable_irq(dev->irq); atomic_inc(&nic->isr_cnt); @@ -3215,6 +3225,8 @@ static void alarm_intr_handler(struct s2io_nic *nic) int i; if (atomic_read(&nic->card_state) == CARD_DOWN) return; + if (pci_channel_offline(nic->pdev)) + return; nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; /* Handling the XPAK counters update */ if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { @@ -4314,6 +4326,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) struct mac_info *mac_control; struct config_param *config; + /* Pretend we handled any irq's from a disconnected card */ + if (pci_channel_offline(sp->pdev)) + return IRQ_NONE; + atomic_inc(&sp->isr_cnt); mac_control = &sp->mac_control; config = &sp->config; @@ -6569,7 +6585,7 @@ static void s2io_rem_isr(struct s2io_nic * sp) } while(cnt < 5); } -static void s2io_card_down(struct s2io_nic * sp) +static void do_s2io_card_down(struct s2io_nic * sp, int do_io) { int cnt = 0; struct XENA_dev_config __iomem *bar0 = sp->bar0; @@ -6584,7 +6600,8 @@ static void s2io_card_down(struct s2io_nic * sp) atomic_set(&sp->card_state, CARD_DOWN); /* disable Tx and Rx traffic on the NIC */ - stop_nic(sp); + if (do_io) + stop_nic(sp); s2io_rem_isr(sp); @@ -6592,7 +6609,7 @@ static void s2io_card_down(struct s2io_nic * sp) tasklet_kill(&sp->task); /* Check if the device is Quiescent and then Reset the NIC */ - do { + while(do_io) { /* As per the HW requirement we need to replenish the * receive buffer to avoid the ring bump. Since there is * no intention of processing the Rx frame at this pointwe are @@ -6617,8 +6634,9 @@ static void s2io_card_down(struct s2io_nic * sp) (unsigned long long) val64); break; } - } while (1); - s2io_reset(sp); + } + if (do_io) + s2io_reset(sp); spin_lock_irqsave(&sp->tx_lock, flags); /* Free all Tx buffers */ @@ -6633,6 +6651,11 @@ static void s2io_card_down(struct s2io_nic * sp) clear_bit(0, &(sp->link_state)); } +static void s2io_card_down(struct s2io_nic * sp) +{ + do_s2io_card_down(sp, 1); +} + static int s2io_card_up(struct s2io_nic * sp) { int i, ret = 0; @@ -8010,3 +8033,86 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; return; } + +/** + * s2io_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci conneection state + * + * This function is called after a PCI bus error affecting + * this device has been detected. + */ +static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct s2io_nic *sp = netdev->priv; + + netif_device_detach(netdev); + + if (netif_running(netdev)) { + /* Bring down the card, while avoiding PCI I/O */ + do_s2io_card_down(sp, 0); + sp->device_close_flag = TRUE; /* Device is shut down. */ + } + pci_disable_device(pdev); + + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * s2io_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + * At this point, the card has exprienced a hard reset, + * followed by fixups by BIOS, and has its config space + * set up identically to what it was at cold boot. + */ +static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct s2io_nic *sp = netdev->priv; + + if (pci_enable_device(pdev)) { + printk(KERN_ERR "s2io: " + "Cannot re-enable PCI device after reset.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + + pci_set_master(pdev); + s2io_reset(sp); + + return PCI_ERS_RESULT_RECOVERED; +} + +/** + * s2io_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells + * us that its OK to resume normal operation. + */ +static void s2io_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct s2io_nic *sp = netdev->priv; + + if (netif_running(netdev)) { + if (s2io_card_up(sp)) { + printk(KERN_ERR "s2io: " + "Can't bring device back up after reset.\n"); + return; + } + + if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) { + s2io_card_down(sp); + printk(KERN_ERR "s2io: " + "Can't resetore mac addr after reset.\n"); + return; + } + } + + netif_device_attach(netdev); + netif_wake_queue(netdev); +} diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 54baa0b8ec7c..b9b660702abd 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -1052,6 +1052,11 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, struct sk_buff *skb, u32 tcp_len); static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring); +static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state); +static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev); +static void s2io_io_resume(struct pci_dev *pdev); + #define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size #define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size #define s2io_offload_type(skb) skb_shinfo(skb)->gso_type From 146bd683cc160d728f1f62a6ddade8451801a8c3 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 14 May 2007 18:41:41 -0500 Subject: [PATCH 071/551] s2io: add PCI error recovery support s2io cleanup suggestions, per discussion on mailing lists. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 -- drivers/net/s2io.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 392ad4a42291..2d826fff7e2e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3970,7 +3970,6 @@ static int s2io_close(struct net_device *dev) /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); - sp->device_close_flag = TRUE; /* Device is shut down. */ return 0; } @@ -8053,7 +8052,6 @@ static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev, if (netif_running(netdev)) { /* Bring down the card, while avoiding PCI I/O */ do_s2io_card_down(sp, 0); - sp->device_close_flag = TRUE; /* Device is shut down. */ } pci_disable_device(pdev); diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index b9b660702abd..58592780f519 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -794,7 +794,6 @@ struct s2io_nic { struct net_device_stats stats; int high_dma_flag; - int device_close_flag; int device_enabled_once; char name[60]; From 0cefeebaf3da39d768bffcf62460fe2088e824ef Mon Sep 17 00:00:00 2001 From: Michael Barkowski Date: Fri, 11 May 2007 18:24:51 -0500 Subject: [PATCH 072/551] phylib: add the ICPlus IP175C PHY driver The ICPlus IP175C sports a 100Mbit/s 4-port switch in addition to a dedicated 100Mbit/s WAN port. Signed-off-by: Michael Barkowski Signed-off-by: Kim Phillips Signed-off-by: Jeff Garzik --- drivers/net/phy/Kconfig | 5 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/icplus.c | 134 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 drivers/net/phy/icplus.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 09b6f259eb92..dd09011c7ee5 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -55,6 +55,11 @@ config BROADCOM_PHY ---help--- Currently supports the BCM5411, BCM5421 and BCM5461 PHYs. +config ICPLUS_PHY + tristate "Drivers for ICPlus PHYs" + ---help--- + Currently supports the IP175C PHY. + config FIXED_PHY tristate "Drivers for PHY emulation on fixed speed/link" ---help--- diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index bcd1efbd2a18..8885650647ff 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o obj-$(CONFIG_SMSC_PHY) += smsc.o obj-$(CONFIG_VITESSE_PHY) += vitesse.o obj-$(CONFIG_BROADCOM_PHY) += broadcom.o +obj-$(CONFIG_ICPLUS_PHY) += icplus.o obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c new file mode 100644 index 000000000000..af3f1f2a9f87 --- /dev/null +++ b/drivers/net/phy/icplus.c @@ -0,0 +1,134 @@ +/* + * Driver for ICPlus PHYs + * + * Copyright (c) 2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); +MODULE_AUTHOR("Michael Barkowski"); +MODULE_LICENSE("GPL"); + +static int ip175c_config_init(struct phy_device *phydev) +{ + int err, i; + static int full_reset_performed = 0; + + if (full_reset_performed == 0) { + + /* master reset */ + err = phydev->bus->write(phydev->bus, 30, 0, 0x175c); + if (err < 0) + return err; + + /* ensure no bus delays overlap reset period */ + err = phydev->bus->read(phydev->bus, 30, 0); + + /* data sheet specifies reset period is 2 msec */ + mdelay(2); + + /* enable IP175C mode */ + err = phydev->bus->write(phydev->bus, 29, 31, 0x175c); + if (err < 0) + return err; + + /* Set MII0 speed and duplex (in PHY mode) */ + err = phydev->bus->write(phydev->bus, 29, 22, 0x420); + if (err < 0) + return err; + + /* reset switch ports */ + for (i = 0; i < 5; i++) { + err = phydev->bus->write(phydev->bus, i, + MII_BMCR, BMCR_RESET); + if (err < 0) + return err; + } + + for (i = 0; i < 5; i++) + err = phydev->bus->read(phydev->bus, i, MII_BMCR); + + mdelay(2); + + full_reset_performed = 1; + } + + if (phydev->addr != 4) { + phydev->state = PHY_RUNNING; + phydev->speed = SPEED_100; + phydev->duplex = DUPLEX_FULL; + phydev->link = 1; + netif_carrier_on(phydev->attached_dev); + } + + return 0; +} + +static int ip175c_read_status(struct phy_device *phydev) +{ + if (phydev->addr == 4) /* WAN port */ + genphy_read_status(phydev); + else + /* Don't need to read status for switch ports */ + phydev->irq = PHY_IGNORE_INTERRUPT; + + return 0; +} + +static int ip175c_config_aneg(struct phy_device *phydev) +{ + if (phydev->addr == 4) /* WAN port */ + genphy_config_aneg(phydev); + + return 0; +} + +static struct phy_driver ip175c_driver = { + .phy_id = 0x02430d80, + .name = "ICPlus IP175C", + .phy_id_mask = 0x0ffffff0, + .features = PHY_BASIC_FEATURES, + .config_init = &ip175c_config_init, + .config_aneg = &ip175c_config_aneg, + .read_status = &ip175c_read_status, + .driver = { .owner = THIS_MODULE,}, +}; + +static int __init ip175c_init(void) +{ + return phy_driver_register(&ip175c_driver); +} + +static void __exit ip175c_exit(void) +{ + phy_driver_unregister(&ip175c_driver); +} + +module_init(ip175c_init); +module_exit(ip175c_exit); From d3c12873c36005263286cf5660663c8c10f9d2b5 Mon Sep 17 00:00:00 2001 From: Kapil Juneja Date: Fri, 11 May 2007 18:25:11 -0500 Subject: [PATCH 073/551] gianfar: add support for SGMII Add code for initialising and configuring TBI interface and programming it for connecting to on-chip SERDES (Lynx PHY) in case of SGMII mode selected through HRCW at reset. also add defines for TBI register configuration. TBI interface is programmed towards the SERDES. refactored mdio read/write functions to differentiate programming local interface MII regs (e.g., for TBI) from always programming the mdio master (TSEC1, for programming the PHYs). Signed-off-by: Kapil Juneja Signed-off-by: Andy Fleming Signed-off-by: Kim Phillips Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 27 +++++++++++++++++++ drivers/net/gianfar.h | 6 +++++ drivers/net/gianfar_mii.c | 55 +++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1b854bf07b09..d7a1a58de766 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -130,6 +130,9 @@ static int gfar_remove(struct platform_device *pdev); static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); +static void gfar_configure_serdes(struct net_device *dev); +extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value); +extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum); #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct net_device *dev, int *budget); #endif @@ -451,6 +454,9 @@ static int init_phy(struct net_device *dev) phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); + if (interface == PHY_INTERFACE_MODE_SGMII) + gfar_configure_serdes(dev); + if (IS_ERR(phydev)) { printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); return PTR_ERR(phydev); @@ -465,6 +471,27 @@ static int init_phy(struct net_device *dev) return 0; } +static void gfar_configure_serdes(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + struct gfar_mii __iomem *regs = + (void __iomem *)&priv->regs->gfar_mii_regs; + + /* Initialise TBI i/f to communicate with serdes (lynx phy) */ + + /* Single clk mode, mii mode off(for aerdes communication) */ + gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT); + + /* Supported pause and full-duplex, no half-duplex */ + gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE, + ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | + ADVERTISE_1000XPSE_ASYM); + + /* ANEG enable, restart ANEG, full duplex mode, speed[1] set */ + gfar_local_mdio_write(regs, TBIPA_VALUE, MII_BMCR, BMCR_ANENABLE | + BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); +} + static void init_registers(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 39e9e321fcbc..d8e779c102fa 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -136,6 +136,12 @@ extern const char gfar_driver_version[]; #define MIIMCFG_RESET 0x80000000 #define MIIMIND_BUSY 0x00000001 +/* TBI register addresses */ +#define MII_TBICON 0x11 + +/* TBICON register bit fields */ +#define TBICON_CLK_SELECT 0x0020 + /* MAC register bits */ #define MACCFG1_SOFT_RESET 0x80000000 #define MACCFG1_RESET_RX_MC 0x00080000 diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index bcc6b82f4a33..5dd34a1a7b89 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -43,13 +43,18 @@ #include "gianfar.h" #include "gianfar_mii.h" -/* Write value to the PHY at mii_id at register regnum, - * on the bus, waiting until the write is done before returning. - * All PHY configuration is done through the TSEC1 MIIM regs */ -int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) +/* + * Write value to the PHY at mii_id at register regnum, + * on the bus attached to the local interface, which may be different from the + * generic mdio bus (tied to a single interface), waiting until the write is + * done before returning. This is helpful in programming interfaces like + * the TBI which control interfaces like onchip SERDES and are always tied to + * the local mdio pins, which may not be the same as system mdio bus, used for + * controlling the external PHYs, for example. + */ +int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, + int regnum, u16 value) { - struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; - /* Set the PHY address and the register address we want to write */ gfar_write(®s->miimadd, (mii_id << 8) | regnum); @@ -63,12 +68,19 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) return 0; } -/* Read the bus for PHY at addr mii_id, register regnum, and - * return the value. Clears miimcom first. All PHY - * configuration has to be done through the TSEC1 MIIM regs */ -int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +/* + * Read the bus for PHY at addr mii_id, register regnum, and + * return the value. Clears miimcom first. All PHY operation + * done on the bus attached to the local interface, + * which may be different from the generic mdio bus + * This is helpful in programming interfaces like + * the TBI which, inturn, control interfaces like onchip SERDES + * and are always tied to the local mdio pins, which may not be the + * same as system mdio bus, used for controlling the external PHYs, for eg. + */ +int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum) + { - struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; u16 value; /* Set the PHY address and the register address we want to read */ @@ -88,6 +100,27 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) return value; } +/* Write value to the PHY at mii_id at register regnum, + * on the bus, waiting until the write is done before returning. + * All PHY configuration is done through the TSEC1 MIIM regs */ +int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) +{ + struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; + + /* Write to the local MII regs */ + return(gfar_local_mdio_write(regs, mii_id, regnum, value)); +} + +/* Read the bus for PHY at addr mii_id, register regnum, and + * return the value. Clears miimcom first. All PHY + * configuration has to be done through the TSEC1 MIIM regs */ +int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +{ + struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; + + /* Read the local MII regs */ + return(gfar_local_mdio_read(regs, mii_id, regnum)); +} /* Reset the MIIM registers, and wait for the bus to free */ int gfar_mdio_reset(struct mii_bus *bus) From 4117b5be4b877cec7c34058f0c239fcf78274e3d Mon Sep 17 00:00:00 2001 From: Kapil Juneja Date: Fri, 11 May 2007 18:25:18 -0500 Subject: [PATCH 074/551] phylib: m88e1111: enable SGMII mode If connected via SGMII, initialize with SGMII mode configured. Signed-off-by: Kapil Juneja Signed-off-by: Andy Fleming Signed-off-by: Kim Phillips Signed-off-by: Jeff Garzik --- drivers/net/phy/marvell.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index b87f8d2a888b..fbe1104e9a07 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -60,6 +60,7 @@ #define MII_M1111_PHY_EXT_SR 0x1b #define MII_M1111_HWCFG_MODE_MASK 0xf #define MII_M1111_HWCFG_MODE_RGMII 0xb +#define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 MODULE_DESCRIPTION("Marvell PHY driver"); MODULE_AUTHOR("Andy Fleming"); @@ -169,6 +170,21 @@ static int m88e1111_config_init(struct phy_device *phydev) return err; } + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + int temp; + + temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); + if (temp < 0) + return temp; + + temp &= ~(MII_M1111_HWCFG_MODE_MASK); + temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; + + err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); + if (err < 0) + return err; + } + err = phy_write(phydev, MII_BMCR, BMCR_RESET); if (err < 0) return err; From 2501f843b051621c5a6df7a092a64dfd78b201f7 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 19 May 2007 22:26:40 +0200 Subject: [PATCH 075/551] 8139cp: Convert to generic boolean Signed-off-by: Richard Knutsson Signed-off-by: Jeff Garzik --- drivers/net/8139cp.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index a804965e6542..58bbc3e6d0de 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -107,11 +107,6 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered mu #define PFX DRV_NAME ": " -#ifndef TRUE -#define FALSE 0 -#define TRUE (!FALSE) -#endif - #define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ NETIF_MSG_PROBE | \ NETIF_MSG_LINK) @@ -661,7 +656,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) if (status & (TxOK | TxErr | TxEmpty | SWInt)) cp_tx(cp); if (status & LinkChg) - mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), false); spin_unlock(&cp->lock); @@ -1188,7 +1183,7 @@ static int cp_open (struct net_device *dev) goto err_out_hw; netif_carrier_off(dev); - mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), true); netif_start_queue(dev); return 0; @@ -2050,7 +2045,7 @@ static int cp_resume (struct pci_dev *pdev) spin_lock_irqsave (&cp->lock, flags); - mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), false); spin_unlock_irqrestore (&cp->lock, flags); From 18ab458fb7bd5c64bef766090020648266cfa9b6 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 25 May 2007 12:31:32 -0700 Subject: [PATCH 076/551] usbnet whitespace fixes Whitespace updates for usbnet core, mostly switching to tab-only indents. Signed-off-by: David Brownell Signed-off-by: Jeff Garzik --- drivers/net/usb/usbnet.c | 76 +++++++++++++++++++++------------------- drivers/net/usb/usbnet.h | 10 +++--- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index a12f576391cf..86b690843362 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -192,7 +192,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf) usb_pipeendpoint(pipe), maxp, period); } } - return 0; + return 0; } /* Passes this packet up the stack, updating its accounting. @@ -326,7 +326,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) if (netif_running (dev->net) && netif_device_present (dev->net) && !test_bit (EVENT_RX_HALT, &dev->flags)) { - switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ + switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { case -EPIPE: usbnet_defer_kevent (dev, EVENT_RX_HALT); break; @@ -393,8 +393,8 @@ static void rx_complete (struct urb *urb) entry->urb = NULL; switch (urb_status) { - // success - case 0: + /* success */ + case 0: if (skb->len < dev->net->hard_header_len) { entry->state = rx_cleanup; dev->stats.rx_errors++; @@ -404,28 +404,30 @@ static void rx_complete (struct urb *urb) } break; - // stalls need manual reset. this is rare ... except that - // when going through USB 2.0 TTs, unplug appears this way. - // we avoid the highspeed version of the ETIMEOUT/EILSEQ - // storm, recovering as needed. - case -EPIPE: + /* stalls need manual reset. this is rare ... except that + * when going through USB 2.0 TTs, unplug appears this way. + * we avoid the highspeed version of the ETIMEOUT/EILSEQ + * storm, recovering as needed. + */ + case -EPIPE: dev->stats.rx_errors++; usbnet_defer_kevent (dev, EVENT_RX_HALT); // FALLTHROUGH - // software-driven interface shutdown - case -ECONNRESET: // async unlink - case -ESHUTDOWN: // hardware gone + /* software-driven interface shutdown */ + case -ECONNRESET: /* async unlink */ + case -ESHUTDOWN: /* hardware gone */ if (netif_msg_ifdown (dev)) devdbg (dev, "rx shutdown, code %d", urb_status); goto block; - // we get controller i/o faults during khubd disconnect() delays. - // throttle down resubmits, to avoid log floods; just temporarily, - // so we still recover when the fault isn't a khubd delay. - case -EPROTO: - case -ETIME: - case -EILSEQ: + /* we get controller i/o faults during khubd disconnect() delays. + * throttle down resubmits, to avoid log floods; just temporarily, + * so we still recover when the fault isn't a khubd delay. + */ + case -EPROTO: + case -ETIME: + case -EILSEQ: dev->stats.rx_errors++; if (!timer_pending (&dev->delay)) { mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); @@ -438,12 +440,12 @@ block: urb = NULL; break; - // data overrun ... flush fifo? - case -EOVERFLOW: + /* data overrun ... flush fifo? */ + case -EOVERFLOW: dev->stats.rx_over_errors++; // FALLTHROUGH - default: + default: entry->state = rx_cleanup; dev->stats.rx_errors++; if (netif_msg_rx_err (dev)) @@ -471,22 +473,22 @@ static void intr_complete (struct urb *urb) int status = urb->status; switch (status) { - /* success */ - case 0: + /* success */ + case 0: dev->driver_info->status(dev, urb); break; - /* software-driven interface shutdown */ - case -ENOENT: // urb killed - case -ESHUTDOWN: // hardware gone + /* software-driven interface shutdown */ + case -ENOENT: /* urb killed */ + case -ESHUTDOWN: /* hardware gone */ if (netif_msg_ifdown (dev)) devdbg (dev, "intr shutdown, code %d", status); return; - /* NOTE: not throttling like RX/TX, since this endpoint - * already polls infrequently - */ - default: + /* NOTE: not throttling like RX/TX, since this endpoint + * already polls infrequently + */ + default: devdbg (dev, "intr status %d", status); break; } @@ -569,9 +571,9 @@ static int usbnet_stop (struct net_device *net) temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); // maybe wait for deletions to finish. - while (!skb_queue_empty(&dev->rxq) && - !skb_queue_empty(&dev->txq) && - !skb_queue_empty(&dev->done)) { + while (!skb_queue_empty(&dev->rxq) + && !skb_queue_empty(&dev->txq) + && !skb_queue_empty(&dev->done)) { msleep(UNLINK_TIMEOUT_MS); if (netif_msg_ifdown (dev)) devdbg (dev, "waited for %d urb completions", temp); @@ -1011,16 +1013,16 @@ static void usbnet_bh (unsigned long param) while ((skb = skb_dequeue (&dev->done))) { entry = (struct skb_data *) skb->cb; switch (entry->state) { - case rx_done: + case rx_done: entry->state = rx_cleanup; rx_process (dev, skb); continue; - case tx_done: - case rx_cleanup: + case tx_done: + case rx_cleanup: usb_free_urb (entry->urb); dev_kfree_skb (skb); continue; - default: + default: devdbg (dev, "bogus skb state %d", entry->state); } } diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h index a3f8b9e7bc00..a6c5820767de 100644 --- a/drivers/net/usb/usbnet.h +++ b/drivers/net/usb/usbnet.h @@ -47,7 +47,7 @@ struct usbnet { unsigned long data [5]; u32 xid; u32 hard_mtu; /* count any extra framing */ - size_t rx_urb_size; /* size for rx urbs */ + size_t rx_urb_size; /* size for rx urbs */ struct mii_if_info mii; /* various kinds of pending driver work */ @@ -85,7 +85,7 @@ struct driver_info { #define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */ #define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */ -#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ +#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); @@ -146,9 +146,9 @@ extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *); /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ - |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ - |USB_CDC_PACKET_TYPE_PROMISCUOUS \ - |USB_CDC_PACKET_TYPE_DIRECTED) + |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ + |USB_CDC_PACKET_TYPE_PROMISCUOUS \ + |USB_CDC_PACKET_TYPE_DIRECTED) /* we record the state for each of our queued skbs */ From 40738f3fcdb951fb8ade286dc1ea05812acc94db Mon Sep 17 00:00:00 2001 From: Komuro Date: Sun, 27 May 2007 08:57:58 +0900 Subject: [PATCH 077/551] PCMCIA-NETDEV : add new ID of lan&modem multifunction card fmvj18x_cs: NEC PK-UG-J001 Panasonic CF-VML201 Panasonic TO-PDL9610 pcnet_cs: MICRO-RESEARCH MC336LAN Signed-off-by: Komuro Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/fmvj18x_cs.c | 23 ++++++++++++++++++++++- drivers/net/pcmcia/pcnet_cs.c | 1 + drivers/serial/serial_cs.c | 4 ++++ include/pcmcia/ciscode.h | 2 ++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 3f93d4933235..85d5f2ca4bb5 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -109,7 +109,7 @@ static const struct ethtool_ops netdev_ethtool_ops; card type */ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, - XXX10304 + XXX10304, NEC, KME } cardtype_t; /* @@ -374,6 +374,18 @@ static int fmvj18x_config(struct pcmcia_device *link) link->io.NumPorts2 = 8; } break; + case MANFID_NEC: + cardtype = NEC; /* MultiFunction Card */ + link->conf.ConfigBase = 0x800; + link->conf.ConfigIndex = 0x47; + link->io.NumPorts2 = 8; + break; + case MANFID_KME: + cardtype = KME; /* MultiFunction Card */ + link->conf.ConfigBase = 0x800; + link->conf.ConfigIndex = 0x47; + link->io.NumPorts2 = 8; + break; case MANFID_CONTEC: cardtype = CONTEC; break; @@ -450,6 +462,8 @@ static int fmvj18x_config(struct pcmcia_device *link) case TDK: case LA501: case CONTEC: + case NEC: + case KME: tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); @@ -469,6 +483,10 @@ static int fmvj18x_config(struct pcmcia_device *link) card_name = "TDK LAK-CD021"; } else if( cardtype == LA501 ) { card_name = "LA501"; + } else if( cardtype == NEC ) { + card_name = "PK-UG-J001"; + } else if( cardtype == KME ) { + card_name = "Panasonic"; } else { card_name = "C-NET(PC)C"; } @@ -678,8 +696,11 @@ static struct pcmcia_device_id fmvj18x_ids[] = { PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da), PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080), PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), + PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index d88e9b2e93cf..61f7a4f3ee65 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1552,6 +1552,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 6b76babc7fbf..a0ea43598515 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -842,12 +842,16 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h index eae7e2e84497..ad6e278ba7f2 100644 --- a/include/pcmcia/ciscode.h +++ b/include/pcmcia/ciscode.h @@ -126,4 +126,6 @@ #define MANFID_POSSIO 0x030c #define PRODID_POSSIO_GCC 0x0003 +#define MANFID_NEC 0x0010 + #endif /* _LINUX_CISCODE_H */ From 287aa83dffd1b39859f49d73b0d67f57106de5f1 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Wed, 30 May 2007 03:59:02 -0400 Subject: [PATCH 078/551] drivers/net: fix comparisons of unsigned < 0 Recent gcc versions emit warnings when unsigned variables are compared < 0 or >= 0. Signed-off-by: Bill Nottingham Signed-off-by: Jeff Garzik --- drivers/net/mlx4/qp.c | 3 +-- drivers/net/netxen/netxen_nic_niu.c | 6 +++--- drivers/net/tulip/de2104x.c | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c index 7f8b7d55b6e1..492cfaaaa75c 100644 --- a/drivers/net/mlx4/qp.c +++ b/drivers/net/mlx4/qp.c @@ -113,8 +113,7 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, struct mlx4_cmd_mailbox *mailbox; int ret = 0; - if (cur_state < 0 || cur_state >= MLX4_QP_NUM_STATE || - new_state < 0 || cur_state >= MLX4_QP_NUM_STATE || + if (cur_state >= MLX4_QP_NUM_STATE || cur_state >= MLX4_QP_NUM_STATE || !op[cur_state][new_state]) return -EINVAL; diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 75102d30730f..05e0577a0e10 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -724,7 +724,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) __u32 mac_cfg0; u32 port = physical_port[adapter->portnum]; - if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + if (port > NETXEN_NIU_MAX_GBE_PORTS) return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); @@ -757,7 +757,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, __u32 reg; u32 port = physical_port[adapter->portnum]; - if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) + if (port > NETXEN_NIU_MAX_GBE_PORTS) return -EINVAL; /* save previous contents */ @@ -894,7 +894,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, __u32 reg; u32 port = physical_port[adapter->portnum]; - if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) + if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; if (netxen_nic_hw_read_wx(adapter, diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 861729806dc1..d380e0b3f05a 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -785,7 +785,6 @@ static void __de_set_rx_mode (struct net_device *dev) de->tx_head = NEXT_TX(entry); - BUG_ON(TX_BUFFS_AVAIL(de) < 0); if (TX_BUFFS_AVAIL(de) == 0) netif_stop_queue(dev); From cf992af561cc3ba72d79582535e6262818b00548 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 30 May 2007 21:10:47 -0700 Subject: [PATCH 079/551] cxgb3 - sge page management Streamline sge page management. Fix dma mappings when buffers are recycled. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/adapter.h | 38 ++-- drivers/net/cxgb3/sge.c | 423 ++++++++++++++++++------------------ 2 files changed, 232 insertions(+), 229 deletions(-) diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 80c3d8f268a7..ab72563b81ee 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -71,27 +71,29 @@ enum { /* adapter flags */ QUEUES_BOUND = (1 << 3), }; +struct fl_pg_chunk { + struct page *page; + void *va; + unsigned int offset; +}; + struct rx_desc; struct rx_sw_desc; -struct sge_fl_page { - struct skb_frag_struct frag; - unsigned char *va; -}; - -struct sge_fl { /* SGE per free-buffer list state */ - unsigned int buf_size; /* size of each Rx buffer */ - unsigned int credits; /* # of available Rx buffers */ - unsigned int size; /* capacity of free list */ - unsigned int cidx; /* consumer index */ - unsigned int pidx; /* producer index */ - unsigned int gen; /* free list generation */ - unsigned int cntxt_id; /* SGE context id for the free list */ - struct sge_fl_page page; - struct rx_desc *desc; /* address of HW Rx descriptor ring */ - struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */ - dma_addr_t phys_addr; /* physical address of HW ring start */ - unsigned long empty; /* # of times queue ran out of buffers */ +struct sge_fl { /* SGE per free-buffer list state */ + unsigned int buf_size; /* size of each Rx buffer */ + unsigned int credits; /* # of available Rx buffers */ + unsigned int size; /* capacity of free list */ + unsigned int cidx; /* consumer index */ + unsigned int pidx; /* producer index */ + unsigned int gen; /* free list generation */ + struct fl_pg_chunk pg_chunk;/* page chunk cache */ + unsigned int use_pages; /* whether FL uses pages or sk_buffs */ + struct rx_desc *desc; /* address of HW Rx descriptor ring */ + struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */ + dma_addr_t phys_addr; /* physical address of HW ring start */ + unsigned int cntxt_id; /* SGE context id for the free list */ + unsigned long empty; /* # of times queue ran out of buffers */ unsigned long alloc_failed; /* # of times buffer allocation failed */ }; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index a60ec4d4707c..a2cfd68ac757 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -46,23 +46,16 @@ #define SGE_RX_SM_BUF_SIZE 1536 -/* - * If USE_RX_PAGE is defined, the small freelist populated with (partial) - * pages instead of skbs. Pages are carved up into RX_PAGE_SIZE chunks (must - * be a multiple of the host page size). - */ -#define USE_RX_PAGE -#define RX_PAGE_SIZE 2048 - -/* - * skb freelist packets are copied into a new skb (and the freelist one is - * reused) if their len is <= - */ #define SGE_RX_COPY_THRES 256 +#define SGE_RX_PULL_LEN 128 /* - * Minimum number of freelist entries before we start dropping TUNNEL frames. + * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks. + * It must be a divisor of PAGE_SIZE. If set to 0 FL0 will use sk_buffs + * directly. */ +#define FL0_PG_CHUNK_SIZE 2048 + #define SGE_RX_DROP_THRES 16 /* @@ -100,12 +93,12 @@ struct tx_sw_desc { /* SW state per Tx descriptor */ struct sk_buff *skb; }; -struct rx_sw_desc { /* SW state per Rx descriptor */ +struct rx_sw_desc { /* SW state per Rx descriptor */ union { struct sk_buff *skb; - struct sge_fl_page page; - } t; - DECLARE_PCI_UNMAP_ADDR(dma_addr); + struct fl_pg_chunk pg_chunk; + }; + DECLARE_PCI_UNMAP_ADDR(dma_addr); }; struct rsp_desc { /* response queue descriptor */ @@ -351,27 +344,26 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q) pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr), q->buf_size, PCI_DMA_FROMDEVICE); - - if (q->buf_size != RX_PAGE_SIZE) { - kfree_skb(d->t.skb); - d->t.skb = NULL; + if (q->use_pages) { + put_page(d->pg_chunk.page); + d->pg_chunk.page = NULL; } else { - if (d->t.page.frag.page) - put_page(d->t.page.frag.page); - d->t.page.frag.page = NULL; + kfree_skb(d->skb); + d->skb = NULL; } if (++cidx == q->size) cidx = 0; } - if (q->page.frag.page) - put_page(q->page.frag.page); - q->page.frag.page = NULL; + if (q->pg_chunk.page) { + __free_page(q->pg_chunk.page); + q->pg_chunk.page = NULL; + } } /** * add_one_rx_buf - add a packet buffer to a free-buffer list - * @va: va of the buffer to add + * @va: buffer start VA * @len: the buffer length * @d: the HW Rx descriptor to write * @sd: the SW Rx descriptor to write @@ -381,7 +373,7 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q) * Add a buffer of the given length to the supplied HW and SW Rx * descriptors. */ -static inline void add_one_rx_buf(unsigned char *va, unsigned int len, +static inline void add_one_rx_buf(void *va, unsigned int len, struct rx_desc *d, struct rx_sw_desc *sd, unsigned int gen, struct pci_dev *pdev) { @@ -397,6 +389,27 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len, d->gen2 = cpu_to_be32(V_FLD_GEN2(gen)); } +static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp) +{ + if (!q->pg_chunk.page) { + q->pg_chunk.page = alloc_page(gfp); + if (unlikely(!q->pg_chunk.page)) + return -ENOMEM; + q->pg_chunk.va = page_address(q->pg_chunk.page); + q->pg_chunk.offset = 0; + } + sd->pg_chunk = q->pg_chunk; + + q->pg_chunk.offset += q->buf_size; + if (q->pg_chunk.offset == PAGE_SIZE) + q->pg_chunk.page = NULL; + else { + q->pg_chunk.va += q->buf_size; + get_page(q->pg_chunk.page); + } + return 0; +} + /** * refill_fl - refill an SGE free-buffer list * @adapter: the adapter @@ -410,49 +423,29 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len, */ static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) { + void *buf_start; struct rx_sw_desc *sd = &q->sdesc[q->pidx]; struct rx_desc *d = &q->desc[q->pidx]; - struct sge_fl_page *p = &q->page; while (n--) { - unsigned char *va; - - if (unlikely(q->buf_size != RX_PAGE_SIZE)) { - struct sk_buff *skb = alloc_skb(q->buf_size, gfp); - - if (!skb) { - q->alloc_failed++; + if (q->use_pages) { + if (unlikely(alloc_pg_chunk(q, sd, gfp))) { +nomem: q->alloc_failed++; break; } - va = skb->data; - sd->t.skb = skb; + buf_start = sd->pg_chunk.va; } else { - if (!p->frag.page) { - p->frag.page = alloc_pages(gfp, 0); - if (unlikely(!p->frag.page)) { - q->alloc_failed++; - break; - } else { - p->frag.size = RX_PAGE_SIZE; - p->frag.page_offset = 0; - p->va = page_address(p->frag.page); - } - } + struct sk_buff *skb = alloc_skb(q->buf_size, gfp); - memcpy(&sd->t, p, sizeof(*p)); - va = p->va; + if (!skb) + goto nomem; - p->frag.page_offset += RX_PAGE_SIZE; - BUG_ON(p->frag.page_offset > PAGE_SIZE); - p->va += RX_PAGE_SIZE; - if (p->frag.page_offset == PAGE_SIZE) - p->frag.page = NULL; - else - get_page(p->frag.page); + sd->skb = skb; + buf_start = skb->data; } - add_one_rx_buf(va, q->buf_size, d, sd, q->gen, adap->pdev); - + add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen, + adap->pdev); d++; sd++; if (++q->pidx == q->size) { @@ -487,7 +480,7 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q, struct rx_desc *from = &q->desc[idx]; struct rx_desc *to = &q->desc[q->pidx]; - memcpy(&q->sdesc[q->pidx], &q->sdesc[idx], sizeof(struct rx_sw_desc)); + q->sdesc[q->pidx] = q->sdesc[idx]; to->addr_lo = from->addr_lo; /* already big endian */ to->addr_hi = from->addr_hi; /* likewise */ wmb(); @@ -649,6 +642,132 @@ static inline unsigned int flits_to_desc(unsigned int n) return flit_desc_map[n]; } +/** + * get_packet - return the next ingress packet buffer from a free list + * @adap: the adapter that received the packet + * @fl: the SGE free list holding the packet + * @len: the packet length including any SGE padding + * @drop_thres: # of remaining buffers before we start dropping packets + * + * Get the next packet from a free list and complete setup of the + * sk_buff. If the packet is small we make a copy and recycle the + * original buffer, otherwise we use the original buffer itself. If a + * positive drop threshold is supplied packets are dropped and their + * buffers recycled if (a) the number of remaining buffers is under the + * threshold and the packet is too big to copy, or (b) the packet should + * be copied but there is no memory for the copy. + */ +static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl, + unsigned int len, unsigned int drop_thres) +{ + struct sk_buff *skb = NULL; + struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; + + prefetch(sd->skb->data); + fl->credits--; + + if (len <= SGE_RX_COPY_THRES) { + skb = alloc_skb(len, GFP_ATOMIC); + if (likely(skb != NULL)) { + __skb_put(skb, len); + pci_dma_sync_single_for_cpu(adap->pdev, + pci_unmap_addr(sd, dma_addr), len, + PCI_DMA_FROMDEVICE); + memcpy(skb->data, sd->skb->data, len); + pci_dma_sync_single_for_device(adap->pdev, + pci_unmap_addr(sd, dma_addr), len, + PCI_DMA_FROMDEVICE); + } else if (!drop_thres) + goto use_orig_buf; +recycle: + recycle_rx_buf(adap, fl, fl->cidx); + return skb; + } + + if (unlikely(fl->credits < drop_thres)) + goto recycle; + +use_orig_buf: + pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr), + fl->buf_size, PCI_DMA_FROMDEVICE); + skb = sd->skb; + skb_put(skb, len); + __refill_fl(adap, fl); + return skb; +} + +/** + * get_packet_pg - return the next ingress packet buffer from a free list + * @adap: the adapter that received the packet + * @fl: the SGE free list holding the packet + * @len: the packet length including any SGE padding + * @drop_thres: # of remaining buffers before we start dropping packets + * + * Get the next packet from a free list populated with page chunks. + * If the packet is small we make a copy and recycle the original buffer, + * otherwise we attach the original buffer as a page fragment to a fresh + * sk_buff. If a positive drop threshold is supplied packets are dropped + * and their buffers recycled if (a) the number of remaining buffers is + * under the threshold and the packet is too big to copy, or (b) there's + * no system memory. + * + * Note: this function is similar to @get_packet but deals with Rx buffers + * that are page chunks rather than sk_buffs. + */ +static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl, + unsigned int len, unsigned int drop_thres) +{ + struct sk_buff *skb = NULL; + struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; + + if (len <= SGE_RX_COPY_THRES) { + skb = alloc_skb(len, GFP_ATOMIC); + if (likely(skb != NULL)) { + __skb_put(skb, len); + pci_dma_sync_single_for_cpu(adap->pdev, + pci_unmap_addr(sd, dma_addr), len, + PCI_DMA_FROMDEVICE); + memcpy(skb->data, sd->pg_chunk.va, len); + pci_dma_sync_single_for_device(adap->pdev, + pci_unmap_addr(sd, dma_addr), len, + PCI_DMA_FROMDEVICE); + } else if (!drop_thres) + return NULL; +recycle: + fl->credits--; + recycle_rx_buf(adap, fl, fl->cidx); + return skb; + } + + if (unlikely(fl->credits <= drop_thres)) + goto recycle; + + skb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC); + if (unlikely(!skb)) { + if (!drop_thres) + return NULL; + goto recycle; + } + + pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr), + fl->buf_size, PCI_DMA_FROMDEVICE); + __skb_put(skb, SGE_RX_PULL_LEN); + memcpy(skb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN); + skb_fill_page_desc(skb, 0, sd->pg_chunk.page, + sd->pg_chunk.offset + SGE_RX_PULL_LEN, + len - SGE_RX_PULL_LEN); + skb->len = len; + skb->data_len = len - SGE_RX_PULL_LEN; + skb->truesize += skb->data_len; + + fl->credits--; + /* + * We do not refill FLs here, we let the caller do it to overlap a + * prefetch. + */ + return skb; +} + /** * get_imm_packet - return the next ingress packet buffer from a response * @resp: the response descriptor containing the packet data @@ -1715,85 +1834,6 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, netif_rx(skb); } -#define SKB_DATA_SIZE 128 - -static void skb_data_init(struct sk_buff *skb, struct sge_fl_page *p, - unsigned int len) -{ - skb->len = len; - if (len <= SKB_DATA_SIZE) { - skb_copy_to_linear_data(skb, p->va, len); - skb->tail += len; - put_page(p->frag.page); - } else { - skb_copy_to_linear_data(skb, p->va, SKB_DATA_SIZE); - skb_shinfo(skb)->frags[0].page = p->frag.page; - skb_shinfo(skb)->frags[0].page_offset = - p->frag.page_offset + SKB_DATA_SIZE; - skb_shinfo(skb)->frags[0].size = len - SKB_DATA_SIZE; - skb_shinfo(skb)->nr_frags = 1; - skb->data_len = len - SKB_DATA_SIZE; - skb->tail += SKB_DATA_SIZE; - skb->truesize += skb->data_len; - } -} - -/** -* get_packet - return the next ingress packet buffer from a free list -* @adap: the adapter that received the packet -* @fl: the SGE free list holding the packet -* @len: the packet length including any SGE padding -* @drop_thres: # of remaining buffers before we start dropping packets -* -* Get the next packet from a free list and complete setup of the -* sk_buff. If the packet is small we make a copy and recycle the -* original buffer, otherwise we use the original buffer itself. If a -* positive drop threshold is supplied packets are dropped and their -* buffers recycled if (a) the number of remaining buffers is under the -* threshold and the packet is too big to copy, or (b) the packet should -* be copied but there is no memory for the copy. -*/ -static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl, - unsigned int len, unsigned int drop_thres) -{ - struct sk_buff *skb = NULL; - struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; - - prefetch(sd->t.skb->data); - - if (len <= SGE_RX_COPY_THRES) { - skb = alloc_skb(len, GFP_ATOMIC); - if (likely(skb != NULL)) { - struct rx_desc *d = &fl->desc[fl->cidx]; - dma_addr_t mapping = - (dma_addr_t)((u64) be32_to_cpu(d->addr_hi) << 32 | - be32_to_cpu(d->addr_lo)); - - __skb_put(skb, len); - pci_dma_sync_single_for_cpu(adap->pdev, mapping, len, - PCI_DMA_FROMDEVICE); - skb_copy_from_linear_data(sd->t.skb, skb->data, len); - pci_dma_sync_single_for_device(adap->pdev, mapping, len, - PCI_DMA_FROMDEVICE); - } else if (!drop_thres) - goto use_orig_buf; -recycle: - recycle_rx_buf(adap, fl, fl->cidx); - return skb; - } - - if (unlikely(fl->credits < drop_thres)) - goto recycle; - -use_orig_buf: - pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr), - fl->buf_size, PCI_DMA_FROMDEVICE); - skb = sd->t.skb; - skb_put(skb, len); - __refill_fl(adap, fl); - return skb; -} - /** * handle_rsp_cntrl_info - handles control information in a response * @qs: the queue set corresponding to the response @@ -1935,7 +1975,7 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs, } else if (flags & F_RSPD_IMM_DATA_VALID) { skb = get_imm_packet(r); if (unlikely(!skb)) { - no_mem: +no_mem: q->next_holdoff = NOMEM_INTR_DELAY; q->nomem++; /* consume one credit since we tried */ @@ -1945,53 +1985,29 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs, q->imm_data++; ethpad = 0; } else if ((len = ntohl(r->len_cq)) != 0) { - struct sge_fl *fl = - (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; + struct sge_fl *fl; - if (fl->buf_size == RX_PAGE_SIZE) { - struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; - struct sge_fl_page *p = &sd->t.page; - - prefetch(p->va); - prefetch(p->va + L1_CACHE_BYTES); + fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; + if (fl->use_pages) { + void *addr = fl->sdesc[fl->cidx].pg_chunk.va; + prefetch(addr); +#if L1_CACHE_BYTES < 128 + prefetch(addr + L1_CACHE_BYTES); +#endif __refill_fl(adap, fl); - pci_unmap_single(adap->pdev, - pci_unmap_addr(sd, dma_addr), - fl->buf_size, - PCI_DMA_FROMDEVICE); - - if (eth) { - if (unlikely(fl->credits < - SGE_RX_DROP_THRES)) - goto eth_recycle; - - skb = alloc_skb(SKB_DATA_SIZE, - GFP_ATOMIC); - if (unlikely(!skb)) { -eth_recycle: - q->rx_drops++; - recycle_rx_buf(adap, fl, - fl->cidx); - goto eth_done; - } - } else { - skb = alloc_skb(SKB_DATA_SIZE, - GFP_ATOMIC); - if (unlikely(!skb)) - goto no_mem; - } - - skb_data_init(skb, p, G_RSPD_LEN(len)); -eth_done: - fl->credits--; - q->eth_pkts++; - } else { - fl->credits--; + skb = get_packet_pg(adap, fl, G_RSPD_LEN(len), + eth ? SGE_RX_DROP_THRES : 0); + } else skb = get_packet(adap, fl, G_RSPD_LEN(len), eth ? SGE_RX_DROP_THRES : 0); - } + if (unlikely(!skb)) { + if (!eth) + goto no_mem; + q->rx_drops++; + } else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT)) + __skb_pull(skb, 2); if (++fl->cidx == fl->size) fl->cidx = 0; @@ -2016,20 +2032,15 @@ eth_done: q->credits = 0; } - if (skb) { - /* Preserve the RSS info in csum & priority */ - skb->csum = rss_hi; - skb->priority = rss_lo; - + if (likely(skb != NULL)) { if (eth) rx_eth(adap, q, skb, ethpad); else { - if (unlikely(r->rss_hdr.opcode == - CPL_TRACE_PKT)) - __skb_pull(skb, ethpad); - - ngathered = rx_offload(&adap->tdev, q, - skb, offload_skbs, + /* Preserve the RSS info in csum & priority */ + skb->csum = rss_hi; + skb->priority = rss_lo; + ngathered = rx_offload(&adap->tdev, q, skb, + offload_skbs, ngathered); } } @@ -2635,25 +2646,15 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, q->txq[TXQ_ETH].stop_thres = nports * flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3); - if (!is_offload(adapter)) { -#ifdef USE_RX_PAGE - q->fl[0].buf_size = RX_PAGE_SIZE; +#if FL0_PG_CHUNK_SIZE > 0 + q->fl[0].buf_size = FL0_PG_CHUNK_SIZE; #else - q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + 2 + - sizeof(struct cpl_rx_pkt); + q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + sizeof(struct cpl_rx_data); #endif - q->fl[1].buf_size = MAX_FRAME_SIZE + 2 + - sizeof(struct cpl_rx_pkt); - } else { -#ifdef USE_RX_PAGE - q->fl[0].buf_size = RX_PAGE_SIZE; -#else - q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + - sizeof(struct cpl_rx_data); -#endif - q->fl[1].buf_size = (16 * 1024) - - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - } + q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0; + q->fl[1].buf_size = is_offload(adapter) ? + (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) : + MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt); spin_lock(&adapter->sge.reg_lock); From 8a9fab22cf6a3abde7731f4425d4ff87509bc15a Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 30 May 2007 21:10:52 -0700 Subject: [PATCH 080/551] cxgb3 - Firmware update Update FW to 4.1. Proceed to subsequent HW tuning to improve RDMA perfs.. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/regs.h | 4 ++++ drivers/net/cxgb3/t3_hw.c | 42 ++++++++++++++++++++----------------- drivers/net/cxgb3/version.h | 2 +- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 020859c855d7..02f8731ffb02 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -1160,6 +1160,8 @@ #define A_TP_MOD_CHANNEL_WEIGHT 0x434 +#define A_TP_MOD_RATE_LIMIT 0x438 + #define A_TP_PIO_ADDR 0x440 #define A_TP_PIO_DATA 0x444 @@ -1214,6 +1216,8 @@ #define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \ M_TXDROPCNTCH0RCVD) +#define A_TP_PROXY_FLOW_CNTL 0x4b0 + #define A_ULPRX_CTL 0x500 #define S_ROUND_ROBIN 4 diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index fb485d0a43d8..9e3591d7706f 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -921,7 +921,7 @@ static int t3_flash_erase_sectors(struct adapter *adapter, int start, int end) /* * t3_load_fw - download firmware * @adapter: the adapter - * @fw_data: the firrware image to write + * @fw_data: the firmware image to write * @size: image size * * Write the supplied firmware image to the card's serial flash. @@ -2362,7 +2362,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p) F_TCPCHECKSUMOFFLOAD | V_IPTTL(64)); t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) | F_MTUENABLE | V_WINDOWSCALEMODE(1) | - V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1)); + V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1)); t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) | V_AUTOSTATE2(1) | V_AUTOSTATE1(0) | V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) | @@ -2371,16 +2371,18 @@ static void tp_config(struct adapter *adap, const struct tp_params *p) F_IPV6ENABLE | F_NICMODE); t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814); t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105); - t3_set_reg_field(adap, A_TP_PARA_REG6, - adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND, - 0); + t3_set_reg_field(adap, A_TP_PARA_REG6, 0, + adap->params.rev > 0 ? F_ENABLEESND : + F_T3A_ENABLEESND); t3_set_reg_field(adap, A_TP_PC_CONFIG, - F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL, - F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE | - F_RXCONGESTIONMODE); + F_ENABLEEPCMDAFULL, + F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK | + F_TXCONGESTIONMODE | F_RXCONGESTIONMODE); t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0); - + t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080); + t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000); + if (adap->params.rev > 0) { tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE); t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO, @@ -2390,9 +2392,10 @@ static void tp_config(struct adapter *adap, const struct tp_params *p) } else t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED); - t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0x12121212); - t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0x12121212); - t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0x1212); + t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0); + t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0); + t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0); + t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000); } /* Desired TP timer resolution in usec */ @@ -2468,6 +2471,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) val |= F_RXCOALESCEENABLE; if (psh) val |= F_RXCOALESCEPSHEN; + size = min(MAX_RX_COALESCING_LEN, size); t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) | V_MAXRXDATA(MAX_RX_COALESCING_LEN)); } @@ -2496,11 +2500,11 @@ static void __devinit init_mtus(unsigned short mtus[]) * it can accomodate max size TCP/IP headers when SACK and timestamps * are enabled and still have at least 8 bytes of payload. */ - mtus[0] = 88; - mtus[1] = 256; - mtus[2] = 512; - mtus[3] = 576; - mtus[4] = 808; + mtus[1] = 88; + mtus[1] = 88; + mtus[2] = 256; + mtus[3] = 512; + mtus[4] = 576; mtus[5] = 1024; mtus[6] = 1280; mtus[7] = 1492; @@ -2802,7 +2806,7 @@ static void init_hw_for_avail_ports(struct adapter *adap, int nports) t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0); t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN | F_PORT0ACTIVE | F_ENFORCEPKT); - t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000); + t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff); } else { t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN); t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB); @@ -3097,7 +3101,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params) else t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN); - t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000); + t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff); init_hw_for_avail_ports(adapter, adapter->params.nports); t3_sge_init(adapter, &adapter->params.sge); diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h index b112317f033e..8eddd23a3a51 100644 --- a/drivers/net/cxgb3/version.h +++ b/drivers/net/cxgb3/version.h @@ -39,6 +39,6 @@ /* Firmware version */ #define FW_VERSION_MAJOR 4 -#define FW_VERSION_MINOR 0 +#define FW_VERSION_MINOR 1 #define FW_VERSION_MICRO 0 #endif /* __CHELSIO_VERSION_H */ From 480fe1a31c662ef4ff0598a7cacefa21f98335f1 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 30 May 2007 21:10:58 -0700 Subject: [PATCH 081/551] cxgb3 - TP SRAM update The chip executes microcode present in internal RAM, whose content is loaded from EEPROM on power cycle. This patch allows an update of the microcode through PIO without forcing a power cycle. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/common.h | 28 +++++++++++ drivers/net/cxgb3/cxgb3_main.c | 43 +++++++++++++++++ drivers/net/cxgb3/regs.h | 7 +++ drivers/net/cxgb3/t3_hw.c | 86 ++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 8d1379633698..16378004507a 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -101,6 +101,7 @@ enum { TCB_SIZE = 128, /* TCB size */ NMTUS = 16, /* size of MTU table */ NCCTRL_WIN = 32, /* # of congestion control windows */ + PROTO_SRAM_LINES = 128, /* size of TP sram */ }; #define MAX_RX_COALESCING_LEN 16224U @@ -123,6 +124,30 @@ enum { /* adapter interrupt-maintained statistics */ IRQ_NUM_STATS /* keep last */ }; +enum { + TP_VERSION_MAJOR = 1, + TP_VERSION_MINOR = 0, + TP_VERSION_MICRO = 44 +}; + +#define S_TP_VERSION_MAJOR 16 +#define M_TP_VERSION_MAJOR 0xFF +#define V_TP_VERSION_MAJOR(x) ((x) << S_TP_VERSION_MAJOR) +#define G_TP_VERSION_MAJOR(x) \ + (((x) >> S_TP_VERSION_MAJOR) & M_TP_VERSION_MAJOR) + +#define S_TP_VERSION_MINOR 8 +#define M_TP_VERSION_MINOR 0xFF +#define V_TP_VERSION_MINOR(x) ((x) << S_TP_VERSION_MINOR) +#define G_TP_VERSION_MINOR(x) \ + (((x) >> S_TP_VERSION_MINOR) & M_TP_VERSION_MINOR) + +#define S_TP_VERSION_MICRO 0 +#define M_TP_VERSION_MICRO 0xFF +#define V_TP_VERSION_MICRO(x) ((x) << S_TP_VERSION_MICRO) +#define G_TP_VERSION_MICRO(x) \ + (((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO) + enum { SGE_QSETS = 8, /* # of SGE Tx/Rx/RspQ sets */ SGE_RXQ_PER_SET = 2, /* # of Rx queues per set */ @@ -654,6 +679,9 @@ const struct adapter_info *t3_get_adapter_info(unsigned int board_id); int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data); int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data); int t3_seeprom_wp(struct adapter *adapter, int enable); +int t3_check_tpsram_version(struct adapter *adapter); +int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size); +int t3_set_proto_sram(struct adapter *adap, u8 *data); int t3_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented); int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index d8a1f5452c51..15defe4c4f05 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -2088,6 +2088,42 @@ static void cxgb_netpoll(struct net_device *dev) } #endif +#define TPSRAM_NAME "t3%c_protocol_sram-%d.%d.%d.bin" +int update_tpsram(struct adapter *adap) +{ + const struct firmware *tpsram; + char buf[64]; + struct device *dev = &adap->pdev->dev; + int ret; + char rev; + + rev = adap->params.rev == T3_REV_B2 ? 'b' : 'a'; + + snprintf(buf, sizeof(buf), TPSRAM_NAME, rev, + TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO); + + ret = request_firmware(&tpsram, buf, dev); + if (ret < 0) { + dev_err(dev, "could not load TP SRAM: unable to load %s\n", + buf); + return ret; + } + + ret = t3_check_tpsram(adap, tpsram->data, tpsram->size); + if (ret) + goto release_tpsram; + + ret = t3_set_proto_sram(adap, tpsram->data); + if (ret) + dev_err(dev, "loading protocol SRAM failed\n"); + +release_tpsram: + release_firmware(tpsram); + + return ret; +} + + /* * Periodic accumulation of MAC statistics. */ @@ -2437,6 +2473,13 @@ static int __devinit init_one(struct pci_dev *pdev, goto out_free_dev; } + err = t3_check_tpsram_version(adapter); + if (err == -EINVAL) + err = update_tpsram(adapter); + + if (err) + goto out_free_dev; + /* * The card is now ready to go. If any errors occur during device * registration we do not fail the whole card but rather proceed only diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 02f8731ffb02..aa80313c922e 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -1218,6 +1218,13 @@ #define A_TP_PROXY_FLOW_CNTL 0x4b0 +#define A_TP_EMBED_OP_FIELD0 0x4e8 +#define A_TP_EMBED_OP_FIELD1 0x4ec +#define A_TP_EMBED_OP_FIELD2 0x4f0 +#define A_TP_EMBED_OP_FIELD3 0x4f4 +#define A_TP_EMBED_OP_FIELD4 0x4f8 +#define A_TP_EMBED_OP_FIELD5 0x4fc + #define A_ULPRX_CTL 0x500 #define S_ROUND_ROBIN 4 diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 9e3591d7706f..dd3149d94ba8 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -847,6 +847,64 @@ static int t3_write_flash(struct adapter *adapter, unsigned int addr, return 0; } +/** + * t3_check_tpsram_version - read the tp sram version + * @adapter: the adapter + * + * Reads the protocol sram version from serial eeprom. + */ +int t3_check_tpsram_version(struct adapter *adapter) +{ + int ret; + u32 vers; + unsigned int major, minor; + + /* Get version loaded in SRAM */ + t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0); + ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0, + 1, 1, 5, 1); + if (ret) + return ret; + + vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1); + + major = G_TP_VERSION_MAJOR(vers); + minor = G_TP_VERSION_MINOR(vers); + + if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) + return 0; + + return -EINVAL; +} + +/** + * t3_check_tpsram - check if provided protocol SRAM + * is compatible with this driver + * @adapter: the adapter + * @tp_sram: the firmware image to write + * @size: image size + * + * Checks if an adapter's tp sram is compatible with the driver. + * Returns 0 if the versions are compatible, a negative error otherwise. + */ +int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size) +{ + u32 csum; + unsigned int i; + const u32 *p = (const u32 *)tp_sram; + + /* Verify checksum */ + for (csum = 0, i = 0; i < size / sizeof(csum); i++) + csum += ntohl(p[i]); + if (csum != 0xffffffff) { + CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n", + csum); + return -EINVAL; + } + + return 0; +} + enum fw_version_type { FW_VERSION_N3, FW_VERSION_T3 @@ -2686,6 +2744,34 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p) t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff); } +/** + * t3_set_proto_sram - set the contents of the protocol sram + * @adapter: the adapter + * @data: the protocol image + * + * Write the contents of the protocol SRAM. + */ +int t3_set_proto_sram(struct adapter *adap, u8 *data) +{ + int i; + u32 *buf = (u32 *)data; + + for (i = 0; i < PROTO_SRAM_LINES; i++) { + t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++)); + t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++)); + t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++)); + t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++)); + t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++)); + + t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31); + if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1)) + return -EIO; + } + t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, 0); + + return 0; +} + void t3_config_trace_filter(struct adapter *adapter, const struct trace_params *tp, int filter_index, int invert, int enable) From eb034a7998956bffdd2acccb7fddfc114c913120 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 19 May 2007 22:18:10 +0200 Subject: [PATCH 082/551] tulip: Convert to generic boolean Signed-off-by: Richard Knutsson Signed-off-by: Jeff Garzik --- drivers/net/tulip/de4x5.c | 98 +++++++++++++++++++-------------------- drivers/net/tulip/de4x5.h | 9 ---- 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 62143f92c231..42fca26afc50 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -597,7 +597,7 @@ static char *args; #endif struct parameters { - int fdx; + bool fdx; int autosense; }; @@ -809,10 +809,10 @@ struct de4x5_private { s32 irq_en; /* Summary interrupt bits */ int media; /* Media (eg TP), mode (eg 100B)*/ int c_media; /* Remember the last media conn */ - int fdx; /* media full duplex flag */ + bool fdx; /* media full duplex flag */ int linkOK; /* Link is OK */ int autosense; /* Allow/disallow autosensing */ - int tx_enable; /* Enable descriptor polling */ + bool tx_enable; /* Enable descriptor polling */ int setup_f; /* Setup frame filtering type */ int local_state; /* State within a 'media' state */ struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */ @@ -838,8 +838,8 @@ struct de4x5_private { struct de4x5_srom srom; /* A copy of the SROM */ int cfrv; /* Card CFRV copy */ int rx_ovf; /* Check for 'RX overflow' tag */ - int useSROM; /* For non-DEC card use SROM */ - int useMII; /* Infoblock using the MII */ + bool useSROM; /* For non-DEC card use SROM */ + bool useMII; /* Infoblock using the MII */ int asBitValid; /* Autosense bits in GEP? */ int asPolarity; /* 0 => asserted high */ int asBit; /* Autosense bit number in GEP */ @@ -928,7 +928,7 @@ static int dc21040_state(struct net_device *dev, int csr13, int csr14, int c static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); static int test_for_100Mb(struct net_device *dev, int msec); static int wait_for_link(struct net_device *dev); -static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec); +static int test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec); static int is_spd_100(struct net_device *dev); static int is_100_up(struct net_device *dev); static int is_10_up(struct net_device *dev); @@ -1109,7 +1109,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) /* ** Now find out what kind of DC21040/DC21041/DC21140 board we have. */ - lp->useSROM = FALSE; + lp->useSROM = false; if (lp->bus == PCI) { PCI_signature(name, lp); } else { @@ -1137,7 +1137,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) lp->cache.gepc = GEP_INIT; lp->asBit = GEP_SLNK; lp->asPolarity = GEP_SLNK; - lp->asBitValid = TRUE; + lp->asBitValid = ~0; lp->timeout = -1; lp->gendev = gendev; spin_lock_init(&lp->lock); @@ -1463,7 +1463,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) u_long flags = 0; netif_stop_queue(dev); - if (lp->tx_enable == NO) { /* Cannot send for now */ + if (!lp->tx_enable) { /* Cannot send for now */ return -1; } @@ -2424,7 +2424,7 @@ dc21040_autoconf(struct net_device *dev) switch (lp->media) { case INIT: DISABLE_IRQs; - lp->tx_enable = NO; + lp->tx_enable = false; lp->timeout = -1; de4x5_save_skbs(dev); if ((lp->autosense == AUTO) || (lp->autosense == TP)) { @@ -2477,7 +2477,7 @@ dc21040_autoconf(struct net_device *dev) lp->c_media = lp->media; } lp->media = INIT; - lp->tx_enable = NO; + lp->tx_enable = false; break; } @@ -2578,7 +2578,7 @@ dc21041_autoconf(struct net_device *dev) switch (lp->media) { case INIT: DISABLE_IRQs; - lp->tx_enable = NO; + lp->tx_enable = false; lp->timeout = -1; de4x5_save_skbs(dev); /* Save non transmitted skb's */ if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) { @@ -2757,7 +2757,7 @@ dc21041_autoconf(struct net_device *dev) lp->c_media = lp->media; } lp->media = INIT; - lp->tx_enable = NO; + lp->tx_enable = false; break; } @@ -2781,7 +2781,7 @@ dc21140m_autoconf(struct net_device *dev) case INIT: if (lp->timeout < 0) { DISABLE_IRQs; - lp->tx_enable = FALSE; + lp->tx_enable = false; lp->linkOK = 0; de4x5_save_skbs(dev); /* Save non transmitted skb's */ } @@ -2830,7 +2830,7 @@ dc21140m_autoconf(struct net_device *dev) if (lp->timeout < 0) { mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); } - cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); + cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500); if (cr < 0) { next_tick = cr & ~TIMER_CB; } else { @@ -2845,7 +2845,7 @@ dc21140m_autoconf(struct net_device *dev) break; case 1: - if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { + if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000)) < 0) { next_tick = sr & ~TIMER_CB; } else { lp->media = SPD_DET; @@ -2857,10 +2857,10 @@ dc21140m_autoconf(struct net_device *dev) if (!(anlpa & MII_ANLPA_RF) && (cap = anlpa & MII_ANLPA_TAF & ana)) { if (cap & MII_ANA_100M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); + lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0; lp->media = _100Mb; } else if (cap & MII_ANA_10M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); + lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0; lp->media = _10Mb; } @@ -2932,7 +2932,7 @@ dc21140m_autoconf(struct net_device *dev) lp->c_media = lp->media; } lp->media = INIT; - lp->tx_enable = FALSE; + lp->tx_enable = false; break; } @@ -2965,7 +2965,7 @@ dc2114x_autoconf(struct net_device *dev) case INIT: if (lp->timeout < 0) { DISABLE_IRQs; - lp->tx_enable = FALSE; + lp->tx_enable = false; lp->linkOK = 0; lp->timeout = -1; de4x5_save_skbs(dev); /* Save non transmitted skb's */ @@ -3013,7 +3013,7 @@ dc2114x_autoconf(struct net_device *dev) if (lp->timeout < 0) { mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); } - cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); + cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500); if (cr < 0) { next_tick = cr & ~TIMER_CB; } else { @@ -3028,7 +3028,8 @@ dc2114x_autoconf(struct net_device *dev) break; case 1: - if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { + sr = test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000); + if (sr < 0) { next_tick = sr & ~TIMER_CB; } else { lp->media = SPD_DET; @@ -3040,10 +3041,10 @@ dc2114x_autoconf(struct net_device *dev) if (!(anlpa & MII_ANLPA_RF) && (cap = anlpa & MII_ANLPA_TAF & ana)) { if (cap & MII_ANA_100M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); + lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0; lp->media = _100Mb; } else if (cap & MII_ANA_10M) { - lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); + lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0; lp->media = _10Mb; } } @@ -3222,14 +3223,14 @@ srom_map_media(struct net_device *dev) { struct de4x5_private *lp = netdev_priv(dev); - lp->fdx = 0; + lp->fdx = false; if (lp->infoblock_media == lp->media) return 0; switch(lp->infoblock_media) { case SROM_10BASETF: if (!lp->params.fdx) return -1; - lp->fdx = TRUE; + lp->fdx = true; case SROM_10BASET: if (lp->params.fdx && !lp->fdx) return -1; if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) { @@ -3249,7 +3250,7 @@ srom_map_media(struct net_device *dev) case SROM_100BASETF: if (!lp->params.fdx) return -1; - lp->fdx = TRUE; + lp->fdx = true; case SROM_100BASET: if (lp->params.fdx && !lp->fdx) return -1; lp->media = _100Mb; @@ -3261,7 +3262,7 @@ srom_map_media(struct net_device *dev) case SROM_100BASEFF: if (!lp->params.fdx) return -1; - lp->fdx = TRUE; + lp->fdx = true; case SROM_100BASEF: if (lp->params.fdx && !lp->fdx) return -1; lp->media = _100Mb; @@ -3297,7 +3298,7 @@ de4x5_init_connection(struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); de4x5_rst_desc_ring(dev); de4x5_setup_intr(dev); - lp->tx_enable = YES; + lp->tx_enable = true; spin_unlock_irqrestore(&lp->lock, flags); outl(POLL_DEMAND, DE4X5_TPD); @@ -3336,7 +3337,7 @@ de4x5_reset_phy(struct net_device *dev) } } if (lp->useMII) { - next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500); + next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, false, 500); } } else if (lp->chipset == DC21140) { PHY_HARD_RESET; @@ -3466,7 +3467,7 @@ wait_for_link(struct net_device *dev) ** */ static int -test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) +test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec) { struct de4x5_private *lp = netdev_priv(dev); int test; @@ -3476,9 +3477,8 @@ test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) lp->timeout = msec/100; } - if (pol) pol = ~0; reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask; - test = (reg ^ pol) & mask; + test = (reg ^ (pol ? ~0 : 0)) & mask; if (test && --lp->timeout) { reg = 100 | TIMER_CB; @@ -3992,10 +3992,10 @@ PCI_signature(char *name, struct de4x5_private *lp) ))))))); } if (lp->chipset != DC21041) { - lp->useSROM = TRUE; /* card is not recognisably DEC */ + lp->useSROM = true; /* card is not recognisably DEC */ } } else if ((lp->chipset & ~0x00ff) == DC2114x) { - lp->useSROM = TRUE; + lp->useSROM = true; } return status; @@ -4216,7 +4216,7 @@ srom_repair(struct net_device *dev, int card) memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom)); memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN); memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100); - lp->useSROM = TRUE; + lp->useSROM = true; break; } @@ -4392,7 +4392,7 @@ srom_infoleaf_info(struct net_device *dev) if (lp->chipset == infoleaf_array[i].chipset) break; } if (i == INFOLEAF_SIZE) { - lp->useSROM = FALSE; + lp->useSROM = false; printk("%s: Cannot find correct chipset for SROM decoding!\n", dev->name); return -ENXIO; @@ -4409,7 +4409,7 @@ srom_infoleaf_info(struct net_device *dev) if (lp->device == *p) break; } if (i == 0) { - lp->useSROM = FALSE; + lp->useSROM = false; printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n", dev->name, lp->device); return -ENXIO; @@ -4542,7 +4542,7 @@ dc21140_infoleaf(struct net_device *dev) } lp->media = INIT; lp->tcount = 0; - lp->tx_enable = FALSE; + lp->tx_enable = false; } return next_tick & ~TIMER_CB; @@ -4577,7 +4577,7 @@ dc21142_infoleaf(struct net_device *dev) } lp->media = INIT; lp->tcount = 0; - lp->tx_enable = FALSE; + lp->tx_enable = false; } return next_tick & ~TIMER_CB; @@ -4611,7 +4611,7 @@ dc21143_infoleaf(struct net_device *dev) } lp->media = INIT; lp->tcount = 0; - lp->tx_enable = FALSE; + lp->tx_enable = false; } return next_tick & ~TIMER_CB; @@ -4650,7 +4650,7 @@ compact_infoblock(struct net_device *dev, u_char count, u_char *p) lp->asBit = 1 << ((csr6 >> 1) & 0x07); lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; + lp->useMII = false; de4x5_switch_mac_port(dev); } @@ -4691,7 +4691,7 @@ type0_infoblock(struct net_device *dev, u_char count, u_char *p) lp->asBit = 1 << ((csr6 >> 1) & 0x07); lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; + lp->useMII = false; de4x5_switch_mac_port(dev); } @@ -4731,7 +4731,7 @@ type1_infoblock(struct net_device *dev, u_char count, u_char *p) lp->ibn = 1; lp->active = *p; lp->infoblock_csr6 = OMR_MII_100; - lp->useMII = TRUE; + lp->useMII = true; lp->infoblock_media = ANS; de4x5_switch_mac_port(dev); @@ -4773,7 +4773,7 @@ type2_infoblock(struct net_device *dev, u_char count, u_char *p) lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); lp->infoblock_csr6 = OMR_SIA; - lp->useMII = FALSE; + lp->useMII = false; de4x5_switch_mac_port(dev); } @@ -4814,7 +4814,7 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p) lp->active = *p; if (MOTO_SROM_BUG) lp->active = 0; lp->infoblock_csr6 = OMR_MII_100; - lp->useMII = TRUE; + lp->useMII = true; lp->infoblock_media = ANS; de4x5_switch_mac_port(dev); @@ -4856,7 +4856,7 @@ type4_infoblock(struct net_device *dev, u_char count, u_char *p) lp->asBit = 1 << ((csr6 >> 1) & 0x07); lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); - lp->useMII = FALSE; + lp->useMII = false; de4x5_switch_mac_port(dev); } @@ -5077,7 +5077,7 @@ mii_get_phy(struct net_device *dev) int id; lp->active = 0; - lp->useMII = TRUE; + lp->useMII = true; /* Search the MII address space for possible PHY devices */ for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(i+1)%DE4X5_MAX_MII) { @@ -5127,7 +5127,7 @@ mii_get_phy(struct net_device *dev) de4x5_dbg_mii(dev, k); } } - if (!lp->mii_cnt) lp->useMII = FALSE; + if (!lp->mii_cnt) lp->useMII = false; return lp->mii_cnt; } diff --git a/drivers/net/tulip/de4x5.h b/drivers/net/tulip/de4x5.h index 57226e5eb8a6..12af0cc037fb 100644 --- a/drivers/net/tulip/de4x5.h +++ b/drivers/net/tulip/de4x5.h @@ -892,15 +892,6 @@ #define ALL 0 /* Clear out all the setup frame */ #define PHYS_ADDR_ONLY 1 /* Update the physical address only */ -/* -** Booleans -*/ -#define NO 0 -#define FALSE 0 - -#define YES ~0 -#define TRUE ~0 - /* ** Adapter state */ From a72a8179734393ca351f6ecf8cad6841ab7e1470 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 13:25:37 -0700 Subject: [PATCH 083/551] b44: timer power saving Make the PHY and statistic timer run on one second boundary for powersaving. On resume, the driver should check for link up immediately, to get online faster (rather than waiting for the next second). Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 879a2fff474e..e87bab9f9bea 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -599,8 +599,7 @@ static void b44_timer(unsigned long __opaque) spin_unlock_irq(&bp->lock); - bp->timer.expires = jiffies + HZ; - add_timer(&bp->timer); + mod_timer(&bp->timer, round_jiffies(jiffies + HZ)); } static void b44_tx(struct b44 *bp) @@ -2348,11 +2347,11 @@ static int b44_resume(struct pci_dev *pdev) netif_device_attach(bp->dev); spin_unlock_irq(&bp->lock); - bp->timer.expires = jiffies + HZ; - add_timer(&bp->timer); - b44_enable_ints(bp); netif_wake_queue(dev); + + mod_timer(&bp->timer, jiffies + 1); + return 0; } From f65a71775cc3eb5d5d8ac4c349c8f48a7d5c7759 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 13:25:38 -0700 Subject: [PATCH 084/551] b44: tx bounce sizing. No need to grap full size MTU buffer for possibly small transmit bounce buffers. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index e87bab9f9bea..d10d31cd12d7 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -69,7 +69,6 @@ #define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) #define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64) -#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8) /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) @@ -968,7 +967,6 @@ static void b44_tx_timeout(struct net_device *dev) static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct b44 *bp = netdev_priv(dev); - struct sk_buff *bounce_skb; int rc = NETDEV_TX_OK; dma_addr_t mapping; u32 len, entry, ctrl; @@ -986,12 +984,13 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { + struct sk_buff *bounce_skb; + /* Chip can't handle DMA to/from >1GB, use bounce buffer */ if (!dma_mapping_error(mapping)) pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); - bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, - GFP_ATOMIC|GFP_DMA); + bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) goto err_out; @@ -1000,13 +999,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { if (!dma_mapping_error(mapping)) pci_unmap_single(bp->pdev, mapping, - len, PCI_DMA_TODEVICE); + len, PCI_DMA_TODEVICE); dev_kfree_skb_any(bounce_skb); goto err_out; } - skb_copy_from_linear_data(skb, skb_put(bounce_skb, len), - skb->len); + skb_copy_from_linear_data(skb, skb_put(bounce_skb, len), len); dev_kfree_skb_any(skb); skb = bounce_skb; } From 72f4861ef9b1c1ca6e4abb49854698e80d3b684d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 13:25:39 -0700 Subject: [PATCH 085/551] b44: packet offset is constant The receive buffer offset is constant in this driver. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 30 +++++++++++++----------------- drivers/net/b44.h | 2 -- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index d10d31cd12d7..8fdcb698d611 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -68,7 +69,8 @@ (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP)) #define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) -#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64) +#define RX_PKT_OFFSET 30 +#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64) /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) @@ -683,10 +685,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) } skb->dev = bp->dev; - skb_reserve(skb, bp->rx_offset); + rh = (struct rx_header *) skb->data; + skb_reserve(skb, RX_PKT_OFFSET); - rh = (struct rx_header *) - (skb->data - bp->rx_offset); rh->len = 0; rh->flags = 0; @@ -696,13 +697,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) if (src_map != NULL) src_map->skb = NULL; - ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - bp->rx_offset)); + ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET)); if (dest_idx == (B44_RX_RING_SIZE - 1)) ctrl |= DESC_CTRL_EOT; dp = &bp->rx_ring[dest_idx]; dp->ctrl = cpu_to_le32(ctrl); - dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset); + dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset); if (bp->flags & B44_FLAG_RX_RING_HACK) b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma, @@ -781,7 +782,7 @@ static int b44_rx(struct b44 *bp, int budget) PCI_DMA_FROMDEVICE); rh = (struct rx_header *) skb->data; len = le16_to_cpu(rh->len); - if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) || + if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) || (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) { drop_it: b44_recycle_rx(bp, cons, bp->rx_prod); @@ -813,8 +814,8 @@ static int b44_rx(struct b44 *bp, int budget) pci_unmap_single(bp->pdev, map, skb_size, PCI_DMA_FROMDEVICE); /* Leave out rx_header */ - skb_put(skb, len+bp->rx_offset); - skb_pull(skb,bp->rx_offset); + skb_put(skb, len + RX_PKT_OFFSET); + skb_pull(skb, RX_PKT_OFFSET); } else { struct sk_buff *copy_skb; @@ -826,7 +827,7 @@ static int b44_rx(struct b44 *bp, int budget) skb_reserve(copy_skb, 2); skb_put(copy_skb, len); /* DMA sync done above, copy just the actual packet */ - skb_copy_from_linear_data_offset(skb, bp->rx_offset, + skb_copy_from_linear_data_offset(skb, RX_PKT_OFFSET, copy_skb->data, len); skb = copy_skb; } @@ -1393,12 +1394,12 @@ static void b44_init_hw(struct b44 *bp, int reset_kind) bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ if (reset_kind == B44_PARTIAL_RESET) { bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT))); } else { bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT))); bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); bw32(bp, B44_DMARX_PTR, bp->rx_pending); @@ -2090,11 +2091,6 @@ static int __devinit b44_get_invariants(struct b44 *bp) bp->phy_addr = eeprom[90] & 0x1f; - /* With this, plus the rx_header prepended to the data by the - * hardware, we'll land the ethernet header on a 2-byte boundary. - */ - bp->rx_offset = 30; - bp->imask = IMASK_DEF; bp->core_unit = ssb_core_unit(bp); diff --git a/drivers/net/b44.h b/drivers/net/b44.h index 18fc13336628..e537e63f292e 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h @@ -443,8 +443,6 @@ struct b44 { #define B44_FLAG_TX_RING_HACK 0x40000000 #define B44_FLAG_WOL_ENABLE 0x80000000 - u32 rx_offset; - u32 msg_enable; struct timer_list timer; From bf0dcbd929faf036f1a4f2918090344d0e249cf5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 13:25:40 -0700 Subject: [PATCH 086/551] b44: use netdev_alloc_skb Use netdev_alloc_skb rather than dev_alloc_skb when allocating receive buffers. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/b44.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 8fdcb698d611..96fb0ec905a7 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -653,7 +653,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) src_map = &bp->rx_buffers[src_idx]; dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1); map = &bp->rx_buffers[dest_idx]; - skb = dev_alloc_skb(RX_PKT_BUF_SZ); + skb = netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ); if (skb == NULL) return -ENOMEM; @@ -669,7 +669,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) if (!dma_mapping_error(mapping)) pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); - skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); + skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); if (skb == NULL) return -ENOMEM; mapping = pci_map_single(bp->pdev, skb->data, @@ -684,7 +684,6 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) } } - skb->dev = bp->dev; rh = (struct rx_header *) skb->data; skb_reserve(skb, RX_PKT_OFFSET); From 8f036c04a8f3487fa4a2368d99dd74be42b7c6fd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Jun 2007 16:04:39 +0200 Subject: [PATCH 087/551] acenic: SET_NETDEV_DEV is always there these days acenic: SET_NETDEV_DEV is always there these days Signed-off-by: Geert Uytterhoeven Signed-off-by: Jeff Garzik --- drivers/net/acenic.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 04382f979c99..b78a4e5ceeb2 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -159,10 +159,6 @@ static struct pci_device_id acenic_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); -#ifndef SET_NETDEV_DEV -#define SET_NETDEV_DEV(net, pdev) do{} while(0) -#endif - #define ace_sync_irq(irq) synchronize_irq(irq) #ifndef offset_in_page From d1c0a65fb597697d1fbce4eadf42b84f70483edc Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Jun 2007 12:48:53 -0700 Subject: [PATCH 088/551] Use menuconfig objects II - netdev (general+100mbit) CONFIG_NETDEVICES, CONFIG_NET_ETHERNET: Change Kconfig objects from "menu, config" into "menuconfig" so that the user can disable the whole feature without having to enter the menu first. CONFIG_SMC9194: Move it so that it appears correctly in menuconfig. Signed-off-by: Jan Engelhardt Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 167 +++++++++++++++++------------------- drivers/net/arm/Kconfig | 12 +-- drivers/net/fec_8xx/Kconfig | 2 +- drivers/net/fs_enet/Kconfig | 2 +- drivers/net/tulip/Kconfig | 27 +++--- 5 files changed, 102 insertions(+), 108 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b49375abb5f4..dbf773356326 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3,10 +3,7 @@ # Network device configuration # -menu "Network device support" - depends on NET - -config NETDEVICES +menuconfig NETDEVICES default y if UML bool "Network device support" ---help--- @@ -151,11 +148,9 @@ source "drivers/net/phy/Kconfig" # Ethernet # -menu "Ethernet (10 or 100Mbit)" - depends on !UML - -config NET_ETHERNET +menuconfig NET_ETHERNET bool "Ethernet (10 or 100Mbit)" + depends on !UML ---help--- Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common type of Local Area Network (LAN) in universities and companies. @@ -180,9 +175,10 @@ config NET_ETHERNET kernel: saying N will just cause the configurator to skip all the questions about Ethernet network cards. If unsure, say N. +if NET_ETHERNET + config MII tristate "Generic Media Independent Interface device support" - depends on NET_ETHERNET help Most ethernet controllers have MII transceiver either as an external or internal device. It is safe to say Y or M here even if your @@ -190,7 +186,7 @@ config MII config MACB tristate "Atmel MACB support" - depends on NET_ETHERNET && (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263) + depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 select MII help The Atmel MACB ethernet interface is found on many AT32 and AT91 @@ -203,7 +199,7 @@ source "drivers/net/arm/Kconfig" config MACE tristate "MACE (Power Mac ethernet) support" - depends on NET_ETHERNET && PPC_PMAC && PPC32 + depends on PPC_PMAC && PPC32 select CRC32 help Power Macintoshes and clones with Ethernet built-in on the @@ -226,7 +222,7 @@ config MACE_AAUI_PORT config BMAC tristate "BMAC (G3 ethernet) support" - depends on NET_ETHERNET && PPC_PMAC && PPC32 + depends on PPC_PMAC && PPC32 select CRC32 help Say Y for support of BMAC Ethernet interfaces. These are used on G3 @@ -237,7 +233,7 @@ config BMAC config ARIADNE tristate "Ariadne support" - depends on NET_ETHERNET && ZORRO + depends on ZORRO help If you have a Village Tronic Ariadne Ethernet adapter, say Y. Otherwise, say N. @@ -247,7 +243,7 @@ config ARIADNE config A2065 tristate "A2065 support" - depends on NET_ETHERNET && ZORRO + depends on ZORRO select CRC32 help If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise, @@ -258,7 +254,7 @@ config A2065 config HYDRA tristate "Hydra support" - depends on NET_ETHERNET && ZORRO + depends on ZORRO select CRC32 help If you have a Hydra Ethernet adapter, say Y. Otherwise, say N. @@ -268,7 +264,7 @@ config HYDRA config ZORRO8390 tristate "Zorro NS8390-based Ethernet support" - depends on NET_ETHERNET && ZORRO + depends on ZORRO select CRC32 help This driver is for Zorro Ethernet cards using an NS8390-compatible @@ -281,7 +277,7 @@ config ZORRO8390 config APNE tristate "PCMCIA NE2000 support" - depends on NET_ETHERNET && AMIGA_PCMCIA + depends on AMIGA_PCMCIA select CRC32 help If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise, @@ -292,7 +288,7 @@ config APNE config APOLLO_ELPLUS tristate "Apollo 3c505 support" - depends on NET_ETHERNET && APOLLO + depends on APOLLO help Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card. If you don't have one made for Apollos, you can use one from a PC, @@ -301,7 +297,7 @@ config APOLLO_ELPLUS config MAC8390 bool "Macintosh NS 8390 based ethernet cards" - depends on NET_ETHERNET && MAC + depends on MAC select CRC32 help If you want to include a driver to support Nubus or LC-PDS @@ -311,7 +307,7 @@ config MAC8390 config MAC89x0 tristate "Macintosh CS89x0 based ethernet cards" - depends on NET_ETHERNET && MAC + depends on MAC ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a Nubus or LC-PDS network (Ethernet) card of this type, say Y and @@ -324,7 +320,7 @@ config MAC89x0 config MACSONIC tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" - depends on NET_ETHERNET && MAC + depends on MAC ---help--- Support for NatSemi SONIC based Ethernet devices. This includes the onboard Ethernet in many Quadras as well as some LC-PDS, @@ -338,7 +334,7 @@ config MACSONIC config MACMACE bool "Macintosh (AV) onboard MACE ethernet" - depends on NET_ETHERNET && MAC + depends on MAC select CRC32 help Support for the onboard AMD 79C940 MACE Ethernet controller used in @@ -348,7 +344,7 @@ config MACMACE config MVME147_NET tristate "MVME147 (Lance) Ethernet support" - depends on NET_ETHERNET && MVME147 + depends on MVME147 select CRC32 help Support for the on-board Ethernet interface on the Motorola MVME147 @@ -358,7 +354,7 @@ config MVME147_NET config MVME16x_NET tristate "MVME16x Ethernet support" - depends on NET_ETHERNET && MVME16x + depends on MVME16x help This is the driver for the Ethernet interface on the Motorola MVME162, 166, 167, 172 and 177 boards. Say Y here to include the @@ -367,7 +363,7 @@ config MVME16x_NET config BVME6000_NET tristate "BVME6000 Ethernet support" - depends on NET_ETHERNET && BVME6000 + depends on BVME6000 help This is the driver for the Ethernet interface on BVME4000 and BVME6000 VME boards. Say Y here to include the driver for this chip @@ -376,7 +372,7 @@ config BVME6000_NET config ATARILANCE tristate "Atari Lance support" - depends on NET_ETHERNET && ATARI + depends on ATARI help Say Y to include support for several Atari Ethernet adapters based on the AMD Lance chipset: RieblCard (with or without battery), or @@ -384,7 +380,7 @@ config ATARILANCE config ATARI_BIONET tristate "BioNet-100 support" - depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN + depends on ATARI && ATARI_ACSI && BROKEN help Say Y to include support for BioData's BioNet-100 Ethernet adapter for the ACSI port. The driver works (has to work...) with a polled @@ -392,7 +388,7 @@ config ATARI_BIONET config ATARI_PAMSNET tristate "PAMsNet support" - depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN + depends on ATARI && ATARI_ACSI && BROKEN help Say Y to include support for the PAMsNet Ethernet adapter for the ACSI port ("ACSI node"). The driver works (has to work...) with a @@ -400,7 +396,7 @@ config ATARI_PAMSNET config SUN3LANCE tristate "Sun3/Sun3x on-board LANCE support" - depends on NET_ETHERNET && (SUN3 || SUN3X) + depends on SUN3 || SUN3X help Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80) featured an AMD Lance 10Mbit Ethernet controller on board; say Y @@ -413,7 +409,7 @@ config SUN3LANCE config SUN3_82586 bool "Sun3 on-board Intel 82586 support" - depends on NET_ETHERNET && SUN3 + depends on SUN3 help This driver enables support for the on-board Intel 82586 based Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards. Note @@ -422,7 +418,7 @@ config SUN3_82586 config HPLANCE bool "HP on-board LANCE support" - depends on NET_ETHERNET && DIO + depends on DIO select CRC32 help If you want to use the builtin "LANCE" Ethernet controller on an @@ -430,21 +426,21 @@ config HPLANCE config LASI_82596 tristate "Lasi ethernet" - depends on NET_ETHERNET && GSC + depends on GSC help Say Y here to support the builtin Intel 82596 ethernet controller found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet. config MIPS_JAZZ_SONIC tristate "MIPS JAZZ onboard SONIC Ethernet support" - depends on NET_ETHERNET && MACH_JAZZ + depends on MACH_JAZZ help This is the driver for the onboard card of MIPS Magnum 4000, Acer PICA, Olivetti M700-10 and a few other identical OEM systems. config MIPS_AU1X00_ENET bool "MIPS AU1000 Ethernet support" - depends on NET_ETHERNET && SOC_AU1X00 + depends on SOC_AU1X00 select PHYLIB select CRC32 help @@ -453,11 +449,11 @@ config MIPS_AU1X00_ENET config NET_SB1250_MAC tristate "SB1250 Ethernet support" - depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC + depends on SIBYTE_SB1xxx_SOC config SGI_IOC3_ETH bool "SGI IOC3 Ethernet" - depends on NET_ETHERNET && PCI && SGI_IP27 + depends on PCI && SGI_IP27 select CRC32 select MII help @@ -487,7 +483,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM config MIPS_SIM_NET tristate "MIPS simulator Network device" - depends on NET_ETHERNET && MIPS_SIM + depends on MIPS_SIM help The MIPSNET device is a simple Ethernet network device which is emulated by the MIPS Simulator. @@ -495,11 +491,11 @@ config MIPS_SIM_NET config SGI_O2MACE_ETH tristate "SGI O2 MACE Fast Ethernet support" - depends on NET_ETHERNET && SGI_IP32=y + depends on SGI_IP32=y config STNIC tristate "National DP83902AV support" - depends on NET_ETHERNET && SUPERH + depends on SUPERH select CRC32 help Support for cards based on the National Semiconductor DP83902AV @@ -511,7 +507,7 @@ config STNIC config SUNLANCE tristate "Sun LANCE support" - depends on NET_ETHERNET && SBUS + depends on SBUS select CRC32 help This driver supports the "le" interface present on all 32-bit Sparc @@ -524,7 +520,7 @@ config SUNLANCE config HAPPYMEAL tristate "Sun Happy Meal 10/100baseT support" - depends on NET_ETHERNET && (SBUS || PCI) + depends on SBUS || PCI select CRC32 help This driver supports the "hme" interface present on most Ultra @@ -537,7 +533,7 @@ config HAPPYMEAL config SUNBMAC tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)" - depends on NET_ETHERNET && SBUS && EXPERIMENTAL + depends on SBUS && EXPERIMENTAL select CRC32 help This driver supports the "be" interface available as an Sbus option. @@ -548,7 +544,7 @@ config SUNBMAC config SUNQE tristate "Sun QuadEthernet support" - depends on NET_ETHERNET && SBUS + depends on SBUS select CRC32 help This driver supports the "qe" 10baseT Ethernet device, available as @@ -560,7 +556,7 @@ config SUNQE config SUNGEM tristate "Sun GEM support" - depends on NET_ETHERNET && PCI + depends on PCI select CRC32 help Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also @@ -568,7 +564,7 @@ config SUNGEM config CASSINI tristate "Sun Cassini support" - depends on NET_ETHERNET && PCI + depends on PCI select CRC32 help Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also @@ -576,7 +572,7 @@ config CASSINI config NET_VENDOR_3COM bool "3COM cards" - depends on NET_ETHERNET && (ISA || EISA || MCA || PCI) + depends on ISA || EISA || MCA || PCI help If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -736,7 +732,7 @@ config TYPHOON config LANCE tristate "AMD LANCE and PCnet (AT1500 and NE2100) support" - depends on NET_ETHERNET && ISA && ISA_DMA_API + depends on ISA && ISA_DMA_API help If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -748,7 +744,7 @@ config LANCE config NET_VENDOR_SMC bool "Western Digital/SMC cards" - depends on NET_ETHERNET && (ISA || MCA || EISA || MAC) + depends on ISA || MCA || EISA || MAC help If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -818,24 +814,6 @@ config ULTRA32 . The module will be called smc-ultra32. -config SMC91X - tristate "SMC 91C9x/91C1xxx support" - select CRC32 - select MII - depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN) - help - This is a driver for SMC's 91x series of Ethernet chipsets, - including the SMC91C94 and the SMC91C111. Say Y if you want it - compiled into the kernel, and read the file - and the Ethernet-HOWTO, - available from . - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called smc91x. If you want to compile it as a - module, say M here and read - as well as . - config SMC9194 tristate "SMC 9194 support" depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) @@ -852,10 +830,28 @@ config SMC9194 . The module will be called smc9194. +config SMC91X + tristate "SMC 91C9x/91C1xxx support" + select CRC32 + select MII + depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN + help + This is a driver for SMC's 91x series of Ethernet chipsets, + including the SMC91C94 and the SMC91C111. Say Y if you want it + compiled into the kernel, and read the file + and the Ethernet-HOWTO, + available from . + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called smc91x. If you want to compile it as a + module, say M here and read + as well as . + config NET_NETX tristate "NetX Ethernet support" select MII - depends on NET_ETHERNET && ARCH_NETX + depends on ARCH_NETX help This is support for the Hilscher netX builtin Ethernet ports @@ -865,7 +861,7 @@ config NET_NETX config DM9000 tristate "DM9000 support" - depends on (ARM || MIPS) && NET_ETHERNET + depends on ARM || MIPS select CRC32 select MII ---help--- @@ -879,7 +875,7 @@ config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 select MII - depends on NET_ETHERNET && ARCH_PXA + depends on ARCH_PXA help This is a driver for SMSC's LAN911x series of Ethernet chipsets including the new LAN9115, LAN9116, LAN9117, and LAN9118. @@ -893,7 +889,7 @@ config SMC911X config NET_VENDOR_RACAL bool "Racal-Interlan (Micom) NI cards" - depends on NET_ETHERNET && ISA + depends on ISA help If you have a network (Ethernet) card belonging to this class, such as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO, @@ -945,7 +941,7 @@ source "drivers/net/tulip/Kconfig" config AT1700 tristate "AT1700/1720 support (EXPERIMENTAL)" - depends on NET_ETHERNET && (ISA || MCA_LEGACY) && EXPERIMENTAL + depends on (ISA || MCA_LEGACY) && EXPERIMENTAL select CRC32 ---help--- If you have a network (Ethernet) card of this type, say Y and read @@ -958,7 +954,7 @@ config AT1700 config DEPCA tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support" - depends on NET_ETHERNET && (ISA || EISA || MCA) + depends on ISA || EISA || MCA select CRC32 ---help--- If you have a network (Ethernet) card of this type, say Y and read @@ -972,7 +968,7 @@ config DEPCA config HP100 tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support" - depends on NET_ETHERNET && (ISA || EISA || PCI) + depends on ISA || EISA || PCI help If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -984,7 +980,7 @@ config HP100 config NET_ISA bool "Other ISA cards" - depends on NET_ETHERNET && ISA + depends on ISA ---help--- If your network (Ethernet) card hasn't been mentioned yet and its bus system (that's the way the cards talks to the other components @@ -1147,7 +1143,7 @@ config SEEQ8005 config NE2_MCA tristate "NE/2 (ne2000 MCA version) support" - depends on NET_ETHERNET && MCA_LEGACY + depends on MCA_LEGACY select CRC32 help If you have a network (Ethernet) card of this type, say Y and read @@ -1160,7 +1156,7 @@ config NE2_MCA config IBMLANA tristate "IBM LAN Adapter/A support" - depends on NET_ETHERNET && MCA && MCA_LEGACY + depends on MCA && MCA_LEGACY ---help--- This is a Micro Channel Ethernet adapter. You need to set CONFIG_MCA to use this driver. It is both available as an in-kernel @@ -1176,7 +1172,7 @@ config IBMLANA config IBMVETH tristate "IBM LAN Virtual Ethernet support" - depends on NET_ETHERNET && PPC_PSERIES + depends on PPC_PSERIES ---help--- This driver supports virtual ethernet adapters on newer IBM iSeries and pSeries systems. @@ -1257,7 +1253,7 @@ config IBM_EMAC_TAH config NET_PCI bool "EISA, VLB, PCI and on board controllers" - depends on NET_ETHERNET && (ISA || EISA || PCI) + depends on ISA || EISA || PCI help This is another class of network cards which attach directly to the bus. If you have one of those, say Y and read the Ethernet-HOWTO, @@ -1313,6 +1309,7 @@ config AMD8111_ETH To compile this driver as a module, choose M here and read . The module will be called amd8111e. + config AMD8111E_NAPI bool "Enable NAPI support" depends on AMD8111_ETH @@ -1778,7 +1775,7 @@ config SC92031 config NET_POCKET bool "Pocket and portable adapters" - depends on NET_ETHERNET && PARPORT + depends on PARPORT ---help--- Cute little network (Ethernet) devices which attach to the parallel port ("pocket adapters"), commonly used with laptops. If you have @@ -1847,14 +1844,14 @@ config DE620 config SGISEEQ tristate "SGI Seeq ethernet controller support" - depends on NET_ETHERNET && SGI_IP22 + depends on SGI_IP22 help Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. config DECLANCE tristate "DEC LANCE ethernet controller support" - depends on NET_ETHERNET && MACH_DECSTATION + depends on MACH_DECSTATION select CRC32 help This driver is for the series of Ethernet controllers produced by @@ -1884,7 +1881,7 @@ config FEC2 config NE_H8300 tristate "NE2000 compatible support for H8/300" - depends on H8300 && NET_ETHERNET + depends on H8300 help Say Y here if you want to use the NE2000 compatible controller on the Renesas H8/300 processor. @@ -1892,7 +1889,7 @@ config NE_H8300 source "drivers/net/fec_8xx/Kconfig" source "drivers/net/fs_enet/Kconfig" -endmenu +endif # NET_ETHERNET # # Gigabit Ethernet @@ -2948,8 +2945,6 @@ config NETCONSOLE If you want to log kernel messages over the network, enable this. See for details. -endif #NETDEVICES - config NETPOLL def_bool NETCONSOLE @@ -2961,4 +2956,4 @@ config NETPOLL_TRAP config NET_POLL_CONTROLLER def_bool NETPOLL -endmenu +endif # NETDEVICES diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 678e4f48d36b..5bf2d33887ac 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -4,7 +4,7 @@ # config ARM_AM79C961A bool "ARM EBSA110 AM79C961A support" - depends on NET_ETHERNET && ARM && ARCH_EBSA110 + depends on ARM && ARCH_EBSA110 select CRC32 help If you wish to compile a kernel for the EBSA-110, then you should @@ -12,21 +12,21 @@ config ARM_AM79C961A config ARM_ETHER1 tristate "Acorn Ether1 support" - depends on NET_ETHERNET && ARM && ARCH_ACORN + depends on ARM && ARCH_ACORN help If you have an Acorn system with one of these (AKA25) network cards, you should say Y to this option if you wish to use it with Linux. config ARM_ETHER3 tristate "Acorn/ANT Ether3 support" - depends on NET_ETHERNET && ARM && ARCH_ACORN + depends on ARM && ARCH_ACORN help If you have an Acorn system with one of these network cards, you should say Y to this option if you wish to use it with Linux. config ARM_ETHERH tristate "I-cubed EtherH/ANT EtherM support" - depends on NET_ETHERNET && ARM && ARCH_ACORN + depends on ARM && ARCH_ACORN select CRC32 help If you have an Acorn system with one of these network cards, you @@ -34,7 +34,7 @@ config ARM_ETHERH config ARM_AT91_ETHER tristate "AT91RM9200 Ethernet support" - depends on NET_ETHERNET && ARM && ARCH_AT91RM9200 + depends on ARM && ARCH_AT91RM9200 select MII help If you wish to compile a kernel for the AT91RM9200 and enable @@ -42,7 +42,7 @@ config ARM_AT91_ETHER config EP93XX_ETH tristate "EP93xx Ethernet support" - depends on NET_ETHERNET && ARM && ARCH_EP93XX + depends on ARM && ARCH_EP93XX help This is a driver for the ethernet hardware included in EP93xx CPUs. Say Y if you are building a kernel for EP93xx based devices. diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig index a84c232395e3..afb34ded26ee 100644 --- a/drivers/net/fec_8xx/Kconfig +++ b/drivers/net/fec_8xx/Kconfig @@ -1,6 +1,6 @@ config FEC_8XX tristate "Motorola 8xx FEC driver" - depends on NET_ETHERNET && 8xx + depends on 8XX select MII config FEC_8XX_GENERIC_PHY diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig index 6aaee67dd4b7..e27ee210b605 100644 --- a/drivers/net/fs_enet/Kconfig +++ b/drivers/net/fs_enet/Kconfig @@ -1,6 +1,6 @@ config FS_ENET tristate "Freescale Ethernet Driver" - depends on NET_ETHERNET && (CPM1 || CPM2) + depends on CPM1 || CPM2 select MII config FS_ENET_HAS_SCC diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 8c9634a98c11..1c537d5a3062 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -2,17 +2,17 @@ # Tulip family network device configuration # -menu "Tulip family network device support" - depends on NET_ETHERNET && (PCI || EISA || CARDBUS) - -config NET_TULIP +menuconfig NET_TULIP bool "\"Tulip\" family network device support" + depends on PCI || EISA || CARDBUS help This selects the "Tulip" family of EISA/PCI network cards. +if NET_TULIP + config DE2104X tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)" - depends on NET_TULIP && PCI && EXPERIMENTAL + depends on PCI && EXPERIMENTAL select CRC32 ---help--- This driver is developed for the SMC EtherPower series Ethernet @@ -30,7 +30,7 @@ config DE2104X config TULIP tristate "DECchip Tulip (dc2114x) PCI support" - depends on NET_TULIP && PCI + depends on PCI select CRC32 ---help--- This driver is developed for the SMC EtherPower series Ethernet @@ -95,7 +95,7 @@ config TULIP_NAPI_HW_MITIGATION config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" - depends on NET_TULIP && (PCI || EISA) + depends on PCI || EISA select CRC32 ---help--- This is support for the DIGITAL series of PCI/EISA Ethernet cards. @@ -112,7 +112,7 @@ config DE4X5 config WINBOND_840 tristate "Winbond W89c840 Ethernet support" - depends on NET_TULIP && PCI + depends on PCI select CRC32 select MII help @@ -123,7 +123,7 @@ config WINBOND_840 config DM9102 tristate "Davicom DM910x/DM980x support" - depends on NET_TULIP && PCI + depends on PCI select CRC32 ---help--- This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from @@ -137,7 +137,7 @@ config DM9102 config ULI526X tristate "ULi M526x controller support" - depends on NET_TULIP && PCI + depends on PCI select CRC32 ---help--- This driver is for ULi M5261/M5263 10/100M Ethernet Controller @@ -149,7 +149,7 @@ config ULI526X config PCMCIA_XIRCOM tristate "Xircom CardBus support (new driver)" - depends on NET_TULIP && CARDBUS + depends on CARDBUS ---help--- This driver is for the Digital "Tulip" Ethernet CardBus adapters. It should work with most DEC 21*4*-based chips/ethercards, as well @@ -162,7 +162,7 @@ config PCMCIA_XIRCOM config PCMCIA_XIRTULIP tristate "Xircom Tulip-like CardBus support (old driver)" - depends on NET_TULIP && CARDBUS && BROKEN_ON_SMP + depends on CARDBUS && BROKEN_ON_SMP select CRC32 ---help--- This driver is for the Digital "Tulip" Ethernet CardBus adapters. @@ -174,5 +174,4 @@ config PCMCIA_XIRTULIP . The module will be called xircom_tulip_cb. If unsure, say N. -endmenu - +endif # NET_TULIP From 59b34c1260045ca264c0208f2b666e839909e2d4 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 5 Jun 2007 22:55:06 +0900 Subject: [PATCH 089/551] add return value check of request_irq() This patch has added return value check of request_irq() to pcmcia net drivers. Signed-off-by: Yoichi Yuasa Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/axnet_cs.c | 7 +++++-- drivers/net/pcmcia/pcnet_cs.c | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 808fae1577e0..50dff1b81d34 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -521,6 +521,7 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value) static int axnet_open(struct net_device *dev) { + int ret; axnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; @@ -529,9 +530,11 @@ static int axnet_open(struct net_device *dev) if (!pcmcia_dev_present(link)) return -ENODEV; - link->open++; + ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); + if (ret) + return ret; - request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); + link->open++; info->link_status = 0x00; init_timer(&info->watchdog); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 61f7a4f3ee65..f2613c29b008 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -960,6 +960,7 @@ static void mii_phy_probe(struct net_device *dev) static int pcnet_open(struct net_device *dev) { + int ret; pcnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; @@ -968,10 +969,12 @@ static int pcnet_open(struct net_device *dev) if (!pcmcia_dev_present(link)) return -ENODEV; - link->open++; - set_misc_reg(dev); - request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); + ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); + if (ret) + return ret; + + link->open++; info->phy_id = info->eth_phy; info->link_status = 0x00; From 91e745aa46336087e1295d44685ee2839bbba07d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 30 May 2007 14:23:18 -0700 Subject: [PATCH 090/551] qla3xxx: cleanup checksum offload code The code for checksum is more complex than needed when dealing with VLAN's; the higher layers already pass down the location of the IP header. Compile tested only, no hardware available. Signed-off-by: Stephen Hemminger Signed-off-by: Ron Mercer Signed-off-by: Jeff Garzik --- drivers/net/qla3xxx.c | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 585be044ebbb..8be8be451ada 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2433,37 +2433,22 @@ static int ql_get_seg_count(struct ql3_adapter *qdev, return -1; } -static void ql_hw_csum_setup(struct sk_buff *skb, +static void ql_hw_csum_setup(const struct sk_buff *skb, struct ob_mac_iocb_req *mac_iocb_ptr) { - struct ethhdr *eth; - struct iphdr *ip = NULL; - u8 offset = ETH_HLEN; + const struct iphdr *ip = ip_hdr(skb); - eth = (struct ethhdr *)(skb->data); + mac_iocb_ptr->ip_hdr_off = skb_network_offset(skb); + mac_iocb_ptr->ip_hdr_len = ip->ihl; - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[ETH_HLEN]; - } else if (eth->h_proto == htons(ETH_P_8021Q) && - ((struct vlan_ethhdr *)skb->data)-> - h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) { - ip = (struct iphdr *)&skb->data[VLAN_ETH_HLEN]; - offset = VLAN_ETH_HLEN; + if (ip->protocol == IPPROTO_TCP) { + mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC | + OB_3032MAC_IOCB_REQ_IC; + } else { + mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC | + OB_3032MAC_IOCB_REQ_IC; } - if (ip) { - if (ip->protocol == IPPROTO_TCP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC | - OB_3032MAC_IOCB_REQ_IC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } else if (ip->protocol == IPPROTO_UDP) { - mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC | - OB_3032MAC_IOCB_REQ_IC; - mac_iocb_ptr->ip_hdr_off = offset; - mac_iocb_ptr->ip_hdr_len = ip->ihl; - } - } } /* From e6311d855e100184d42c0165ab9d5215fd792c89 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 13:41:38 -0500 Subject: [PATCH 091/551] spidernet: beautify error messages Use dev_err() to print device error messages. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 64 +++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 7a4aa6a9f949..4c8243a7f9c1 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -434,7 +434,8 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, bufsize + SPIDER_NET_RXBUF_ALIGN - 1); if (!descr->skb) { if (netif_msg_rx_err(card) && net_ratelimit()) - pr_err("Not enough memory to allocate rx buffer\n"); + dev_err(&card->netdev->dev, + "Not enough memory to allocate rx buffer\n"); card->spider_stats.alloc_rx_skb_error++; return -ENOMEM; } @@ -455,7 +456,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, dev_kfree_skb_any(descr->skb); descr->skb = NULL; if (netif_msg_rx_err(card) && net_ratelimit()) - pr_err("Could not iommu-map rx buffer\n"); + dev_err(&card->netdev->dev, "Could not iommu-map rx buffer\n"); card->spider_stats.rx_iommu_map_error++; hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; } else { @@ -692,7 +693,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) - pr_err("could not iommu-map packet (%p, %i). " + dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); card->spider_stats.tx_iommu_map_error++; return -ENOMEM; @@ -832,9 +833,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) case SPIDER_NET_DESCR_PROTECTION_ERROR: case SPIDER_NET_DESCR_FORCE_END: if (netif_msg_tx_err(card)) - pr_err("%s: forcing end of tx descriptor " - "with status x%02x\n", - card->netdev->name, status); + dev_err(&card->netdev->dev, "forcing end of tx descriptor " + "with status x%02x\n", status); card->netdev_stats.tx_errors++; break; @@ -1147,8 +1147,8 @@ spider_net_decode_one_descr(struct spider_net_card *card) (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || (status == SPIDER_NET_DESCR_FORCE_END) ) { if (netif_msg_rx_err(card)) - pr_err("%s: dropping RX descriptor with state %d\n", - card->netdev->name, status); + dev_err(&card->netdev->dev, + "dropping RX descriptor with state %d\n", status); card->netdev_stats.rx_dropped++; goto bad_desc; } @@ -1156,8 +1156,8 @@ spider_net_decode_one_descr(struct spider_net_card *card) if ( (status != SPIDER_NET_DESCR_COMPLETE) && (status != SPIDER_NET_DESCR_FRAME_END) ) { if (netif_msg_rx_err(card)) - pr_err("%s: RX descriptor with unknown state %d\n", - card->netdev->name, status); + dev_err(&card->netdev->dev, + "RX descriptor with unknown state %d\n", status); card->spider_stats.rx_desc_unk_state++; goto bad_desc; } @@ -1165,16 +1165,15 @@ spider_net_decode_one_descr(struct spider_net_card *card) /* The cases we'll throw away the packet immediately */ if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { if (netif_msg_rx_err(card)) - pr_err("%s: error in received descriptor found, " + dev_err(&card->netdev->dev, + "error in received descriptor found, " "data_status=x%08x, data_error=x%08x\n", - card->netdev->name, hwdescr->data_status, hwdescr->data_error); goto bad_desc; } if (hwdescr->dmac_cmd_status & 0xfcf4) { - pr_err("%s: bad status, cmd_status=x%08x\n", - card->netdev->name, + dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n", hwdescr->dmac_cmd_status); pr_err("buf_addr=x%08x\n", hwdescr->buf_addr); pr_err("buf_size=x%08x\n", hwdescr->buf_size); @@ -1415,7 +1414,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GPWFFINT: /* PHY command queue full */ if (netif_msg_intr(card)) - pr_err("PHY write queue full\n"); + dev_err(&card->netdev->dev, "PHY write queue full\n"); show_error = 0; break; @@ -1582,9 +1581,8 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) } if ((show_error) && (netif_msg_intr(card)) && net_ratelimit()) - pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " + dev_err(&card->netdev->dev, "Error interrupt, GHIINT0STS = 0x%08x, " "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", - card->netdev->name, status_reg, error_reg1, error_reg2); /* clear interrupt sources */ @@ -1849,7 +1847,8 @@ spider_net_init_firmware(struct spider_net_card *card) SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && netif_msg_probe(card) ) { - pr_err("Incorrect size of spidernet firmware in " \ + dev_err(&card->netdev->dev, + "Incorrect size of spidernet firmware in " \ "filesystem. Looking in host firmware...\n"); goto try_host_fw; } @@ -1873,8 +1872,8 @@ try_host_fw: if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && netif_msg_probe(card) ) { - pr_err("Incorrect size of spidernet firmware in " \ - "host firmware\n"); + dev_err(&card->netdev->dev, + "Incorrect size of spidernet firmware in host firmware\n"); goto done; } @@ -1884,7 +1883,8 @@ done: return err; out_err: if (netif_msg_probe(card)) - pr_err("Couldn't find spidernet firmware in filesystem " \ + dev_err(&card->netdev->dev, + "Couldn't find spidernet firmware in filesystem " \ "or host firmware\n"); return err; } @@ -2279,13 +2279,14 @@ spider_net_setup_netdev(struct spider_net_card *card) result = spider_net_set_mac(netdev, &addr); if ((result) && (netif_msg_probe(card))) - pr_err("Failed to set MAC address: %i\n", result); + dev_err(&card->netdev->dev, + "Failed to set MAC address: %i\n", result); result = register_netdev(netdev); if (result) { if (netif_msg_probe(card)) - pr_err("Couldn't register net_device: %i\n", - result); + dev_err(&card->netdev->dev, + "Couldn't register net_device: %i\n", result); return result; } @@ -2363,17 +2364,19 @@ spider_net_setup_pci_dev(struct pci_dev *pdev) unsigned long mmio_start, mmio_len; if (pci_enable_device(pdev)) { - pr_err("Couldn't enable PCI device\n"); + dev_err(&pdev->dev, "Couldn't enable PCI device\n"); return NULL; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - pr_err("Couldn't find proper PCI device base address.\n"); + dev_err(&pdev->dev, + "Couldn't find proper PCI device base address.\n"); goto out_disable_dev; } if (pci_request_regions(pdev, spider_net_driver_name)) { - pr_err("Couldn't obtain PCI resources, aborting.\n"); + dev_err(&pdev->dev, + "Couldn't obtain PCI resources, aborting.\n"); goto out_disable_dev; } @@ -2381,8 +2384,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev) card = spider_net_alloc_card(); if (!card) { - pr_err("Couldn't allocate net_device structure, " - "aborting.\n"); + dev_err(&pdev->dev, + "Couldn't allocate net_device structure, aborting.\n"); goto out_release_regions; } card->pdev = pdev; @@ -2396,7 +2399,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev) card->regs = ioremap(mmio_start, mmio_len); if (!card->regs) { - pr_err("Couldn't obtain PCI resources, aborting.\n"); + dev_err(&pdev->dev, + "Couldn't obtain PCI resources, aborting.\n"); goto out_release_regions; } From 9948357d49c84102151bc14233c2f489552c1f57 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 13:48:55 -0500 Subject: [PATCH 092/551] spidernet: enhance the dump routine Crazy device problems are hard to debug, when one does not have good trace info. This patch makes a major enhancement to the device dump routine. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 78 +++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 4c8243a7f9c1..4d180072de4d 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1022,34 +1022,94 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, netif_receive_skb(skb); } -#ifdef DEBUG static void show_rx_chain(struct spider_net_card *card) { struct spider_net_descr_chain *chain = &card->rx_chain; struct spider_net_descr *start= chain->tail; struct spider_net_descr *descr= start; + struct spider_net_hw_descr *hwd = start->hwdescr; + struct device *dev = &card->netdev->dev; + u32 curr_desc, next_desc; int status; + int tot = 0; int cnt = 0; - int cstat = spider_net_get_descr_status(descr); - printk(KERN_INFO "RX chain tail at descr=%ld\n", - (start - card->descr) - card->tx_chain.num_desc); + int off = start - chain->ring; + int cstat = hwd->dmac_cmd_status; + + dev_info(dev, "Total number of descrs=%d\n", + chain->num_desc); + dev_info(dev, "Chain tail located at descr=%d, status=0x%x\n", + off, cstat); + + curr_desc = spider_net_read_reg(card, SPIDER_NET_GDACTDPA); + next_desc = spider_net_read_reg(card, SPIDER_NET_GDACNEXTDA); + status = cstat; do { - status = spider_net_get_descr_status(descr); + hwd = descr->hwdescr; + off = descr - chain->ring; + status = hwd->dmac_cmd_status; + + if (descr == chain->head) + dev_info(dev, "Chain head is at %d, head status=0x%x\n", + off, status); + + if (curr_desc == descr->bus_addr) + dev_info(dev, "HW curr desc (GDACTDPA) is at %d, status=0x%x\n", + off, status); + + if (next_desc == descr->bus_addr) + dev_info(dev, "HW next desc (GDACNEXTDA) is at %d, status=0x%x\n", + off, status); + + if (hwd->next_descr_addr == 0) + dev_info(dev, "chain is cut at %d\n", off); + if (cstat != status) { - printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat); + int from = (chain->num_desc + off - cnt) % chain->num_desc; + int to = (chain->num_desc + off - 1) % chain->num_desc; + dev_info(dev, "Have %d (from %d to %d) descrs " + "with stat=0x%08x\n", cnt, from, to, cstat); cstat = status; cnt = 0; } + cnt ++; + tot ++; + descr = descr->next; + } while (descr != start); + + dev_info(dev, "Last %d descrs with stat=0x%08x " + "for a total of %d descrs\n", cnt, cstat, tot); + +#ifdef DEBUG + /* Now dump the whole ring */ + descr = start; + do + { + struct spider_net_hw_descr *hwd = descr->hwdescr; + status = spider_net_get_descr_status(hwd); + cnt = descr - chain->ring; + dev_info(dev, "Descr %d stat=0x%08x skb=%p\n", + cnt, status, descr->skb); + dev_info(dev, "bus addr=%08x buf addr=%08x sz=%d\n", + descr->bus_addr, hwd->buf_addr, hwd->buf_size); + dev_info(dev, "next=%08x result sz=%d valid sz=%d\n", + hwd->next_descr_addr, hwd->result_size, + hwd->valid_size); + dev_info(dev, "dmac=%08x data stat=%08x data err=%08x\n", + hwd->dmac_cmd_status, hwd->data_status, + hwd->data_error); + dev_info(dev, "\n"); + descr = descr->next; } while (descr != start); - printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat); -} #endif +} + /** * spider_net_resync_head_ptr - Advance head ptr past empty descrs * @@ -1195,6 +1255,8 @@ spider_net_decode_one_descr(struct spider_net_card *card) return 1; bad_desc: + if (netif_msg_rx_err(card)) + show_rx_chain(card); dev_kfree_skb_irq(descr->skb); descr->skb = NULL; hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; From 9e0a6e2598ac08d14c3388567eae9a4ccea1244f Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 13:52:03 -0500 Subject: [PATCH 093/551] spidernet: invalidate unused pointer. Invalidate a pointer as its pci_unmap'ed; this is a bit of paranoia to make sure hardware doesn't continue trying to DMA to it. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 4d180072de4d..628efc01f273 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1187,6 +1187,7 @@ spider_net_decode_one_descr(struct spider_net_card *card) struct spider_net_descr_chain *chain = &card->rx_chain; struct spider_net_descr *descr = chain->tail; struct spider_net_hw_descr *hwdescr = descr->hwdescr; + u32 hw_buf_addr; int status; status = spider_net_get_descr_status(hwdescr); @@ -1200,7 +1201,9 @@ spider_net_decode_one_descr(struct spider_net_card *card) chain->tail = descr->next; /* unmap descriptor */ - pci_unmap_single(card->pdev, hwdescr->buf_addr, + hw_buf_addr = hwdescr->buf_addr; + hwdescr->buf_addr = 0xffffffff; + pci_unmap_single(card->pdev, hw_buf_addr, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || @@ -1235,7 +1238,7 @@ spider_net_decode_one_descr(struct spider_net_card *card) if (hwdescr->dmac_cmd_status & 0xfcf4) { dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n", hwdescr->dmac_cmd_status); - pr_err("buf_addr=x%08x\n", hwdescr->buf_addr); + pr_err("buf_addr=x%08x\n", hw_buf_addr); pr_err("buf_size=x%08x\n", hwdescr->buf_size); pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr); pr_err("result_size=x%08x\n", hwdescr->result_size); From e1fd9070729765910b144ffcf74ca199c766509b Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 13:59:21 -0500 Subject: [PATCH 094/551] spidernet: service TX later. When entering the netdev poll routine, empty out the RX chain first, before cleaning up the TX chain. This should help avoid RX buffer overflows. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 628efc01f273..946b2e244f65 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1285,7 +1285,6 @@ spider_net_poll(struct net_device *netdev, int *budget) int packets_to_do, packets_done = 0; int no_more_packets = 0; - spider_net_cleanup_tx_ring(card); packets_to_do = min(*budget, netdev->quota); while (packets_to_do) { @@ -1310,6 +1309,8 @@ spider_net_poll(struct net_device *netdev, int *budget) spider_net_refill_rx_chain(card); spider_net_enable_rxdmac(card); + spider_net_cleanup_tx_ring(card); + /* if all packets are in the stack, enable interrupts and return 0 */ /* if not, return 1 */ if (no_more_packets) { From 59a11f8809ada4b89ac079fb7f549eaca0554f94 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 14:05:41 -0500 Subject: [PATCH 095/551] spidernet: move a block of code around Put the enable and disable routines next to one-another, as this makes verifying thier symmetry that much easier. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 946b2e244f65..8fa9ff72d1a6 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -500,6 +500,20 @@ spider_net_enable_rxdmac(struct spider_net_card *card) SPIDER_NET_DMA_RX_VALUE); } +/** + * spider_net_disable_rxdmac - disables the receive DMA controller + * @card: card structure + * + * spider_net_disable_rxdmac terminates processing on the DMA controller + * by turing off the DMA controller, with the force-end flag set. + */ +static inline void +spider_net_disable_rxdmac(struct spider_net_card *card) +{ + spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, + SPIDER_NET_DMA_RX_FEND_VALUE); +} + /** * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains * @card: card structure @@ -655,20 +669,6 @@ write_hash: } } -/** - * spider_net_disable_rxdmac - disables the receive DMA controller - * @card: card structure - * - * spider_net_disable_rxdmac terminates processing on the DMA controller by - * turing off DMA and issueing a force end - */ -static void -spider_net_disable_rxdmac(struct spider_net_card *card) -{ - spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, - SPIDER_NET_DMA_RX_FEND_VALUE); -} - /** * spider_net_prepare_tx_descr - fill tx descriptor with skb data * @card: card structure From 5f309b90e242a4a9c5519ed113801a7ad542cd48 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 14:09:16 -0500 Subject: [PATCH 096/551] spidernet: fix misnamed flag The transmit frame tail bit is stranglely misnamed as "no checksum". Fix the name to what it should be: "transmit frame tail". No functional change, just a name change. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 2 +- drivers/net/spider_net.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 8fa9ff72d1a6..9d3ae35767b4 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -716,7 +716,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, hwdescr->data_status = 0; hwdescr->dmac_cmd_status = - SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; + SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_TXFRMTL; spin_unlock_irqrestore(&chain->lock, flags); if (skb->ip_summed == CHECKSUM_PARTIAL) diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 1d054aa71504..04007d7b0e41 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -349,7 +349,7 @@ enum spider_net_int2_status { #define SPIDER_NET_GPRDAT_MASK 0x0000ffff #define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 -#define SPIDER_NET_DMAC_NOCS 0x00040000 +#define SPIDER_NET_DMAC_TXFRMTL 0x00040000 #define SPIDER_NET_DMAC_TCP 0x00020000 #define SPIDER_NET_DMAC_UDP 0x00030000 #define SPIDER_NET_TXDCEST 0x08000000 From 3213e3abc68c776589d574decf3e6aee0467d12c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 11 Jun 2007 14:12:09 -0500 Subject: [PATCH 097/551] spidernet: driver docmentation Documentation for the spidernet driver. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- Documentation/networking/spider_net.txt | 204 ++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 Documentation/networking/spider_net.txt diff --git a/Documentation/networking/spider_net.txt b/Documentation/networking/spider_net.txt new file mode 100644 index 000000000000..4b4adb8eb14f --- /dev/null +++ b/Documentation/networking/spider_net.txt @@ -0,0 +1,204 @@ + + The Spidernet Device Driver + =========================== + +Written by Linas Vepstas + +Version of 7 June 2007 + +Abstract +======== +This document sketches the structure of portions of the spidernet +device driver in the Linux kernel tree. The spidernet is a gigabit +ethernet device built into the Toshiba southbridge commonly used +in the SONY Playstation 3 and the IBM QS20 Cell blade. + +The Structure of the RX Ring. +============================= +The receive (RX) ring is a circular linked list of RX descriptors, +together with three pointers into the ring that are used to manage its +contents. + +The elements of the ring are called "descriptors" or "descrs"; they +describe the received data. This includes a pointer to a buffer +containing the received data, the buffer size, and various status bits. + +There are three primary states that a descriptor can be in: "empty", +"full" and "not-in-use". An "empty" or "ready" descriptor is ready +to receive data from the hardware. A "full" descriptor has data in it, +and is waiting to be emptied and processed by the OS. A "not-in-use" +descriptor is neither empty or full; it is simply not ready. It may +not even have a data buffer in it, or is otherwise unusable. + +During normal operation, on device startup, the OS (specifically, the +spidernet device driver) allocates a set of RX descriptors and RX +buffers. These are all marked "empty", ready to receive data. This +ring is handed off to the hardware, which sequentially fills in the +buffers, and marks them "full". The OS follows up, taking the full +buffers, processing them, and re-marking them empty. + +This filling and emptying is managed by three pointers, the "head" +and "tail" pointers, managed by the OS, and a hardware current +descriptor pointer (GDACTDPA). The GDACTDPA points at the descr +currently being filled. When this descr is filled, the hardware +marks it full, and advances the GDACTDPA by one. Thus, when there is +flowing RX traffic, every descr behind it should be marked "full", +and everything in front of it should be "empty". If the hardware +discovers that the current descr is not empty, it will signal an +interrupt, and halt processing. + +The tail pointer tails or trails the hardware pointer. When the +hardware is ahead, the tail pointer will be pointing at a "full" +descr. The OS will process this descr, and then mark it "not-in-use", +and advance the tail pointer. Thus, when there is flowing RX traffic, +all of the descrs in front of the tail pointer should be "full", and +all of those behind it should be "not-in-use". When RX traffic is not +flowing, then the tail pointer can catch up to the hardware pointer. +The OS will then note that the current tail is "empty", and halt +processing. + +The head pointer (somewhat mis-named) follows after the tail pointer. +When traffic is flowing, then the head pointer will be pointing at +a "not-in-use" descr. The OS will perform various housekeeping duties +on this descr. This includes allocating a new data buffer and +dma-mapping it so as to make it visible to the hardware. The OS will +then mark the descr as "empty", ready to receive data. Thus, when there +is flowing RX traffic, everything in front of the head pointer should +be "not-in-use", and everything behind it should be "empty". If no +RX traffic is flowing, then the head pointer can catch up to the tail +pointer, at which point the OS will notice that the head descr is +"empty", and it will halt processing. + +Thus, in an idle system, the GDACTDPA, tail and head pointers will +all be pointing at the same descr, which should be "empty". All of the +other descrs in the ring should be "empty" as well. + +The show_rx_chain() routine will print out the the locations of the +GDACTDPA, tail and head pointers. It will also summarize the contents +of the ring, starting at the tail pointer, and listing the status +of the descrs that follow. + +A typical example of the output, for a nearly idle system, might be + +net eth1: Total number of descrs=256 +net eth1: Chain tail located at descr=20 +net eth1: Chain head is at 20 +net eth1: HW curr desc (GDACTDPA) is at 21 +net eth1: Have 1 descrs with stat=x40800101 +net eth1: HW next desc (GDACNEXTDA) is at 22 +net eth1: Last 255 descrs with stat=xa0800000 + +In the above, the hardware has filled in one descr, number 20. Both +head and tail are pointing at 20, because it has not yet been emptied. +Meanwhile, hw is pointing at 21, which is free. + +The "Have nnn decrs" refers to the descr starting at the tail: in this +case, nnn=1 descr, starting at descr 20. The "Last nnn descrs" refers +to all of the rest of the descrs, from the last status change. The "nnn" +is a count of how many descrs have exactly the same status. + +The status x4... corresponds to "full" and status xa... corresponds +to "empty". The actual value printed is RXCOMST_A. + +In the device driver source code, a different set of names are +used for these same concepts, so that + +"empty" == SPIDER_NET_DESCR_CARDOWNED == 0xa +"full" == SPIDER_NET_DESCR_FRAME_END == 0x4 +"not in use" == SPIDER_NET_DESCR_NOT_IN_USE == 0xf + + +The RX RAM full bug/feature +=========================== + +As long as the OS can empty out the RX buffers at a rate faster than +the hardware can fill them, there is no problem. If, for some reason, +the OS fails to empty the RX ring fast enough, the hardware GDACTDPA +pointer will catch up to the head, notice the not-empty condition, +ad stop. However, RX packets may still continue arriving on the wire. +The spidernet chip can save some limited number of these in local RAM. +When this local ram fills up, the spider chip will issue an interrupt +indicating this (GHIINT0STS will show ERRINT, and the GRMFLLINT bit +will be set in GHIINT1STS). When the RX ram full condition occurs, +a certain bug/feature is triggered that has to be specially handled. +This section describes the special handling for this condition. + +When the OS finally has a chance to run, it will empty out the RX ring. +In particular, it will clear the descriptor on which the hardware had +stopped. However, once the hardware has decided that a certain +descriptor is invalid, it will not restart at that descriptor; instead +it will restart at the next descr. This potentially will lead to a +deadlock condition, as the tail pointer will be pointing at this descr, +which, from the OS point of view, is empty; the OS will be waiting for +this descr to be filled. However, the hardware has skipped this descr, +and is filling the next descrs. Since the OS doesn't see this, there +is a potential deadlock, with the OS waiting for one descr to fill, +while the hardware is waiting for a different set of descrs to become +empty. + +A call to show_rx_chain() at this point indicates the nature of the +problem. A typical print when the network is hung shows the following: + +net eth1: Spider RX RAM full, incoming packets might be discarded! +net eth1: Total number of descrs=256 +net eth1: Chain tail located at descr=255 +net eth1: Chain head is at 255 +net eth1: HW curr desc (GDACTDPA) is at 0 +net eth1: Have 1 descrs with stat=xa0800000 +net eth1: HW next desc (GDACNEXTDA) is at 1 +net eth1: Have 127 descrs with stat=x40800101 +net eth1: Have 1 descrs with stat=x40800001 +net eth1: Have 126 descrs with stat=x40800101 +net eth1: Last 1 descrs with stat=xa0800000 + +Both the tail and head pointers are pointing at descr 255, which is +marked xa... which is "empty". Thus, from the OS point of view, there +is nothing to be done. In particular, there is the implicit assumption +that everything in front of the "empty" descr must surely also be empty, +as explained in the last section. The OS is waiting for descr 255 to +become non-empty, which, in this case, will never happen. + +The HW pointer is at descr 0. This descr is marked 0x4.. or "full". +Since its already full, the hardware can do nothing more, and thus has +halted processing. Notice that descrs 0 through 254 are all marked +"full", while descr 254 and 255 are empty. (The "Last 1 descrs" is +descr 254, since tail was at 255.) Thus, the system is deadlocked, +and there can be no forward progress; the OS thinks there's nothing +to do, and the hardware has nowhere to put incoming data. + +This bug/feature is worked around with the spider_net_resync_head_ptr() +routine. When the driver receives RX interrupts, but an examination +of the RX chain seems to show it is empty, then it is probable that +the hardware has skipped a descr or two (sometimes dozens under heavy +network conditions). The spider_net_resync_head_ptr() subroutine will +search the ring for the next full descr, and the driver will resume +operations there. Since this will leave "holes" in the ring, there +is also a spider_net_resync_tail_ptr() that will skip over such holes. + +As of this writing, the spider_net_resync() strategy seems to work very +well, even under heavy network loads. + + +The TX ring +=========== +The TX ring uses a low-watermark interrupt scheme to make sure that +the TX queue is appropriately serviced for large packet sizes. + +For packet sizes greater than about 1KBytes, the kernel can fill +the TX ring quicker than the device can drain it. Once the ring +is full, the netdev is stopped. When there is room in the ring, +the netdev needs to be reawakened, so that more TX packets are placed +in the ring. The hardware can empty the ring about four times per jiffy, +so its not appropriate to wait for the poll routine to refill, since +the poll routine runs only once per jiffy. The low-watermark mechanism +marks a descr about 1/4th of the way from the bottom of the queue, so +that an interrupt is generated when the descr is processed. This +interrupt wakes up the netdev, which can then refill the queue. +For large packets, this mechanism generates a relatively small number +of interrupts, about 1K/sec. For smaller packets, this will drop to zero +interrupts, as the hardware can empty the queue faster than the kernel +can fill it. + + + ======= END OF DOCUMENT ======== + From 3ead5db7bcd343917e567c083f5faf45f5301664 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:21 -0700 Subject: [PATCH 098/551] sky2: avoid reserved regions on ethtool reg dump On Yukon EX reading some of the undocumented places in the memory space will cause a hang. Since they don't provide useful information, just skip the reserved areas. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fe01b961b597..612257172b95 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3330,7 +3330,7 @@ static int sky2_get_regs_len(struct net_device *dev) /* * Returns copy of control register region - * Note: access to the RAM address register set will cause timeouts. + * Note: ethtool_get_regs always provides full size (16k) buffer */ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) @@ -3338,15 +3338,19 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, const struct sky2_port *sky2 = netdev_priv(dev); const void __iomem *io = sky2->hw->regs; - BUG_ON(regs->len < B3_RI_WTO_R1); regs->version = 1; memset(p, 0, regs->len); memcpy_fromio(p, io, B3_RAM_ADDR); - memcpy_fromio(p + B3_RI_WTO_R1, - io + B3_RI_WTO_R1, - regs->len - B3_RI_WTO_R1); + /* skip diagnostic ram region */ + memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1); + + /* copy GMAC registers */ + memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000); + if (sky2->hw->ports > 1) + memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000); + } /* In order to do Jumbo packets on these chips, need to turn off the From fc99fe0618f355b708ce88fedaca9783072ac3d5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:22 -0700 Subject: [PATCH 099/551] sky2: Add PCI device specfic register 4 & 5 Need to setup more PCI control control registers are on Yukon EX. Some of these also exist on Yukon EC-U as well. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 18 +++++++---- drivers/net/sky2.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 612257172b95..0bd74fe5c338 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -217,13 +217,19 @@ static void sky2_power_on(struct sky2_hw *hw) sky2_write8(hw, B2_Y2_CLK_GATE, 0); if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { - u32 reg1; + u32 reg; - sky2_pci_write32(hw, PCI_DEV_REG3, 0); - reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); - reg1 &= P_ASPM_CONTROL_MSK; - sky2_pci_write32(hw, PCI_DEV_REG4, reg1); - sky2_pci_write32(hw, PCI_DEV_REG5, 0); + reg = sky2_pci_read32(hw, PCI_DEV_REG4); + /* set all bits to 0 except bits 15..12 and 8 */ + reg &= P_ASPM_CONTROL_MSK; + sky2_pci_write32(hw, PCI_DEV_REG4, reg); + + reg = sky2_pci_read32(hw, PCI_DEV_REG5); + /* set all bits to 0 except bits 28 & 27 */ + reg &= P_CTL_TIM_VMAIN_AV_MSK; + sky2_pci_write32(hw, PCI_DEV_REG5, reg); + + sky2_pci_write32(hw, PCI_CFG_REG_1, 0); } } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index b8c4a3b5eadf..3caeddf893ef 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -14,6 +14,8 @@ enum { PCI_DEV_REG3 = 0x80, PCI_DEV_REG4 = 0x84, PCI_DEV_REG5 = 0x88, + PCI_CFG_REG_0 = 0x90, + PCI_CFG_REG_1 = 0x94, }; enum { @@ -28,6 +30,7 @@ enum { enum pci_dev_reg_1 { PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ PCI_Y2_DLL_DIS = 1<<30, /* Disable PCI DLL (YUKON-2) */ + PCI_SW_PWR_ON_RST= 1<<30, /* SW Power on Reset (Yukon-EX) */ PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */ PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */ PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */ @@ -67,6 +70,80 @@ enum pci_dev_reg_4 { | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY, }; +/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */ +enum pci_dev_reg_5 { + /* Bit 31..27: for A3 & later */ + P_CTL_DIV_CORE_CLK_ENA = 1<<31, /* Divide Core Clock Enable */ + P_CTL_SRESET_VMAIN_AV = 1<<30, /* Soft Reset for Vmain_av De-Glitch */ + P_CTL_BYPASS_VMAIN_AV = 1<<29, /* Bypass En. for Vmain_av De-Glitch */ + P_CTL_TIM_VMAIN_AV_MSK = 3<<27, /* Bit 28..27: Timer Vmain_av Mask */ + /* Bit 26..16: Release Clock on Event */ + P_REL_PCIE_RST_DE_ASS = 1<<26, /* PCIe Reset De-Asserted */ + P_REL_GPHY_REC_PACKET = 1<<25, /* GPHY Received Packet */ + P_REL_INT_FIFO_N_EMPTY = 1<<24, /* Internal FIFO Not Empty */ + P_REL_MAIN_PWR_AVAIL = 1<<23, /* Main Power Available */ + P_REL_CLKRUN_REQ_REL = 1<<22, /* CLKRUN Request Release */ + P_REL_PCIE_RESET_ASS = 1<<21, /* PCIe Reset Asserted */ + P_REL_PME_ASSERTED = 1<<20, /* PME Asserted */ + P_REL_PCIE_EXIT_L1_ST = 1<<19, /* PCIe Exit L1 State */ + P_REL_LOADER_NOT_FIN = 1<<18, /* EPROM Loader Not Finished */ + P_REL_PCIE_RX_EX_IDLE = 1<<17, /* PCIe Rx Exit Electrical Idle State */ + P_REL_GPHY_LINK_UP = 1<<16, /* GPHY Link Up */ + + /* Bit 10.. 0: Mask for Gate Clock */ + P_GAT_PCIE_RST_ASSERTED = 1<<10,/* PCIe Reset Asserted */ + P_GAT_GPHY_N_REC_PACKET = 1<<9, /* GPHY Not Received Packet */ + P_GAT_INT_FIFO_EMPTY = 1<<8, /* Internal FIFO Empty */ + P_GAT_MAIN_PWR_N_AVAIL = 1<<7, /* Main Power Not Available */ + P_GAT_CLKRUN_REQ_REL = 1<<6, /* CLKRUN Not Requested */ + P_GAT_PCIE_RESET_ASS = 1<<5, /* PCIe Reset Asserted */ + P_GAT_PME_DE_ASSERTED = 1<<4, /* PME De-Asserted */ + P_GAT_PCIE_ENTER_L1_ST = 1<<3, /* PCIe Enter L1 State */ + P_GAT_LOADER_FINISHED = 1<<2, /* EPROM Loader Finished */ + P_GAT_PCIE_RX_EL_IDLE = 1<<1, /* PCIe Rx Electrical Idle State */ + P_GAT_GPHY_LINK_DOWN = 1<<0, /* GPHY Link Down */ + + PCIE_OUR5_EVENT_CLK_D3_SET = P_REL_GPHY_REC_PACKET | + P_REL_INT_FIFO_N_EMPTY | + P_REL_PCIE_EXIT_L1_ST | + P_REL_PCIE_RX_EX_IDLE | + P_GAT_GPHY_N_REC_PACKET | + P_GAT_INT_FIFO_EMPTY | + P_GAT_PCIE_ENTER_L1_ST | + P_GAT_PCIE_RX_EL_IDLE, +}; + +#/* PCI_CFG_REG_1 32 bit Config Register 1 (Yukon-Ext only) */ +enum pci_cfg_reg1 { + P_CF1_DIS_REL_EVT_RST = 1<<24, /* Dis. Rel. Event during PCIE reset */ + /* Bit 23..21: Release Clock on Event */ + P_CF1_REL_LDR_NOT_FIN = 1<<23, /* EEPROM Loader Not Finished */ + P_CF1_REL_VMAIN_AVLBL = 1<<22, /* Vmain available */ + P_CF1_REL_PCIE_RESET = 1<<21, /* PCI-E reset */ + /* Bit 20..18: Gate Clock on Event */ + P_CF1_GAT_LDR_NOT_FIN = 1<<20, /* EEPROM Loader Finished */ + P_CF1_GAT_PCIE_RX_IDLE = 1<<19, /* PCI-E Rx Electrical idle */ + P_CF1_GAT_PCIE_RESET = 1<<18, /* PCI-E Reset */ + P_CF1_PRST_PHY_CLKREQ = 1<<17, /* Enable PCI-E rst & PM2PHY gen. CLKREQ */ + P_CF1_PCIE_RST_CLKREQ = 1<<16, /* Enable PCI-E rst generate CLKREQ */ + + P_CF1_ENA_CFG_LDR_DONE = 1<<8, /* Enable core level Config loader done */ + + P_CF1_ENA_TXBMU_RD_IDLE = 1<<1, /* Enable TX BMU Read IDLE for ASPM */ + P_CF1_ENA_TXBMU_WR_IDLE = 1<<0, /* Enable TX BMU Write IDLE for ASPM */ + + PCIE_CFG1_EVENT_CLK_D3_SET = P_CF1_DIS_REL_EVT_RST | + P_CF1_REL_LDR_NOT_FIN | + P_CF1_REL_VMAIN_AVLBL | + P_CF1_REL_PCIE_RESET | + P_CF1_GAT_LDR_NOT_FIN | + P_CF1_GAT_PCIE_RESET | + P_CF1_PRST_PHY_CLKREQ | + P_CF1_ENA_CFG_LDR_DONE | + P_CF1_ENA_TXBMU_RD_IDLE | + P_CF1_ENA_TXBMU_WR_IDLE, +}; + #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \ From f449c7c10698e49e6c654452f852b1b719273d8a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:23 -0700 Subject: [PATCH 100/551] sky2: rename BMU register This register is more of a test and control register on Yukon2. So rename it to Q_TEST and give some bit definitions. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 +- drivers/net/sky2.h | 29 +++++++++++------------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 0bd74fe5c338..5b3a866a0b1c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1140,7 +1140,7 @@ static int sky2_rx_start(struct sky2_port *sky2) if (hw->chip_id == CHIP_ID_YUKON_EC_U && (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) - sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); + sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 3caeddf893ef..00907f58019e 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -592,23 +592,15 @@ enum { enum { B8_Q_REGS = 0x0400, /* base of Queue registers */ Q_D = 0x00, /* 8*32 bit Current Descriptor */ - Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ - Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ + Q_VLAN = 0x20, /* 16 bit Current VLAN Tag */ + Q_DONE = 0x24, /* 16 bit Done Index */ Q_AC_L = 0x28, /* 32 bit Current Address Counter Low dWord */ Q_AC_H = 0x2c, /* 32 bit Current Address Counter High dWord */ Q_BC = 0x30, /* 32 bit Current Byte Counter */ Q_CSR = 0x34, /* 32 bit BMU Control/Status Register */ - Q_F = 0x38, /* 32 bit Flag Register */ - Q_T1 = 0x3c, /* 32 bit Test Register 1 */ - Q_T1_TR = 0x3c, /* 8 bit Test Register 1 Transfer SM */ - Q_T1_WR = 0x3d, /* 8 bit Test Register 1 Write Descriptor SM */ - Q_T1_RD = 0x3e, /* 8 bit Test Register 1 Read Descriptor SM */ - Q_T1_SV = 0x3f, /* 8 bit Test Register 1 Supervisor SM */ - Q_T2 = 0x40, /* 32 bit Test Register 2 */ - Q_T3 = 0x44, /* 32 bit Test Register 3 */ + Q_TEST = 0x38, /* 32 bit Test/Control Register */ /* Yukon-2 */ - Q_DONE = 0x24, /* 16 bit Done Index (Yukon-2 only) */ Q_WM = 0x40, /* 16 bit FIFO Watermark */ Q_AL = 0x42, /* 8 bit FIFO Alignment */ Q_RSP = 0x44, /* 16 bit FIFO Read Shadow Pointer */ @@ -622,15 +614,16 @@ enum { }; #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs)) -/* Q_F 32 bit Flag Register */ +/* Q_TEST 32 bit Test Register */ enum { - F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */ - F_EMPTY = 1<<27, /* Tx FIFO: empty flag */ - F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */ - F_WM_REACHED = 1<<25, /* Watermark reached */ + /* Transmit */ + F_TX_CHK_AUTO_OFF = 1<<31, /* Tx checksum auto calc off (Yukon EX) */ + F_TX_CHK_AUTO_ON = 1<<30, /* Tx checksum auto calc off (Yukon EX) */ + + /* Receive */ F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */ - F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */ - F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */ + + /* Hardware testbits not used */ }; /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/ From 451af33552286b426940a32126bd3ece243223a3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:24 -0700 Subject: [PATCH 101/551] sky2: enable clocks before probe Catch-22: On Yukon EX (88E8071) need to have internal clocks enabled before reading chip id. It is harmless on other chips. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5b3a866a0b1c..fbe39d929277 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2519,6 +2519,9 @@ static int __devinit sky2_init(struct sky2_hw *hw) { u8 t8; + /* Enable all clocks */ + sky2_pci_write32(hw, PCI_DEV_REG3, 0); + sky2_write8(hw, B0_CTST, CS_RST_CLR); hw->chip_id = sky2_read8(hw, B2_CHIP_ID); @@ -2532,10 +2535,6 @@ static int __devinit sky2_init(struct sky2_hw *hw) dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" "Please report success or failure to \n"); - /* Make sure and enable all clocks */ - if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) - sky2_pci_write32(hw, PCI_DEV_REG3, 0); - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; /* This rev is really old, and requires untested workarounds */ From 8f70920f2f2a699b4ad35e625071cd92f4ba6ca3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:25 -0700 Subject: [PATCH 102/551] sky2: GPIO register The General Purpose I/O register is yet another hardware workaround catchall. Enable workaround that vendor driver does to stay but for bug compatiable. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 5 +++++ drivers/net/sky2.h | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fbe39d929277..1f1b6db434be 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -230,6 +230,11 @@ static void sky2_power_on(struct sky2_hw *hw) sky2_pci_write32(hw, PCI_DEV_REG5, reg); sky2_pci_write32(hw, PCI_CFG_REG_1, 0); + + /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ + reg = sky2_read32(hw, B2_GP_IO); + reg |= GLB_GPIO_STAT_RACE_DIS; + sky2_write32(hw, B2_GP_IO, reg); } } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 00907f58019e..c6c0baffc082 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -441,6 +441,20 @@ enum { TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */ }; +/* B2_GPIO */ +enum { + GLB_GPIO_CLK_DEB_ENA = 1<<31, /* Clock Debug Enable */ + GLB_GPIO_CLK_DBG_MSK = 0xf<<26, /* Clock Debug */ + + GLB_GPIO_INT_RST_D3_DIS = 1<<15, /* Disable Internal Reset After D3 to D0 */ + GLB_GPIO_LED_PAD_SPEED_UP = 1<<14, /* LED PAD Speed Up */ + GLB_GPIO_STAT_RACE_DIS = 1<<13, /* Status Race Disable */ + GLB_GPIO_TEST_SEL_MSK = 3<<11, /* Testmode Select */ + GLB_GPIO_TEST_SEL_BASE = 1<<11, + GLB_GPIO_RAND_ENA = 1<<10, /* Random Enable */ + GLB_GPIO_RAND_BIT_1 = 1<<9, /* Random Bit 1 */ +}; + /* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ enum { CFG_CHIP_R_MSK = 0xf<<4, /* Bit 7.. 4: Chip Revision */ From 69161611025b261cb64be70723c0dffe26aeb3ab Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:26 -0700 Subject: [PATCH 103/551] sky2: Yukon Extreme (88e8071) support. Enable support for Yukon EX chipset (88e8071). Most of changes are related to new commands to chip for transmit, and change in status and checksumming. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 166 +++++++++++++++++++++++++++------------------ drivers/net/sky2.h | 43 +++++++++++- 2 files changed, 143 insertions(+), 66 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1f1b6db434be..da7d9580f742 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -130,7 +130,7 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ -// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ { 0 } }; @@ -661,6 +661,30 @@ static void sky2_wol_init(struct sky2_port *sky2) } +static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) +{ + if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) { + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_STFW_ENA | + (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS); + } else { + if (hw->dev[port]->mtu > ETH_DATA_LEN) { + /* set Tx GMAC FIFO Almost Empty Threshold */ + sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), + (ECU_JUMBO_WM << 16) | ECU_AE_THR); + + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_JUMBO_ENA | TX_STFW_DIS); + + /* Can't do offload because of lack of store/forward */ + hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG + | NETIF_F_ALL_CSUM); + } else + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_JUMBO_DIS | TX_STFW_ENA); + } +} + static void sky2_mac_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); @@ -741,8 +765,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) /* Configure Rx MAC FIFO */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), - GMF_OPER_ON | GMF_RX_F_FL_ON); + reg = GMF_OPER_ON | GMF_RX_F_FL_ON; + if (hw->chip_id == CHIP_ID_YUKON_EX) + reg |= GMF_RX_OVER_ON; + + sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg); /* Flush Rx MAC FIFO on any flow control or error */ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); @@ -758,16 +785,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); - /* set Tx GMAC FIFO Almost Empty Threshold */ - sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), - (ECU_JUMBO_WM << 16) | ECU_AE_THR); - - if (hw->dev[port]->mtu > ETH_DATA_LEN) - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_DIS); - else - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); + sky2_set_tx_stfwd(hw, port); } } @@ -950,14 +968,16 @@ static void rx_set_checksum(struct sky2_port *sky2) { struct sky2_rx_le *le; - le = sky2_next_rx(sky2); - le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); - le->ctrl = 0; - le->opcode = OP_TCPSTART | HW_OWNER; + if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) { + le = sky2_next_rx(sky2); + le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); + le->ctrl = 0; + le->opcode = OP_TCPSTART | HW_OWNER; - sky2_write32(sky2->hw, - Q_ADDR(rxqaddr[sky2->port], Q_CSR), - sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + sky2_write32(sky2->hw, + Q_ADDR(rxqaddr[sky2->port], Q_CSR), + sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + } } @@ -1296,6 +1316,10 @@ static int sky2_up(struct net_device *dev) sky2_qset(hw, txqaddr[port]); + /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */ + if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0) + sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF); + /* Set almost empty threshold */ if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_U_A0) @@ -1404,14 +1428,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) /* Check for TCP Segmentation Offload */ mss = skb_shinfo(skb)->gso_size; if (mss != 0) { - mss += tcp_optlen(skb); /* TCP options */ - mss += ip_hdrlen(skb) + sizeof(struct tcphdr); - mss += ETH_HLEN; + if (hw->chip_id != CHIP_ID_YUKON_EX) + mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); - if (mss != sky2->tx_last_mss) { - le = get_tx_le(sky2); - le->addr = cpu_to_le32(mss); - le->opcode = OP_LRGLEN | HW_OWNER; + if (mss != sky2->tx_last_mss) { + le = get_tx_le(sky2); + le->addr = cpu_to_le32(mss); + if (hw->chip_id == CHIP_ID_YUKON_EX) + le->opcode = OP_MSS | HW_OWNER; + else + le->opcode = OP_LRGLEN | HW_OWNER; sky2->tx_last_mss = mss; } } @@ -1433,24 +1459,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) /* Handle TCP checksum offload */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - const unsigned offset = skb_transport_offset(skb); - u32 tcpsum; + /* On Yukon EX (some versions) encoding change. */ + if (hw->chip_id == CHIP_ID_YUKON_EX + && hw->chip_rev != CHIP_REV_YU_EX_B0) + ctrl |= CALSUM; /* auto checksum */ + else { + const unsigned offset = skb_transport_offset(skb); + u32 tcpsum; - tcpsum = offset << 16; /* sum start */ - tcpsum |= offset + skb->csum_offset; /* sum write */ + tcpsum = offset << 16; /* sum start */ + tcpsum |= offset + skb->csum_offset; /* sum write */ - ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; - if (ip_hdr(skb)->protocol == IPPROTO_UDP) - ctrl |= UDPTCP; + ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + if (ip_hdr(skb)->protocol == IPPROTO_UDP) + ctrl |= UDPTCP; - if (tcpsum != sky2->tx_tcpsum) { - sky2->tx_tcpsum = tcpsum; + if (tcpsum != sky2->tx_tcpsum) { + sky2->tx_tcpsum = tcpsum; - le = get_tx_le(sky2); - le->addr = cpu_to_le32(tcpsum); - le->length = 0; /* initial checksum value */ - le->ctrl = 1; /* one packet */ - le->opcode = OP_TCPLISW | HW_OWNER; + le = get_tx_le(sky2); + le->addr = cpu_to_le32(tcpsum); + le->length = 0; /* initial checksum value */ + le->ctrl = 1; /* one packet */ + le->opcode = OP_TCPLISW | HW_OWNER; + } } } @@ -1924,15 +1956,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) synchronize_irq(hw->pdev->irq); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { - if (new_mtu > ETH_DATA_LEN) { - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_DIS); - dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; - } else - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); - } + if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) + sky2_set_tx_stfwd(hw, port); ctl = gma_read16(hw, port, GM_GP_CTRL); gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); @@ -2129,6 +2154,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) while (hw->st_idx != hwidx) { struct sky2_status_le *le = hw->st_le + hw->st_idx; + unsigned port = le->css & CSS_LINK_BIT; struct net_device *dev; struct sk_buff *skb; u32 status; @@ -2136,9 +2162,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); - BUG_ON(le->link >= 2); - dev = hw->dev[le->link]; - + dev = hw->dev[port]; sky2 = netdev_priv(dev); length = le16_to_cpu(le->length); status = le32_to_cpu(le->status); @@ -2151,6 +2175,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) goto force_update; } + /* This chip reports checksum status differently */ + if (hw->chip_id == CHIP_ID_YUKON_EX) { + if (sky2->rx_csum && + (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && + (le->css & CSS_TCPUDPCSOK)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + } + skb->protocol = eth_type_trans(skb, dev); sky2->net_stats.rx_packets++; sky2->net_stats.rx_bytes += skb->len; @@ -2166,10 +2200,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) netif_receive_skb(skb); /* Update receiver after 16 frames */ - if (++buf_write[le->link] == RX_BUF_WRITE) { + if (++buf_write[port] == RX_BUF_WRITE) { force_update: - sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put); - buf_write[le->link] = 0; + sky2_put_idx(hw, rxqaddr[port], sky2->rx_put); + buf_write[port] = 0; } /* Stop after net poll weight */ @@ -2190,6 +2224,9 @@ force_update: if (!sky2->rx_csum) break; + if (hw->chip_id == CHIP_ID_YUKON_EX) + break; + /* Both checksum counters are programmed to start at * the same offset, so unless there is a problem they * should match. This failure is an early indication that @@ -2205,7 +2242,7 @@ force_update: dev->name, status); sky2->rx_csum = 0; sky2_write32(sky2->hw, - Q_ADDR(rxqaddr[le->link], Q_CSR), + Q_ADDR(rxqaddr[port], Q_CSR), BMU_DIS_RX_CHKSUM); } break; @@ -2536,10 +2573,6 @@ static int __devinit sky2_init(struct sky2_hw *hw) return -EOPNOTSUPP; } - if (hw->chip_id == CHIP_ID_YUKON_EX) - dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" - "Please report success or failure to \n"); - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; /* This rev is really old, and requires untested workarounds */ @@ -2599,6 +2632,11 @@ static void sky2_reset(struct sky2_hw *hw) for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + + if (hw->chip_id == CHIP_ID_YUKON_EX) + sky2_write16(hw, SK_REG(i, GMAC_CTRL), + GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON + | GMC_BYP_RETR_ON); } sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); @@ -2745,7 +2783,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) sky2->wol = wol->wolopts; - if (hw->chip_id == CHIP_ID_YUKON_EC_U) + if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) sky2_write32(hw, B0_CTST, sky2->wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); @@ -3371,9 +3409,7 @@ static int no_tx_offload(struct net_device *dev) const struct sky2_port *sky2 = netdev_priv(dev); const struct sky2_hw *hw = sky2->hw; - return dev->mtu > ETH_DATA_LEN && - (hw->chip_id == CHIP_ID_YUKON_EX - || hw->chip_id == CHIP_ID_YUKON_EC_U); + return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; } static int sky2_set_tx_csum(struct net_device *dev, u32 data) diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index c6c0baffc082..8df4643493d1 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -483,6 +483,11 @@ enum { CHIP_REV_YU_FE_A2 = 2, }; +enum yukon_ex_rev { + CHIP_REV_YU_EX_A0 = 1, + CHIP_REV_YU_EX_B0 = 2, +}; + /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ enum { @@ -1692,6 +1697,16 @@ enum { RX_VLAN_STRIP_ON = 1<<25, /* enable VLAN stripping */ RX_VLAN_STRIP_OFF = 1<<24, /* disable VLAN stripping */ + RX_MACSEC_FLUSH_ON = 1<<23, + RX_MACSEC_FLUSH_OFF = 1<<22, + RX_MACSEC_ASF_FLUSH_ON = 1<<21, + RX_MACSEC_ASF_FLUSH_OFF = 1<<20, + + GMF_RX_OVER_ON = 1<<19, /* enable flushing on receive overrun */ + GMF_RX_OVER_OFF = 1<<18, /* disable flushing on receive overrun */ + GMF_ASF_RX_OVER_ON = 1<<17, /* enable flushing of ASF when overrun */ + GMF_ASF_RX_OVER_OFF = 1<<16, /* disable flushing of ASF when overrun */ + GMF_WP_TST_ON = 1<<14, /* Write Pointer Test On */ GMF_WP_TST_OFF = 1<<13, /* Write Pointer Test Off */ GMF_WP_STEP = 1<<12, /* Write Pointer Step/Increment */ @@ -1804,6 +1819,15 @@ enum { /* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ enum { + GMC_SET_RST = 1<<15,/* MAC SEC RST */ + GMC_SEC_RST_OFF = 1<<14,/* MAC SEC RSt OFF */ + GMC_BYP_MACSECRX_ON = 1<<13,/* Bypass macsec RX */ + GMC_BYP_MACSECRX_OFF= 1<<12,/* Bypass macsec RX off */ + GMC_BYP_MACSECTX_ON = 1<<11,/* Bypass macsec TX */ + GMC_BYP_MACSECTX_OFF= 1<<10,/* Bypass macsec TX off*/ + GMC_BYP_RETR_ON = 1<<9, /* Bypass retransmit FIFO On */ + GMC_BYP_RETR_OFF= 1<<8, /* Bypass retransmit FIFO Off */ + GMC_H_BURST_ON = 1<<7, /* Half Duplex Burst Mode On */ GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */ GMC_F_LOOPB_ON = 1<<5, /* FIFO Loopback On */ @@ -1889,9 +1913,13 @@ enum { OP_ADDR64VLAN = OP_ADDR64 | OP_VLAN, OP_LRGLEN = 0x24, OP_LRGLENVLAN = OP_LRGLEN | OP_VLAN, + OP_MSS = 0x28, + OP_MSSVLAN = OP_MSS | OP_VLAN, + OP_BUFFER = 0x40, OP_PACKET = 0x41, OP_LARGESEND = 0x43, + OP_LSOV2 = 0x45, /* YUKON-2 STATUS opcodes defines */ OP_RXSTAT = 0x60, @@ -1902,6 +1930,19 @@ enum { OP_RXTIMEVLAN = OP_RXTIMESTAMP | OP_RXVLAN, OP_RSS_HASH = 0x65, OP_TXINDEXLE = 0x68, + OP_MACSEC = 0x6c, + OP_PUTIDX = 0x70, +}; + +enum status_css { + CSS_TCPUDPCSOK = 1<<7, /* TCP / UDP checksum is ok */ + CSS_ISUDP = 1<<6, /* packet is a UDP packet */ + CSS_ISTCP = 1<<5, /* packet is a TCP packet */ + CSS_ISIPFRAG = 1<<4, /* packet is a TCP/UDP frag, CS calc not done */ + CSS_ISIPV6 = 1<<3, /* packet is a IPv6 packet */ + CSS_IPV4CSUMOK = 1<<2, /* IP v4: TCP header checksum is ok */ + CSS_ISIPV4 = 1<<1, /* packet is a IPv4 packet */ + CSS_LINK_BIT = 1<<0, /* port number (legacy) */ }; /* Yukon 2 hardware interface */ @@ -1922,7 +1963,7 @@ struct sky2_rx_le { struct sky2_status_le { __le32 status; /* also checksum */ __le16 length; /* also vlan tag */ - u8 link; + u8 css; u8 opcode; } __attribute((packed)); From a73b629b3519ae97c5325eda346b1749961cfa8d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Jun 2007 17:23:27 -0700 Subject: [PATCH 104/551] sky2: version 1.15 New version because of new chip support. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index da7d9580f742..b51d73c8f817 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.14" +#define DRV_VERSION "1.15" #define PFX DRV_NAME " " /* From 15d317587e17dcb96484e46b17b6e826a1f97661 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 16 Jun 2007 22:36:41 +0200 Subject: [PATCH 105/551] r8169: use netdev_alloc_skb Use netdev_alloc_skb and remove the useless sk_buff * argument of rtl8169_alloc_rx_skb. Signed-off-by: Stephen Hemminger Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 5ec7752caa48..45864461aab6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1997,31 +1997,28 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, rtl8169_mark_to_asic(desc, rx_buf_sz); } -static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align) +static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, + struct net_device *dev, + struct RxDesc *desc, int rx_buf_sz, + unsigned int align) { struct sk_buff *skb; dma_addr_t mapping; - int ret = 0; - skb = dev_alloc_skb(rx_buf_sz + align); + skb = netdev_alloc_skb(dev, rx_buf_sz + align); if (!skb) goto err_out; skb_reserve(skb, (align - 1) & (unsigned long)skb->data); - *sk_buff = skb; mapping = pci_map_single(pdev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); - out: - return ret; + return skb; err_out: - ret = -ENOMEM; rtl8169_make_unusable_by_asic(desc); goto out; } @@ -2044,15 +2041,19 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, u32 cur; for (cur = start; end - cur > 0; cur++) { - int ret, i = cur % NUM_RX_DESC; + struct sk_buff *skb; + unsigned int i = cur % NUM_RX_DESC; if (tp->Rx_skbuff[i]) continue; - ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, - tp->RxDescArray + i, tp->rx_buf_sz, tp->align); - if (ret < 0) + skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, + tp->RxDescArray + i, + tp->rx_buf_sz, tp->align); + if (!skb) break; + + tp->Rx_skbuff[i] = skb; } return cur - start; } From 4ae47c2ddc55e3c571bb55fca921cfe9b02a685f Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sat, 16 Jun 2007 23:28:45 +0200 Subject: [PATCH 106/551] r8169: de-obfuscate modulo arithmetic The former style suggests a modulo arithmetic misuse but the expression should never be < 0. Even if it does, the driver will simply loop longer than expected (not that the remaining parts of the system will necessarily appreciate it...). Let's warn the user when something goes wrong and try to go over it. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 45864461aab6..1f7fb541ec54 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2040,10 +2040,12 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, { u32 cur; - for (cur = start; end - cur > 0; cur++) { + for (cur = start; end - cur != 0; cur++) { struct sk_buff *skb; unsigned int i = cur % NUM_RX_DESC; + WARN_ON((s32)(end - cur) < 0); + if (tp->Rx_skbuff[i]) continue; From 278667ba186a23770b0dd23ccd26de56a8cc4ec2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Jun 2007 17:55:04 -0700 Subject: [PATCH 107/551] r8169: kill eth_copy_and_sum() It hasn't "summed" anything in over 7 years, and it's just a straight mempcy ala skb_copy_to_linear_data() so just get rid of it. Signed-off-by: David S. Miller Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1f7fb541ec54..e4827a414689 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2495,7 +2495,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, skb = dev_alloc_skb(pkt_size + align); if (skb) { skb_reserve(skb, (align - 1) & (unsigned long)skb->data); - eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); + skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); *sk_buff = skb; rtl8169_mark_to_asic(desc, rx_buf_sz); ret = 0; From b449655ff52ff8a29c66c5fc3fc03617e61182ee Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 17 Jun 2007 01:06:49 +0200 Subject: [PATCH 108/551] r8169: Rx path update - pci_dma_sync_single_for_cpu is not needed for a single large packet - remove the function pointer to help gcc optimizing the inline pci_dma functions. Signed-off-by: Stephen Hemminger Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index e4827a414689..4d0cdbaf527e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2483,25 +2483,27 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) skb->ip_summed = CHECKSUM_NONE; } -static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align) +static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, + struct pci_dev *pdev, dma_addr_t addr, + unsigned int align) { - int ret = -1; + struct sk_buff *skb; + bool done = false; - if (pkt_size < rx_copybreak) { - struct sk_buff *skb; + if (pkt_size >= rx_copybreak) + goto out; - skb = dev_alloc_skb(pkt_size + align); - if (skb) { - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); - skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); - *sk_buff = skb; - rtl8169_mark_to_asic(desc, rx_buf_sz); - ret = 0; - } - } - return ret; + skb = dev_alloc_skb(pkt_size + align); + if (!skb) + goto out; + + pci_dma_sync_single_for_cpu(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); + skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); + *sk_buff = skb; + done = true; +out: + return done; } static int @@ -2547,9 +2549,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { struct sk_buff *skb = tp->Rx_skbuff[entry]; + dma_addr_t addr = le64_to_cpu(desc->addr); int pkt_size = (status & 0x00001FFF) - 4; - void (*pci_action)(struct pci_dev *, dma_addr_t, - size_t, int) = pci_dma_sync_single_for_device; + struct pci_dev *pdev = tp->pci_dev; /* * The driver does not support incoming fragmented @@ -2565,19 +2567,17 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, rtl8169_rx_csum(skb, desc); - pci_dma_sync_single_for_cpu(tp->pci_dev, - le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - - if (rtl8169_try_rx_copy(&skb, pkt_size, desc, - tp->rx_buf_sz, tp->align)) { - pci_action = pci_unmap_single; + if (rtl8169_try_rx_copy(&skb, pkt_size, pdev, addr, + tp->align)) { + pci_dma_sync_single_for_device(pdev, addr, + pkt_size, PCI_DMA_FROMDEVICE); + rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + } else { + pci_unmap_single(pdev, addr, pkt_size, + PCI_DMA_FROMDEVICE); tp->Rx_skbuff[entry] = NULL; } - pci_action(tp->pci_dev, le64_to_cpu(desc->addr), - tp->rx_buf_sz, PCI_DMA_FROMDEVICE); - skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); From 07ce4064677806e330599ade772a914f500e74af Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 23 Feb 2007 23:36:39 +0100 Subject: [PATCH 109/551] r8169: add hooks for per-device hw_start handler Rationale: rtl8169_hw_start will not help maintaining an unified driver for different chipsets but people at Realtek are probably too polite to say it distinctly. Let's add the hook and keep hw_start handler unchanged. As can be seen from the content of rtl8169_pci_tbl, the RTL_CFG_1 entry in rtl_cfg_info was unused. I recycled it for the 0x8168. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 64 +++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4d0cdbaf527e..5e24a0cf4d5f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -199,20 +199,25 @@ enum cfg_version { RTL_CFG_2 }; +static void rtl_hw_start_8169(struct net_device *); +static void rtl_hw_start_8168(struct net_device *); +static void rtl_hw_start_8101(struct net_device *); + static const struct { + void (*hw_start)(struct net_device *); unsigned int region; unsigned int align; } rtl_cfg_info[] = { - [RTL_CFG_0] = { 1, NET_IP_ALIGN }, - [RTL_CFG_1] = { 2, NET_IP_ALIGN }, - [RTL_CFG_2] = { 2, 8 } + [RTL_CFG_0] = { rtl_hw_start_8169, 1, NET_IP_ALIGN }, + [RTL_CFG_1] = { rtl_hw_start_8168, 2, 8 }, + [RTL_CFG_2] = { rtl_hw_start_8101, 2, 8 } }; static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, @@ -455,6 +460,7 @@ struct rtl8169_private { int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); void (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(void __iomem *); + void (*hw_start)(struct net_device *); unsigned int (*phy_reset_pending)(void __iomem *); unsigned int (*link_ok)(void __iomem *); struct delayed_work task; @@ -478,9 +484,9 @@ static int rtl8169_open(struct net_device *dev); static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance); static int rtl8169_init_ring(struct net_device *dev); -static void rtl8169_hw_start(struct net_device *dev); +static void rtl_hw_start(struct net_device *dev); static int rtl8169_close(struct net_device *dev); -static void rtl8169_set_rx_mode(struct net_device *dev); +static void rtl_set_rx_mode(struct net_device *dev); static void rtl8169_tx_timeout(struct net_device *dev); static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, @@ -1647,7 +1653,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops); dev->stop = rtl8169_close; dev->tx_timeout = rtl8169_tx_timeout; - dev->set_multicast_list = rtl8169_set_rx_mode; + dev->set_multicast_list = rtl_set_rx_mode; dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; @@ -1676,6 +1682,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; + tp->hw_start = rtl_cfg_info[ent->driver_data].hw_start; + spin_lock_init(&tp->lock); rc = register_netdev(dev); @@ -1774,7 +1782,7 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_release_ring_2; - rtl8169_hw_start(dev); + rtl_hw_start(dev); rtl8169_request_timer(dev); @@ -1818,12 +1826,10 @@ static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp) (InterFrameGap << TxInterFrameGapShift)); } -static void rtl8169_hw_start(struct net_device *dev) +static void rtl_hw_start(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; - u16 cmd; u32 i; /* Soft reset the chip. */ @@ -1836,6 +1842,22 @@ static void rtl8169_hw_start(struct net_device *dev) msleep_interruptible(1); } + tp->hw_start(dev); + + /* Enable all known interrupts by setting the interrupt mask. */ + RTL_W16(IntrMask, rtl8169_intr_mask); + + netif_start_queue(dev); +} + + +static void rtl_hw_start_8169(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + u16 cmd; + if (tp->mac_version == RTL_GIGA_MAC_VER_05) { RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); @@ -1922,15 +1944,20 @@ static void rtl8169_hw_start(struct net_device *dev) RTL_W32(RxMissed, 0); - rtl8169_set_rx_mode(dev); + rtl_set_rx_mode(dev); /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); +} - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); +static void rtl_hw_start_8168(struct net_device *dev) +{ + rtl_hw_start_8169(dev); +} - netif_start_queue(dev); +static void rtl_hw_start_8101(struct net_device *dev) +{ + rtl_hw_start_8169(dev); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) @@ -1956,7 +1983,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) netif_poll_enable(dev); - rtl8169_hw_start(dev); + rtl_hw_start(dev); rtl8169_request_timer(dev); @@ -2201,7 +2228,7 @@ static void rtl8169_reset_task(struct work_struct *work) if (tp->dirty_rx == tp->cur_rx) { rtl8169_init_ring_indexes(tp); - rtl8169_hw_start(dev); + rtl_hw_start(dev); netif_wake_queue(dev); } else { if (net_ratelimit()) { @@ -2792,8 +2819,7 @@ static int rtl8169_close(struct net_device *dev) return 0; } -static void -rtl8169_set_rx_mode(struct net_device *dev) +static void rtl_set_rx_mode(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; From 7f796d83ffa58c6f752e53dbed8faebb74333e24 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 11 Jun 2007 23:04:41 +0200 Subject: [PATCH 110/551] r8169: add helpers for per-device hw_start handler They aim to limit the amount of moved code when the hw_start handler gets more specialized. No functional change. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 53 ++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 5e24a0cf4d5f..f549f096dd01 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1813,7 +1813,7 @@ static void rtl8169_hw_reset(void __iomem *ioaddr) RTL_R8(ChipCmd); } -static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp) +static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; u32 cfg = rtl8169_rx_config; @@ -1851,6 +1851,35 @@ static void rtl_hw_start(struct net_device *dev) } +static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, + void __iomem *ioaddr) +{ + /* + * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh + * register to be written before TxDescAddrLow to work. + * Switching from MMIO to I/O access fixes the issue as well. + */ + RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); + RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK); + RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); + RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK); +} + +static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) +{ + u16 cmd; + + cmd = RTL_R16(CPlusCmd); + RTL_W16(CPlusCmd, cmd); + return cmd; +} + +static void rtl_set_rx_max_size(void __iomem *ioaddr) +{ + /* Low hurts. Let's disable the filtering. */ + RTL_W16(RxMaxSize, 16383); +} + static void rtl_hw_start_8169(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1890,19 +1919,15 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, 16383); + rtl_set_rx_max_size(ioaddr); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03) || (tp->mac_version == RTL_GIGA_MAC_VER_04)) - rtl8169_set_rx_tx_config_registers(tp); + rtl_set_rx_tx_config_registers(tp); - cmd = RTL_R16(CPlusCmd); - RTL_W16(CPlusCmd, cmd); - - tp->cp_cmd |= cmd | PCIMulRW; + tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03)) { @@ -1919,22 +1944,14 @@ static void rtl_hw_start_8169(struct net_device *dev) */ RTL_W16(IntrMitigate, 0x0000); - /* - * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh - * register to be written before TxDescAddrLow to work. - * Switching from MMIO to I/O access fixes the issue as well. - */ - RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); - RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); - RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); - RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); + rtl_set_rx_tx_desc_registers(tp, ioaddr); if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && (tp->mac_version != RTL_GIGA_MAC_VER_02) && (tp->mac_version != RTL_GIGA_MAC_VER_03) && (tp->mac_version != RTL_GIGA_MAC_VER_04)) { RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - rtl8169_set_rx_tx_config_registers(tp); + rtl_set_rx_tx_config_registers(tp); } RTL_W8(Cfg9346, Cfg9346_Lock); From 2dd99530a248bc70e712a5f98e0bc66139a582cb Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 11 Jun 2007 23:22:52 +0200 Subject: [PATCH 111/551] r8169: populate the hw_start handler for the 8168 rtl_hw_start_8168 inherits the content of rtl_hw_start_8169 minus the code which depends on RTL_GIGA_MAC_VER_XY (XY != {11/12}). Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index f549f096dd01..2478ece93bc5 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -156,8 +156,8 @@ enum mac_version { RTL_GIGA_MAC_VER_03 = 0x02, RTL_GIGA_MAC_VER_04 = 0x03, RTL_GIGA_MAC_VER_05 = 0x04, - RTL_GIGA_MAC_VER_11 = 0x0b, - RTL_GIGA_MAC_VER_12 = 0x0c, + RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb + RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf RTL_GIGA_MAC_VER_13 = 0x0d, RTL_GIGA_MAC_VER_14 = 0x0e, RTL_GIGA_MAC_VER_15 = 0x0f @@ -1969,7 +1969,35 @@ static void rtl_hw_start_8169(struct net_device *dev) static void rtl_hw_start_8168(struct net_device *dev) { - rtl_hw_start_8169(dev); + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W8(Cfg9346, Cfg9346_Unlock); + + RTL_W8(EarlyTxThres, EarlyTxThld); + + rtl_set_rx_max_size(ioaddr); + + tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; + + RTL_W16(CPlusCmd, tp->cp_cmd); + + RTL_W16(IntrMitigate, 0x0000); + + rtl_set_rx_tx_desc_registers(tp, ioaddr); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_set_rx_tx_config_registers(tp); + + RTL_W8(Cfg9346, Cfg9346_Lock); + + RTL_R8(IntrMask); + + RTL_W32(RxMissed, 0); + + rtl_set_rx_mode(dev); + + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); } static void rtl_hw_start_8101(struct net_device *dev) From cdf1a608a6ccf9cf1a773969395b58b017bd6f75 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 11 Jun 2007 23:29:50 +0200 Subject: [PATCH 112/551] r8169: populate the hw_start handler for the 8110 Same thing as the previous change for rtl_hw_start_8168. The 8101 related code in rtl_hw_start_8169 (see RTL_GIGA_MAC_VER_13) goes away. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 47 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2478ece93bc5..56b9040b3d55 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -158,9 +158,9 @@ enum mac_version { RTL_GIGA_MAC_VER_05 = 0x04, RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf - RTL_GIGA_MAC_VER_13 = 0x0d, - RTL_GIGA_MAC_VER_14 = 0x0e, - RTL_GIGA_MAC_VER_15 = 0x0f + RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec + RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 + RTL_GIGA_MAC_VER_15 = 0x0f // 8101 }; enum phy_version { @@ -1892,11 +1892,6 @@ static void rtl_hw_start_8169(struct net_device *dev) pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); } - if (tp->mac_version == RTL_GIGA_MAC_VER_13) { - pci_write_config_word(pdev, 0x68, 0x00); - pci_write_config_word(pdev, 0x69, 0x08); - } - /* Undocumented stuff. */ if (tp->mac_version == RTL_GIGA_MAC_VER_05) { /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ @@ -2002,7 +1997,41 @@ static void rtl_hw_start_8168(struct net_device *dev) static void rtl_hw_start_8101(struct net_device *dev) { - rtl_hw_start_8169(dev); + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + + if (tp->mac_version == RTL_GIGA_MAC_VER_13) { + pci_write_config_word(pdev, 0x68, 0x00); + pci_write_config_word(pdev, 0x69, 0x08); + } + + RTL_W8(Cfg9346, Cfg9346_Unlock); + + RTL_W8(EarlyTxThres, EarlyTxThld); + + rtl_set_rx_max_size(ioaddr); + + tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; + + RTL_W16(CPlusCmd, tp->cp_cmd); + + RTL_W16(IntrMitigate, 0x0000); + + rtl_set_rx_tx_desc_registers(tp, ioaddr); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_set_rx_tx_config_registers(tp); + + RTL_W8(Cfg9346, Cfg9346_Lock); + + RTL_R8(IntrMask); + + RTL_W32(RxMissed, 0); + + rtl_set_rx_mode(dev); + + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) From ba6eb6ee8583a2c7c7f8327be5e5c239fb760b03 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 11 Jun 2007 23:35:18 +0200 Subject: [PATCH 113/551] r8169: prettify mac_version ...still a bit yucky though. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 56b9040b3d55..eb793fa4611c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -151,11 +151,11 @@ static const int multicast_filter_limit = 32; #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) enum mac_version { - RTL_GIGA_MAC_VER_01 = 0x00, - RTL_GIGA_MAC_VER_02 = 0x01, - RTL_GIGA_MAC_VER_03 = 0x02, - RTL_GIGA_MAC_VER_04 = 0x03, - RTL_GIGA_MAC_VER_05 = 0x04, + RTL_GIGA_MAC_VER_01 = 0x01, // 8169 + RTL_GIGA_MAC_VER_02 = 0x02, // 8169S + RTL_GIGA_MAC_VER_03 = 0x03, // 8110S + RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB + RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec @@ -180,11 +180,11 @@ static const struct { u8 mac_version; u32 RxConfigMask; /* Clears the bits supported by this chip */ } rtl_chip_info[] = { - _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), - _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), + _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 + _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S + _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S + _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 From 6dccd16b7c2703e8bbf8bca62b5cf248332afbe2 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 13 Feb 2007 23:38:05 +0100 Subject: [PATCH 114/551] r8169: merge with version 6.001.00 of Realtek's r8169 driver - new identifier for the 8110SCe - the PCI latency timer is set unconditionally. This part is identical in Realtek's r8168 (8.001.00) and r8101 (1.001.00) - initialization of the cache line size register is for the 8169s only - more magic in rtl_hw_start_8169 - it is not possible to factor out the setting of the the irq event mask with the 8168 and the 8101 any more. Pushed it into the hw_start handler. - rtl_set_rx_tx_config_registers() and write to the ChipCmd register are issued identically for the whole 8169/8110 family: the 8110SCd/8110SCe are handled the same way - work around for AMD platform. Some registers definitions in Realtek's driver are let aside for later. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 90 +++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index eb793fa4611c..0d2aeb84510f 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -156,6 +156,7 @@ enum mac_version { RTL_GIGA_MAC_VER_03 = 0x03, // 8110S RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd + RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec @@ -185,6 +186,7 @@ static const struct { _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 @@ -328,6 +330,10 @@ enum RTL8169_register_content { /* Config1 register p.24 */ PMEnable = (1 << 0), /* Power Management Enable */ + /* Config2 register p. 25 */ + PCI_Clock_66MHz = 0x01, + PCI_Clock_33MHz = 0x00, + /* Config3 register p.25 */ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ @@ -1169,6 +1175,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io { 0x34000000, RTL_GIGA_MAC_VER_13 }, { 0x30800000, RTL_GIGA_MAC_VER_14 }, { 0x30000000, RTL_GIGA_MAC_VER_11 }, + { 0x98000000, RTL_GIGA_MAC_VER_06 }, { 0x18000000, RTL_GIGA_MAC_VER_05 }, { 0x10000000, RTL_GIGA_MAC_VER_04 }, { 0x04000000, RTL_GIGA_MAC_VER_03 }, @@ -1177,7 +1184,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io }, *p = mac_info; u32 reg; - reg = RTL_R32(TxConfig) & 0x7c800000; + reg = RTL_R32(TxConfig) & 0xfc800000; while ((reg & p->mask) != p->mask) p++; tp->mac_version = p->mac_version; @@ -1425,10 +1432,10 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); RTL_W8(0x82, 0x01); - if (tp->mac_version < RTL_GIGA_MAC_VER_03) { - dprintk("Set PCI Latency=0x40\n"); - pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); - } + pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); + + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); if (tp->mac_version == RTL_GIGA_MAC_VER_02) { dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); @@ -1844,9 +1851,6 @@ static void rtl_hw_start(struct net_device *dev) tp->hw_start(dev); - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); - netif_start_queue(dev); } @@ -1880,31 +1884,41 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr) RTL_W16(RxMaxSize, 16383); } +static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) +{ + struct { + u32 mac_version; + u32 clk; + u32 val; + } cfg2_info [] = { + { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd + { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, + { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe + { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } + }, *p = cfg2_info; + unsigned int i; + u32 clk; + + clk = RTL_R8(Config2) & PCI_Clock_66MHz; + for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) { + if ((p->mac_version == mac_version) && (p->clk == clk)) { + RTL_W32(0x7c, p->val); + break; + } + } +} + static void rtl_hw_start_8169(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - u16 cmd; if (tp->mac_version == RTL_GIGA_MAC_VER_05) { RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); } - /* Undocumented stuff. */ - if (tp->mac_version == RTL_GIGA_MAC_VER_05) { - /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ - if ((RTL_R8(Config2) & 0x07) & 0x01) - RTL_W32(0x7c, 0x0007ffff); - - RTL_W32(0x7c, 0x0007ff00); - - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd = cmd & 0xef; - pci_write_config_word(pdev, PCI_COMMAND, cmd); - } - RTL_W8(Cfg9346, Cfg9346_Unlock); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || @@ -1916,11 +1930,7 @@ static void rtl_hw_start_8169(struct net_device *dev) rtl_set_rx_max_size(ioaddr); - if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || - (tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03) || - (tp->mac_version == RTL_GIGA_MAC_VER_04)) - rtl_set_rx_tx_config_registers(tp); + rtl_set_rx_tx_config_registers(tp); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; @@ -1933,6 +1943,8 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W16(CPlusCmd, tp->cp_cmd); + rtl8169_set_magic_reg(ioaddr, tp->mac_version); + /* * Undocumented corner. Supposedly: * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets @@ -1941,14 +1953,6 @@ static void rtl_hw_start_8169(struct net_device *dev) rtl_set_rx_tx_desc_registers(tp, ioaddr); - if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && - (tp->mac_version != RTL_GIGA_MAC_VER_02) && - (tp->mac_version != RTL_GIGA_MAC_VER_03) && - (tp->mac_version != RTL_GIGA_MAC_VER_04)) { - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - rtl_set_rx_tx_config_registers(tp); - } - RTL_W8(Cfg9346, Cfg9346_Lock); /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ @@ -1960,6 +1964,11 @@ static void rtl_hw_start_8169(struct net_device *dev) /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); + + /* Enable all known interrupts by setting the interrupt mask. */ + RTL_W16(IntrMask, rtl8169_intr_mask); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); } static void rtl_hw_start_8168(struct net_device *dev) @@ -1993,6 +2002,8 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_set_rx_mode(dev); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); + + RTL_W16(IntrMask, rtl8169_intr_mask); } static void rtl_hw_start_8101(struct net_device *dev) @@ -2032,6 +2043,8 @@ static void rtl_hw_start_8101(struct net_device *dev) rtl_set_rx_mode(dev); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); + + RTL_W16(IntrMask, rtl8169_intr_mask); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) @@ -2689,6 +2702,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; } + + /* Work around for AMD plateform. */ + if ((desc->opts2 & 0xfffe000) && + (tp->mac_version == RTL_GIGA_MAC_VER_05)) { + desc->opts2 = 0; + cur_rx++; + } } count = cur_rx - tp->cur_rx; From 0e4851502f846b13b29b7f88f1250c980d57e944 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 20 Feb 2007 00:00:26 +0100 Subject: [PATCH 115/551] r8169: merge with version 8.001.00 of Realtek's r8168 driver This one includes: - more tweaks to rtl_hw_start_8168 - a work around for a Rx FiFO overflow issue on the 8168Bb - rtl8169_{intr_mask/napi_event} are replaced with per-device fields, namely tp->{intr/napi}_event - rtl_cfg_info is converted to C99 for readability but the values are not changed for the 8169/8110 and the 8101 Includes ChipCmd fix from Bernhard Walle (2007/02/24). Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 119 +++++++++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 30 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0d2aeb84510f..9c49d910c06d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -205,16 +205,6 @@ static void rtl_hw_start_8169(struct net_device *); static void rtl_hw_start_8168(struct net_device *); static void rtl_hw_start_8101(struct net_device *); -static const struct { - void (*hw_start)(struct net_device *); - unsigned int region; - unsigned int align; -} rtl_cfg_info[] = { - [RTL_CFG_0] = { rtl_hw_start_8169, 1, NET_IP_ALIGN }, - [RTL_CFG_1] = { rtl_hw_start_8168, 2, 8 }, - [RTL_CFG_2] = { rtl_hw_start_8101, 2, 8 } -}; - static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, @@ -354,10 +344,15 @@ enum RTL8169_register_content { TBINwComplete = 0x01000000, /* CPlusCmd p.31 */ + PktCntrDisable = (1 << 7), // 8168 RxVlan = (1 << 6), RxChkSum = (1 << 5), PCIDAC = (1 << 4), PCIMulRW = (1 << 3), + INTT_0 = 0x0000, // 8168 + INTT_1 = 0x0001, // 8168 + INTT_2 = 0x0002, // 8168 + INTT_3 = 0x0003, // 8168 /* rtl8169_PHYstatus */ TBI_Enable = 0x80, @@ -457,6 +452,8 @@ struct rtl8169_private { unsigned rx_buf_sz; struct timer_list timer; u16 cp_cmd; + u16 intr_event; + u16 napi_event; u16 intr_mask; int phy_auto_nego_reg; int phy_1000_ctrl_reg; @@ -505,10 +502,6 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct net_device *dev, int *budget); #endif -static const u16 rtl8169_intr_mask = - SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; -static const u16 rtl8169_napi_event = - RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr; static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); @@ -1166,6 +1159,13 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) { + /* + * The driver currently handles the 8168Bf and the 8168Be identically + * but they can be identified more specifically through the test below + * if needed: + * + * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be + */ const struct { u32 mask; int mac_version; @@ -1480,10 +1480,44 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EOPNOTSUPP; } +static const struct rtl_cfg_info { + void (*hw_start)(struct net_device *); + unsigned int region; + unsigned int align; + u16 intr_event; + u16 napi_event; +} rtl_cfg_infos [] = { + [RTL_CFG_0] = { + .hw_start = rtl_hw_start_8169, + .region = 1, + .align = NET_IP_ALIGN, + .intr_event = SYSErr | LinkChg | RxOverflow | + RxFIFOOver | TxErr | TxOK | RxOK | RxErr, + .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow + }, + [RTL_CFG_1] = { + .hw_start = rtl_hw_start_8168, + .region = 2, + .align = 8, + .intr_event = SYSErr | LinkChg | RxOverflow | + TxErr | TxOK | RxOK | RxErr, + .napi_event = TxErr | TxOK | RxOK | RxOverflow + }, + [RTL_CFG_2] = { + .hw_start = rtl_hw_start_8101, + .region = 2, + .align = 8, + .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | + RxFIFOOver | TxErr | TxOK | RxOK | RxErr, + .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow + } +}; + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - const unsigned int region = rtl_cfg_info[ent->driver_data].region; + const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; + const unsigned int region = cfg->region; struct rtl8169_private *tp; struct net_device *dev; void __iomem *ioaddr; @@ -1683,14 +1717,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->intr_mask = 0xffff; tp->pci_dev = pdev; tp->mmio_addr = ioaddr; - tp->align = rtl_cfg_info[ent->driver_data].align; + tp->align = cfg->align; + tp->hw_start = cfg->hw_start; + tp->intr_event = cfg->intr_event; + tp->napi_event = cfg->napi_event; init_timer(&tp->timer); tp->timer.data = (unsigned long) dev; tp->timer.function = rtl8169_phy_timer; - tp->hw_start = rtl_cfg_info[ent->driver_data].hw_start; - spin_lock_init(&tp->lock); rc = register_netdev(dev); @@ -1966,7 +2001,7 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); } @@ -1975,6 +2010,8 @@ static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + u8 ctl; RTL_W8(Cfg9346, Cfg9346_Unlock); @@ -1982,17 +2019,27 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_set_rx_max_size(ioaddr); - tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; + rtl_set_rx_tx_config_registers(tp); + + tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; RTL_W16(CPlusCmd, tp->cp_cmd); - RTL_W16(IntrMitigate, 0x0000); + /* Tx performance tweak. */ + pci_read_config_byte(pdev, 0x69, &ctl); + ctl = (ctl & ~0x70) | 0x50; + pci_write_config_byte(pdev, 0x69, ctl); + + RTL_W16(IntrMitigate, 0x5151); + + /* Work around for RxFIFO overflow. */ + if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + tp->intr_event |= RxFIFOOver | PCSTimeout; + tp->intr_event &= ~RxOverflow; + } rtl_set_rx_tx_desc_registers(tp, ioaddr); - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - rtl_set_rx_tx_config_registers(tp); - RTL_W8(Cfg9346, Cfg9346_Lock); RTL_R8(IntrMask); @@ -2001,9 +2048,11 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_set_rx_mode(dev); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); } static void rtl_hw_start_8101(struct net_device *dev) @@ -2042,9 +2091,11 @@ static void rtl_hw_start_8101(struct net_device *dev) rtl_set_rx_mode(dev); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) @@ -2761,9 +2812,17 @@ rtl8169_interrupt(int irq, void *dev_instance) RTL_W16(IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status); - if (!(status & rtl8169_intr_mask)) + if (!(status & tp->intr_event)) break; + /* Work around for rx fifo overflow */ + if (unlikely(status & RxFIFOOver) && + (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + netif_stop_queue(dev); + rtl8169_tx_timeout(dev); + break; + } + if (unlikely(status & SYSErr)) { rtl8169_pcierr_interrupt(dev); break; @@ -2773,8 +2832,8 @@ rtl8169_interrupt(int irq, void *dev_instance) rtl8169_check_link_status(dev, tp, ioaddr); #ifdef CONFIG_R8169_NAPI - RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event); - tp->intr_mask = ~rtl8169_napi_event; + RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); + tp->intr_mask = ~tp->napi_event; if (likely(netif_rx_schedule_prep(dev))) __netif_rx_schedule(dev); @@ -2831,7 +2890,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget) * write is safe - FR */ smp_wmb(); - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); } return (work_done >= work_to_do); From 864022344caf43dab7fa5219152280d056c6e051 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 20 Feb 2007 22:20:51 +0100 Subject: [PATCH 116/551] r8169: confusion between hardware and IP header alignment The rx copybreak part is straightforward. The align field in struct rtl_cfg_info is related to the alignment requirements of the DMA operation. Its value is set at 2 to limit the scale of possible regression but my old v1.21 8169 datasheet claims a 8 bytes requirements (which never appeared in the driver, of course) and the 8101/8168 go with a plain 8 bytes alignment. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 9c49d910c06d..a6fea192ffff 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1490,7 +1490,7 @@ static const struct rtl_cfg_info { [RTL_CFG_0] = { .hw_start = rtl_hw_start_8169, .region = 1, - .align = NET_IP_ALIGN, + .align = 2, .intr_event = SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow @@ -2649,8 +2649,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) } static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, - struct pci_dev *pdev, dma_addr_t addr, - unsigned int align) + struct pci_dev *pdev, dma_addr_t addr) { struct sk_buff *skb; bool done = false; @@ -2658,12 +2657,12 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, if (pkt_size >= rx_copybreak) goto out; - skb = dev_alloc_skb(pkt_size + align); + skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); if (!skb) goto out; pci_dma_sync_single_for_cpu(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, NET_IP_ALIGN); skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); *sk_buff = skb; done = true; @@ -2732,8 +2731,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, rtl8169_rx_csum(skb, desc); - if (rtl8169_try_rx_copy(&skb, pkt_size, pdev, addr, - tp->align)) { + if (rtl8169_try_rx_copy(&skb, pkt_size, pdev, addr)) { pci_dma_sync_single_for_device(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); rtl8169_mark_to_asic(desc, tp->rx_buf_sz); From 0127215c17414322b350c3c6fbd1a7d8dd13856f Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 20 Feb 2007 22:58:51 +0100 Subject: [PATCH 117/551] r8169: small 8101 comment Extracted from version 1.001.00 of Realtek's r8101. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a6fea192ffff..49e599bc3f48 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1165,6 +1165,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io * if needed: * * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be + * + * Same thing for the 8101Eb and the 8101Ec: + * + * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec */ const struct { u32 mask; From 901dda2b5f0dfbd310d22d497ec8826d4c60363b Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 21 Feb 2007 00:10:20 +0100 Subject: [PATCH 118/551] r8169: remove the media option It has been documented as deprecated: - in MODULE_PARM_DESC since may 2005 ; - at the top of the source file and in printk since june 2004. Good bye. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 72 ++++----------------------------------------- 1 file changed, 5 insertions(+), 67 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 49e599bc3f48..2ac532a6ed3e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -7,19 +7,6 @@ Feb 4 2002 - created initially by ShuChen . May 20 2002 - Add link status force-mode and TBI mode support. 2004 - Massive updates. See kernel SCM system for details. -========================================================================= - 1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes. - Command: 'insmod r8169 media = SET_MEDIA' - Ex: 'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex. - - SET_MEDIA can be: - _10_Half = 0x01 - _10_Full = 0x02 - _100_Half = 0x04 - _100_Full = 0x08 - _1000_Full = 0x10 - - 2. Support TBI mode. ========================================================================= VERSION 1.1 <2002/10/4> @@ -108,11 +95,6 @@ VERSION 2.2LK <2005/01/25> #define rtl8169_rx_quota(count, quota) count #endif -/* media options */ -#define MAX_UNITS 8 -static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int num_media = 0; - /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static const int max_interrupt_work = 20; @@ -364,13 +346,6 @@ enum RTL8169_register_content { LinkStatus = 0x02, FullDup = 0x01, - /* _MediaType */ - _10_Half = 0x01, - _10_Full = 0x02, - _100_Half = 0x04, - _100_Full = 0x08, - _1000_Full = 0x10, - /* _TBICSRBit */ TBILinkOK = 0x02000000, @@ -472,8 +447,6 @@ struct rtl8169_private { MODULE_AUTHOR("Realtek and the Linux r8169 crew "); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); -module_param_array(media, int, &num_media, 0); -MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8)."); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); @@ -601,38 +574,6 @@ static void rtl8169_check_link_status(struct net_device *dev, spin_unlock_irqrestore(&tp->lock, flags); } -static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex) -{ - struct { - u16 speed; - u8 duplex; - u8 autoneg; - u8 media; - } link_settings[] = { - { SPEED_10, DUPLEX_HALF, AUTONEG_DISABLE, _10_Half }, - { SPEED_10, DUPLEX_FULL, AUTONEG_DISABLE, _10_Full }, - { SPEED_100, DUPLEX_HALF, AUTONEG_DISABLE, _100_Half }, - { SPEED_100, DUPLEX_FULL, AUTONEG_DISABLE, _100_Full }, - { SPEED_1000, DUPLEX_FULL, AUTONEG_DISABLE, _1000_Full }, - /* Make TBI happy */ - { SPEED_1000, DUPLEX_FULL, AUTONEG_ENABLE, 0xff } - }, *p; - unsigned char option; - - option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff; - - if ((option != 0xff) && !idx && netif_msg_drv(&debug)) - printk(KERN_WARNING PFX "media option is deprecated.\n"); - - for (p = link_settings; p->media != 0xff; p++) { - if (p->media == option) - break; - } - *autoneg = p->autoneg; - *speed = p->speed; - *duplex = p->duplex; -} - static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1425,11 +1366,6 @@ static void rtl8169_phy_reset(struct net_device *dev, static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - static int board_idx = -1; - u8 autoneg, duplex; - u16 speed; - - board_idx++; rtl8169_hw_phy_config(dev); @@ -1448,11 +1384,13 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 } - rtl8169_link_option(board_idx, &autoneg, &speed, &duplex); - rtl8169_phy_reset(dev, tp); - rtl8169_set_speed(dev, autoneg, speed, duplex); + /* + * rtl8169_set_speed_xmii takes good care of the Fast Ethernet + * only 8101. Don't panic. + */ + rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL); if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp)) printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); From 07d3f51febdc139c63e95671126fd2791113902e Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 21 Feb 2007 22:40:46 +0100 Subject: [PATCH 119/551] r8169: cleanup No functionnal change: - trim the old history log - whitespace/indent/case police - unsigned int where signedness does not matter - removal of obsolete assert - needless cast from void * (dev_instance) - remove dead code once related to power management - use netdev_alloc_skb. Signed-off-by: Francois Romieu Cc: Stephen Hemminger Cc: Edward Hsu --- drivers/net/r8169.c | 347 ++++++++++++++++++-------------------------- 1 file changed, 145 insertions(+), 202 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2ac532a6ed3e..5d9e75481f42 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1,40 +1,11 @@ /* -========================================================================= - r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x. - -------------------------------------------------------------------- - - History: - Feb 4 2002 - created initially by ShuChen . - May 20 2002 - Add link status force-mode and TBI mode support. - 2004 - Massive updates. See kernel SCM system for details. -========================================================================= -VERSION 1.1 <2002/10/4> - - The bit4:0 of MII register 4 is called "selector field", and have to be - 00001b to indicate support of IEEE std 802.3 during NWay process of - exchanging Link Code Word (FLP). - -VERSION 1.2 <2002/11/30> - - - Large style cleanup - - Use ether_crc in stock kernel (linux/crc32.h) - - Copy mc_filter setup code from 8139cp - (includes an optimization, and avoids set_bit use) - -VERSION 1.6LK <2004/04/14> - - - Merge of Realtek's version 1.6 - - Conversion to DMA API - - Suspend/resume - - Endianness - - Misc Rx/Tx bugs - -VERSION 2.2LK <2005/01/25> - - - RX csum, TX csum/SG, TSO - - VLAN - - baby (< 7200) Jumbo frames support - - Merge of Realtek's version 2.2 (new phy) + * r8169.c: RealTek 8169/8168/8101 ethernet driver. + * + * Copyright (c) 2002 ShuChen + * Copyright (c) 2003 - 2007 Francois Romieu + * Copyright (c) a lot of people too. Please respect their work. + * + * See MAINTAINERS file for support contact information. */ #include @@ -108,7 +79,7 @@ static const int multicast_filter_limit = 32; #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ +#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ #define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -209,62 +180,62 @@ static struct { u32 msg_enable; } debug = { -1 }; -enum RTL8169_registers { - MAC0 = 0, /* Ethernet hardware address. */ - MAR0 = 8, /* Multicast filter. */ - CounterAddrLow = 0x10, - CounterAddrHigh = 0x14, - TxDescStartAddrLow = 0x20, - TxDescStartAddrHigh = 0x24, - TxHDescStartAddrLow = 0x28, - TxHDescStartAddrHigh = 0x2c, - FLASH = 0x30, - ERSR = 0x36, - ChipCmd = 0x37, - TxPoll = 0x38, - IntrMask = 0x3C, - IntrStatus = 0x3E, - TxConfig = 0x40, - RxConfig = 0x44, - RxMissed = 0x4C, - Cfg9346 = 0x50, - Config0 = 0x51, - Config1 = 0x52, - Config2 = 0x53, - Config3 = 0x54, - Config4 = 0x55, - Config5 = 0x56, - MultiIntr = 0x5C, - PHYAR = 0x60, - TBICSR = 0x64, - TBI_ANAR = 0x68, - TBI_LPAR = 0x6A, - PHYstatus = 0x6C, - RxMaxSize = 0xDA, - CPlusCmd = 0xE0, - IntrMitigate = 0xE2, - RxDescAddrLow = 0xE4, - RxDescAddrHigh = 0xE8, - EarlyTxThres = 0xEC, - FuncEvent = 0xF0, - FuncEventMask = 0xF4, - FuncPresetState = 0xF8, - FuncForceEvent = 0xFC, +enum rtl_registers { + MAC0 = 0, /* Ethernet hardware address. */ + MAR0 = 8, /* Multicast filter. */ + CounterAddrLow = 0x10, + CounterAddrHigh = 0x14, + TxDescStartAddrLow = 0x20, + TxDescStartAddrHigh = 0x24, + TxHDescStartAddrLow = 0x28, + TxHDescStartAddrHigh = 0x2c, + FLASH = 0x30, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, + IntrMask = 0x3c, + IntrStatus = 0x3e, + TxConfig = 0x40, + RxConfig = 0x44, + RxMissed = 0x4c, + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, + MultiIntr = 0x5c, + PHYAR = 0x60, + TBICSR = 0x64, + TBI_ANAR = 0x68, + TBI_LPAR = 0x6a, + PHYstatus = 0x6c, + RxMaxSize = 0xda, + CPlusCmd = 0xe0, + IntrMitigate = 0xe2, + RxDescAddrLow = 0xe4, + RxDescAddrHigh = 0xe8, + EarlyTxThres = 0xec, + FuncEvent = 0xf0, + FuncEventMask = 0xf4, + FuncPresetState = 0xf8, + FuncForceEvent = 0xfc, }; -enum RTL8169_register_content { +enum rtl_register_content { /* InterruptStatusBits */ - SYSErr = 0x8000, - PCSTimeout = 0x4000, - SWInt = 0x0100, - TxDescUnavail = 0x80, - RxFIFOOver = 0x40, - LinkChg = 0x20, - RxOverflow = 0x10, - TxErr = 0x08, - TxOK = 0x04, - RxErr = 0x02, - RxOK = 0x01, + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x0080, + RxFIFOOver = 0x0040, + LinkChg = 0x0020, + RxOverflow = 0x0010, + TxErr = 0x0008, + TxOK = 0x0004, + RxErr = 0x0002, + RxOK = 0x0001, /* RxStatusDesc */ RxFOVF = (1 << 23), @@ -274,26 +245,26 @@ enum RTL8169_register_content { RxCRC = (1 << 19), /* ChipCmdBits */ - CmdReset = 0x10, - CmdRxEnb = 0x08, - CmdTxEnb = 0x04, - RxBufEmpty = 0x01, + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, /* Cfg9346Bits */ - Cfg9346_Lock = 0x00, - Cfg9346_Unlock = 0xC0, + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xc0, /* rx_mode_bits */ - AcceptErr = 0x20, - AcceptRunt = 0x10, - AcceptBroadcast = 0x08, - AcceptMulticast = 0x04, - AcceptMyPhys = 0x02, - AcceptAllPhys = 0x01, + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, /* RxConfigBits */ - RxCfgFIFOShift = 13, - RxCfgDMAShift = 8, + RxCfgFIFOShift = 13, + RxCfgDMAShift = 8, /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -337,23 +308,23 @@ enum RTL8169_register_content { INTT_3 = 0x0003, // 8168 /* rtl8169_PHYstatus */ - TBI_Enable = 0x80, - TxFlowCtrl = 0x40, - RxFlowCtrl = 0x20, - _1000bpsF = 0x10, - _100bps = 0x08, - _10bps = 0x04, - LinkStatus = 0x02, - FullDup = 0x01, + TBI_Enable = 0x80, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, /* _TBICSRBit */ - TBILinkOK = 0x02000000, + TBILinkOK = 0x02000000, /* DumpCounterCommand */ - CounterDump = 0x8, + CounterDump = 0x8, }; -enum _DescStatusBit { +enum desc_status_bit { DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ @@ -478,28 +449,34 @@ static int rtl8169_poll(struct net_device *dev, int *budget); static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); -static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) +static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) { int i; - RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); + RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value); for (i = 20; i > 0; i--) { - /* Check if the RTL8169 has completed writing to the specified MII register */ + /* + * Check if the RTL8169 has completed writing to the specified + * MII register. + */ if (!(RTL_R32(PHYAR) & 0x80000000)) break; udelay(25); } } -static int mdio_read(void __iomem *ioaddr, int RegAddr) +static int mdio_read(void __iomem *ioaddr, int reg_addr) { int i, value = -1; - RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); + RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16); for (i = 20; i > 0; i--) { - /* Check if the RTL8169 has completed retrieving data from the specified MII register */ + /* + * Check if the RTL8169 has completed retrieving data from + * the specified MII register. + */ if (RTL_R32(PHYAR) & 0x80000000) { value = (int) (RTL_R32(PHYAR) & 0xFFFF); break; @@ -557,7 +534,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) } static void rtl8169_check_link_status(struct net_device *dev, - struct rtl8169_private *tp, void __iomem *ioaddr) + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned long flags; @@ -613,7 +591,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - int i; + unsigned int i; static struct { u32 opt; u16 reg; @@ -839,8 +817,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, int ret; if (tp->vlgrp && (opts2 & RxVlanTag)) { - rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, - swab16(opts2 & 0xffff)); + rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff)); ret = 0; } else ret = -1; @@ -1061,7 +1038,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) } } - static const struct ethtool_ops rtl8169_ethtool_ops = { .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, @@ -1087,8 +1063,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { .get_perm_addr = ethtool_op_get_perm_addr, }; -static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum, - int bitval) +static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, + int bitnum, int bitval) { int val; @@ -1098,7 +1074,8 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum mdio_write(ioaddr, reg, val & 0xffff); } -static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) +static void rtl8169_get_mac_version(struct rtl8169_private *tp, + void __iomem *ioaddr) { /* * The driver currently handles the 8168Bf and the 8168Be identically @@ -1140,7 +1117,8 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp) dprintk("mac_version = 0x%02x\n", tp->mac_version); } -static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) +static void rtl8169_get_phy_version(struct rtl8169_private *tp, + void __iomem *ioaddr) { const struct { u16 mask; @@ -1217,7 +1195,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev) 0xbf00 } //w 0 15 0 bf00 } }, *p = phy_magic; - int i; + unsigned int i; rtl8169_print_mac_version(tp); rtl8169_print_phy_version(tp); @@ -1351,7 +1329,7 @@ static void rtl8169_phy_reset(struct net_device *dev, struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - int i; + unsigned int i; tp->phy_reset_enable(ioaddr); for (i = 0; i < 100; i++) { @@ -1463,8 +1441,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct rtl8169_private *tp; struct net_device *dev; void __iomem *ioaddr; - unsigned int pm_cap; - int i, rc; + unsigned int i; + int rc; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", @@ -1497,20 +1475,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc < 0) goto err_out_disable_2; - /* save power state before pci_enable_device overwrites it */ - pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm_cap) { - u16 pwr_command, acpi_idle_state; - - pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); - acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; - } else { - if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, - "PowerManagement capability not found.\n"); - } - } - /* make sure PCI base addr 1 is MMIO */ if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { if (netif_msg_probe(tp)) { @@ -1574,7 +1538,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) RTL_W8(ChipCmd, CmdReset); /* Check that the chip has finished the reset. */ - for (i = 100; i > 0; i--) { + for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; msleep_interruptible(1); @@ -1706,15 +1670,11 @@ err_out_free_dev_1: goto out; } -static void __devexit -rtl8169_remove_one(struct pci_dev *pdev) +static void __devexit rtl8169_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - assert(dev != NULL); - assert(tp != NULL); - flush_scheduled_work(); unregister_netdev(dev); @@ -1814,13 +1774,13 @@ static void rtl_hw_start(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - u32 i; + unsigned int i; /* Soft reset the chip. */ RTL_W8(ChipCmd, CmdReset); /* Check that the chip has finished the reset. */ - for (i = 100; i > 0; i--) { + for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; msleep_interruptible(1); @@ -2132,7 +2092,7 @@ err_out: static void rtl8169_rx_clear(struct rtl8169_private *tp) { - int i; + unsigned int i; for (i = 0; i < NUM_RX_DESC; i++) { if (tp->Rx_skbuff[i]) { @@ -2274,14 +2234,9 @@ static void rtl8169_reinit_task(struct work_struct *work) ret = rtl8169_open(dev); if (unlikely(ret < 0)) { - if (net_ratelimit()) { - struct rtl8169_private *tp = netdev_priv(dev); - - if (netif_msg_drv(tp)) { - printk(PFX KERN_ERR - "%s: reinit failure (status = %d)." - " Rescheduling.\n", dev->name, ret); - } + if (net_ratelimit() && netif_msg_drv(tp)) { + printk(PFX KERN_ERR "%s: reinit failure (status = %d)." + " Rescheduling.\n", dev->name, ret); } rtl8169_schedule_work(dev, rtl8169_reinit_task); } @@ -2311,13 +2266,9 @@ static void rtl8169_reset_task(struct work_struct *work) rtl_hw_start(dev); netif_wake_queue(dev); } else { - if (net_ratelimit()) { - struct rtl8169_private *tp = netdev_priv(dev); - - if (netif_msg_intr(tp)) { - printk(PFX KERN_EMERG - "%s: Rx buffers shortage\n", dev->name); - } + if (net_ratelimit() && netif_msg_intr(tp)) { + printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", + dev->name); } rtl8169_schedule_work(dev, rtl8169_reset_task); } @@ -2524,16 +2475,12 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_schedule_work(dev, rtl8169_reinit_task); } -static void -rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl8169_tx_interrupt(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned int dirty_tx, tx_left; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); - dirty_tx = tp->dirty_tx; smp_rmb(); tx_left = tp->cur_tx - dirty_tx; @@ -2590,8 +2537,9 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) skb->ip_summed = CHECKSUM_NONE; } -static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, - struct pci_dev *pdev, dma_addr_t addr) +static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, + struct rtl8169_private *tp, int pkt_size, + dma_addr_t addr) { struct sk_buff *skb; bool done = false; @@ -2599,11 +2547,12 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, if (pkt_size >= rx_copybreak) goto out; - skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); + skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN); if (!skb) goto out; - pci_dma_sync_single_for_cpu(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); skb_reserve(skb, NET_IP_ALIGN); skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); *sk_buff = skb; @@ -2612,17 +2561,13 @@ out: return done; } -static int -rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) +static int rtl8169_rx_interrupt(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned int cur_rx, rx_left; unsigned int delta, count; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); - cur_rx = tp->cur_rx; rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota); @@ -2673,7 +2618,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, rtl8169_rx_csum(skb, desc); - if (rtl8169_try_rx_copy(&skb, pkt_size, pdev, addr)) { + if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { pci_dma_sync_single_for_device(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); rtl8169_mark_to_asic(desc, tp->rx_buf_sz); @@ -2723,11 +2668,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, return count; } -/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t -rtl8169_interrupt(int irq, void *dev_instance) +static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) { - struct net_device *dev = (struct net_device *) dev_instance; + struct net_device *dev = dev_instance; struct rtl8169_private *tp = netdev_priv(dev); int boguscnt = max_interrupt_work; void __iomem *ioaddr = tp->mmio_addr; @@ -2784,9 +2727,9 @@ rtl8169_interrupt(int irq, void *dev_instance) break; #else /* Rx interrupt */ - if (status & (RxOK | RxOverflow | RxFIFOOver)) { + if (status & (RxOK | RxOverflow | RxFIFOOver)) rtl8169_rx_interrupt(dev, tp, ioaddr); - } + /* Tx interrupt */ if (status & (TxOK | TxErr)) rtl8169_tx_interrupt(dev, tp, ioaddr); @@ -2918,7 +2861,7 @@ static void rtl_set_rx_mode(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; u32 mc_filter[2]; /* Multicast hash filter */ - int i, rx_mode; + int rx_mode; u32 tmp = 0; if (dev->flags & IFF_PROMISC) { @@ -2938,6 +2881,8 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = mc_filter[0] = 0xffffffff; } else { struct dev_mc_list *mclist; + unsigned int i; + rx_mode = AcceptBroadcast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0; for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; @@ -3053,14 +2998,12 @@ static struct pci_driver rtl8169_pci_driver = { #endif }; -static int __init -rtl8169_init_module(void) +static int __init rtl8169_init_module(void) { return pci_register_driver(&rtl8169_pci_driver); } -static void __exit -rtl8169_cleanup_module(void) +static void __exit rtl8169_cleanup_module(void) { pci_unregister_driver(&rtl8169_pci_driver); } From 275391a482c436282dde57beeffc5d61b229fdd2 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 23 Feb 2007 23:50:28 +0100 Subject: [PATCH 120/551] r8169: add bit description for the TxPoll register Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 5d9e75481f42..d8862cd84f3d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -250,6 +250,11 @@ enum rtl_register_content { CmdTxEnb = 0x04, RxBufEmpty = 0x01, + /* TXPoll register p.5 */ + HPQ = 0x80, /* Poll cmd on the high prio queue */ + NPQ = 0x40, /* Poll cmd on the low prio queue */ + FSWInt = 0x01, /* Forced software interrupt */ + /* Cfg9346Bits */ Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xc0, @@ -2405,7 +2410,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_wmb(); - RTL_W8(TxPoll, 0x40); /* set polling bit */ + RTL_W8(TxPoll, NPQ); /* set polling bit */ if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); From e9f63f30863fd778a5329e93c7e2208b9bcb5b79 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 28 Feb 2007 23:16:57 +0100 Subject: [PATCH 121/551] r8169: align the IP header when there is no DMA constraint Align the IP header when the chipset can DMA at any location (plain 0x8169). Otherwise (0x8136/0x8168) obey the constraint imposed by the hardware. This patch complements the previous alignment rework done for copybreak. Original idea from Philip Craig Signed-off-by: Francois Romieu Cc: Philip Craig Cc: Mike Isely Cc: Edward Hsu --- drivers/net/r8169.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d8862cd84f3d..1942bf7843aa 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1415,7 +1415,7 @@ static const struct rtl_cfg_info { [RTL_CFG_0] = { .hw_start = rtl_hw_start_8169, .region = 1, - .align = 2, + .align = 0, .intr_event = SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow @@ -2076,12 +2076,15 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, { struct sk_buff *skb; dma_addr_t mapping; + unsigned int pad; - skb = netdev_alloc_skb(dev, rx_buf_sz + align); + pad = align ? align : NET_IP_ALIGN; + + skb = netdev_alloc_skb(dev, rx_buf_sz + pad); if (!skb) goto err_out; - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); mapping = pci_map_single(pdev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); From 6cccd6e7a261263cdf06576bd1b241be575638b6 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 21 May 2007 22:11:04 +0200 Subject: [PATCH 122/551] r8169: add endianess annotations to [RT]xDesc Signed-off-by: Rolf Eike Beer Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1942bf7843aa..f66ee3ba363b 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -362,15 +362,15 @@ enum desc_status_bit { #define RsvdMask 0x3fffc000 struct TxDesc { - u32 opts1; - u32 opts2; - u64 addr; + __le32 opts1; + __le32 opts2; + __le64 addr; }; struct RxDesc { - u32 opts1; - u32 opts2; - u64 addr; + __le32 opts1; + __le32 opts2; + __le64 addr; }; struct ring_info { From 96b9709c9b47c1f9e8fd80e756e8eddcba68e818 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 30 May 2007 00:32:05 +0200 Subject: [PATCH 123/551] r8169: display some extra debug information during startup It does not cost much and it will ease the identification of (so far) unknown devices. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index f66ee3ba363b..dc8f369006d6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1646,15 +1646,17 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); if (netif_msg_probe(tp)) { + u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff; + printk(KERN_INFO "%s: %s at 0x%lx, " "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", + "XID %08x IRQ %d\n", dev->name, rtl_chip_info[tp->chipset].name, dev->base_addr, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], dev->irq); + dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq); } rtl8169_init_phy(dev, tp); From 773d202194be84cc17d35f62516eac6d8db833e6 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 31 Jan 2007 23:47:43 +0100 Subject: [PATCH 124/551] r8169: mac address change support Merged from Realtek's r8169-6.001 driver. I have added some locking to protect against the arp monitoring timer in the bonding driver. Accessing the configuration registers is otherwise performed under RTNL locking. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index dc8f369006d6..7aa9cf4e9e98 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -182,6 +182,7 @@ static struct { enum rtl_registers { MAC0 = 0, /* Ethernet hardware address. */ + MAC4 = 4, MAR0 = 8, /* Multicast filter. */ CounterAddrLow = 0x10, CounterAddrHigh = 0x14, @@ -1379,6 +1380,40 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); } +static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 high; + u32 low; + + low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); + high = addr[4] | (addr[5] << 8); + + spin_lock_irq(&tp->lock); + + RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W32(MAC0, low); + RTL_W32(MAC4, high); + RTL_W8(Cfg9346, Cfg9346_Lock); + + spin_unlock_irq(&tp->lock); +} + +static int rtl_set_mac_address(struct net_device *dev, void *p) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + rtl_rar_set(tp, dev->dev_addr); + + return 0; +} + static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1610,6 +1645,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; dev->change_mtu = rtl8169_change_mtu; + dev->set_mac_address = rtl_set_mac_address; #ifdef CONFIG_R8169_NAPI dev->poll = rtl8169_poll; From 57a9f236ebe76be6fe1c85b5f7b3cea842e44177 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 4 Jun 2007 22:10:15 +0200 Subject: [PATCH 125/551] r8169: perform RX config change after mac filtering It does not really make sense to update the RX config register before the mac filtering registers. Signed-off-by: Francois Romieu Cc: Edward Hsu --- drivers/net/r8169.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7aa9cf4e9e98..982a9010c7a9 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2953,10 +2953,11 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = 0xffffffff; } - RTL_W32(RxConfig, tmp); RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(MAR0 + 4, mc_filter[1]); + RTL_W32(RxConfig, tmp); + spin_unlock_irqrestore(&tp->lock, flags); } From e65bbf13dd6ca8c0a4fc35028742c8c85f39c02b Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Thu, 14 Jun 2007 18:12:23 -0500 Subject: [PATCH 126/551] spidernet: Replace literal with const Replace literal with const; add bit definitions. Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 2 +- drivers/net/spider_net.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 9d3ae35767b4..f5abb5279d4d 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1235,7 +1235,7 @@ spider_net_decode_one_descr(struct spider_net_card *card) goto bad_desc; } - if (hwdescr->dmac_cmd_status & 0xfcf4) { + if (hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_BAD_STATUS) { dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n", hwdescr->dmac_cmd_status); pr_err("buf_addr=x%08x\n", hw_buf_addr); diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 04007d7b0e41..dbbdb8cee3c6 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -354,6 +354,18 @@ enum spider_net_int2_status { #define SPIDER_NET_DMAC_UDP 0x00030000 #define SPIDER_NET_TXDCEST 0x08000000 +#define SPIDER_NET_DESCR_RXFDIS 0x00000001 +#define SPIDER_NET_DESCR_RXDCEIS 0x00000002 +#define SPIDER_NET_DESCR_RXDEN0IS 0x00000004 +#define SPIDER_NET_DESCR_RXINVDIS 0x00000008 +#define SPIDER_NET_DESCR_RXRERRIS 0x00000010 +#define SPIDER_NET_DESCR_RXFDCIMS 0x00000100 +#define SPIDER_NET_DESCR_RXDCEIMS 0x00000200 +#define SPIDER_NET_DESCR_RXDEN0IMS 0x00000400 +#define SPIDER_NET_DESCR_RXINVDIMS 0x00000800 +#define SPIDER_NET_DESCR_RXRERRMIS 0x00001000 +#define SPIDER_NET_DESCR_UNUSED 0x077fe0e0 + #define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 #define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ #define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ @@ -364,6 +376,13 @@ enum spider_net_int2_status { #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 +#define SPIDER_NET_DESCR_BAD_STATUS (SPIDER_NET_DESCR_RXDEN0IS | \ + SPIDER_NET_DESCR_RXRERRIS | \ + SPIDER_NET_DESCR_RXDEN0IMS | \ + SPIDER_NET_DESCR_RXINVDIMS | \ + SPIDER_NET_DESCR_RXRERRMIS | \ + SPIDER_NET_DESCR_UNUSED) + /* Descriptor, as defined by the hardware */ struct spider_net_hw_descr { u32 buf_addr; From 7c00db3d28131f4fff42eb49632dcd70636f31f4 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 22 Jun 2007 15:04:54 -0500 Subject: [PATCH 127/551] pasemi_mac: Fix TX interrupt threshold It was mistakenly set to interrupt on the second packet instead of first, causing some interesting latency behaviour. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 8d38425e46c3..0b3066a6fe40 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -755,7 +755,7 @@ static int pasemi_mac_open(struct net_device *dev) flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(1)); + PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); From d1d25aaba85fd24ab18b0a4d22f19be02aac65c9 Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Mon, 2 Jul 2007 13:00:46 +0200 Subject: [PATCH 128/551] ehea: Whitespace cleanup This patch fixes several whitespace issues. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 14 ++++----- drivers/net/ehea/ehea_hw.h | 24 ++++++++-------- drivers/net/ehea/ehea_main.c | 32 +++++++++++---------- drivers/net/ehea/ehea_qmr.c | 56 ++++++++++++++++++------------------ 4 files changed, 64 insertions(+), 62 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index c0f81b5a30fb..abaf3ac94936 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0064" +#define DRV_VERSION "EHEA_0065" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) @@ -136,10 +136,10 @@ void ehea_dump(void *adr, int len, char *msg); (0xffffffffffffffffULL >> ((64 - (mask)) & 0xffff)) #define EHEA_BMASK_SET(mask, value) \ - ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask)) + ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask)) #define EHEA_BMASK_GET(mask, value) \ - (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask))) + (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask))) /* * Generic ehea page @@ -190,7 +190,7 @@ struct ehea_av; * Queue attributes passed to ehea_create_qp() */ struct ehea_qp_init_attr { - /* input parameter */ + /* input parameter */ u32 qp_token; /* queue token */ u8 low_lat_rq1; u8 signalingtype; /* cqe generation flag */ @@ -212,7 +212,7 @@ struct ehea_qp_init_attr { u64 recv_cq_handle; u64 aff_eq_handle; - /* output parameter */ + /* output parameter */ u32 qp_nr; u16 act_nr_send_wqes; u16 act_nr_rwqes_rq1; @@ -279,12 +279,12 @@ struct ehea_qp { * Completion Queue attributes */ struct ehea_cq_attr { - /* input parameter */ + /* input parameter */ u32 max_nr_of_cqes; u32 cq_token; u64 eq_handle; - /* output parameter */ + /* output parameter */ u32 act_nr_of_cqes; u32 nr_pages; }; diff --git a/drivers/net/ehea/ehea_hw.h b/drivers/net/ehea/ehea_hw.h index 1246757f2c22..1af7ca499ec5 100644 --- a/drivers/net/ehea/ehea_hw.h +++ b/drivers/net/ehea/ehea_hw.h @@ -211,34 +211,34 @@ static inline void epa_store_acc(struct h_epa epa, u32 offset, u64 value) } #define epa_store_eq(epa, offset, value)\ - epa_store(epa, EQTEMM_OFFSET(offset), value) + epa_store(epa, EQTEMM_OFFSET(offset), value) #define epa_load_eq(epa, offset)\ - epa_load(epa, EQTEMM_OFFSET(offset)) + epa_load(epa, EQTEMM_OFFSET(offset)) #define epa_store_cq(epa, offset, value)\ - epa_store(epa, CQTEMM_OFFSET(offset), value) + epa_store(epa, CQTEMM_OFFSET(offset), value) #define epa_load_cq(epa, offset)\ - epa_load(epa, CQTEMM_OFFSET(offset)) + epa_load(epa, CQTEMM_OFFSET(offset)) #define epa_store_qp(epa, offset, value)\ - epa_store(epa, QPTEMM_OFFSET(offset), value) + epa_store(epa, QPTEMM_OFFSET(offset), value) #define epa_load_qp(epa, offset)\ - epa_load(epa, QPTEMM_OFFSET(offset)) + epa_load(epa, QPTEMM_OFFSET(offset)) #define epa_store_qped(epa, offset, value)\ - epa_store(epa, QPEDMM_OFFSET(offset), value) + epa_store(epa, QPEDMM_OFFSET(offset), value) #define epa_load_qped(epa, offset)\ - epa_load(epa, QPEDMM_OFFSET(offset)) + epa_load(epa, QPEDMM_OFFSET(offset)) #define epa_store_mrmw(epa, offset, value)\ - epa_store(epa, MRMWMM_OFFSET(offset), value) + epa_store(epa, MRMWMM_OFFSET(offset), value) #define epa_load_mrmw(epa, offset)\ - epa_load(epa, MRMWMM_OFFSET(offset)) + epa_load(epa, MRMWMM_OFFSET(offset)) #define epa_store_base(epa, offset, value)\ - epa_store(epa, HCAGR_OFFSET(offset), value) + epa_store(epa, HCAGR_OFFSET(offset), value) #define epa_load_base(epa, offset)\ - epa_load(epa, HCAGR_OFFSET(offset)) + epa_load(epa, HCAGR_OFFSET(offset)) static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes) { diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 9e13433a268a..bdb52419dbf5 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -81,7 +81,7 @@ MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); static int port_name_cnt = 0; static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, - const struct of_device_id *id); + const struct of_device_id *id); static int __devexit ehea_remove(struct ibmebus_dev *dev); @@ -236,7 +236,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr, rwqe = ehea_get_next_rwqe(qp, rq_nr); rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type) - | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); + | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); rwqe->sg_list[0].l_key = pr->recv_mr.lkey; rwqe->sg_list[0].vaddr = (u64)skb->data; rwqe->sg_list[0].len = packet_size; @@ -427,7 +427,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev, break; } skb_copy_to_linear_data(skb, ((char*)cqe) + 64, - cqe->num_bytes_transfered - 4); + cqe->num_bytes_transfered - 4); ehea_fill_skb(port->netdev, skb, cqe); } else if (rq == 2) { /* RQ2 */ skb = get_skb_by_index(skb_arr_rq2, @@ -618,7 +618,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, for (i = 0; i < EHEA_MAX_PORTS; i++) if (adapter->port[i]) - if (adapter->port[i]->logical_port_id == logical_port) + if (adapter->port[i]->logical_port_id == logical_port) return adapter->port[i]; return NULL; } @@ -1695,6 +1695,7 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev, { if (skb->protocol == htons(ETH_P_IP)) { const struct iphdr *iph = ip_hdr(skb); + /* IPv4 */ swqe->tx_control |= EHEA_SWQE_CRC | EHEA_SWQE_IP_CHECKSUM @@ -1705,13 +1706,12 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev, write_ip_start_end(swqe, skb); if (iph->protocol == IPPROTO_UDP) { - if ((iph->frag_off & IP_MF) || - (iph->frag_off & IP_OFFSET)) + if ((iph->frag_off & IP_MF) + || (iph->frag_off & IP_OFFSET)) /* IP fragment, so don't change cs */ swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM; else write_udp_offset_end(swqe, skb); - } else if (iph->protocol == IPPROTO_TCP) { write_tcp_offset_end(swqe, skb); } @@ -1739,6 +1739,7 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, if (skb->protocol == htons(ETH_P_IP)) { const struct iphdr *iph = ip_hdr(skb); + /* IPv4 */ write_ip_start_end(swqe, skb); @@ -1751,8 +1752,8 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, write_tcp_offset_end(swqe, skb); } else if (iph->protocol == IPPROTO_UDP) { - if ((iph->frag_off & IP_MF) || - (iph->frag_off & IP_OFFSET)) + if ((iph->frag_off & IP_MF) + || (iph->frag_off & IP_OFFSET)) /* IP fragment, so don't change cs */ swqe->tx_control |= EHEA_SWQE_CRC | EHEA_SWQE_IMM_DATA_PRESENT; @@ -2407,7 +2408,7 @@ static void __devinit logical_port_release(struct device *dev) } static int ehea_driver_sysfs_add(struct device *dev, - struct device_driver *driver) + struct device_driver *driver) { int ret; @@ -2424,7 +2425,7 @@ static int ehea_driver_sysfs_add(struct device *dev, } static void ehea_driver_sysfs_remove(struct device *dev, - struct device_driver *driver) + struct device_driver *driver) { struct device_driver *drv = driver; @@ -2453,7 +2454,7 @@ static struct device *ehea_register_port(struct ehea_port *port, } ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); - if (ret) { + if (ret) { ehea_error("failed to register attributes, ret=%d", ret); goto out_unreg_of_dev; } @@ -2601,6 +2602,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) { struct device_node *lhea_dn; struct device_node *eth_dn = NULL; + const u32 *dn_log_port_id; int i = 0; @@ -2608,7 +2610,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", - NULL); + NULL); if (!dn_log_port_id) { ehea_error("bad device node: eth_dn name=%s", eth_dn->full_name); @@ -2648,7 +2650,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", - NULL); + NULL); if (dn_log_port_id) if (*dn_log_port_id == logical_port_id) return eth_dn; @@ -2789,7 +2791,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, adapter->ebus_dev = dev; adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", - NULL); + NULL); if (adapter_handle) adapter->handle = *adapter_handle; diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index f24a8862977d..29eaa46948b0 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -211,7 +211,7 @@ u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force) u64 hret; u64 adapter_handle = cq->adapter->handle; - /* deregister all previous registered pages */ + /* deregister all previous registered pages */ hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force); if (hret != H_SUCCESS) return hret; @@ -362,7 +362,7 @@ int ehea_destroy_eq(struct ehea_eq *eq) if (hret != H_SUCCESS) { ehea_error("destroy EQ failed"); return -EIO; - } + } return 0; } @@ -507,44 +507,44 @@ out_freemem: u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) { - u64 hret; - struct ehea_qp_init_attr *qp_attr = &qp->init_attr; + u64 hret; + struct ehea_qp_init_attr *qp_attr = &qp->init_attr; - ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); - hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); - if (hret != H_SUCCESS) - return hret; + ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); + hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); + if (hret != H_SUCCESS) + return hret; - hw_queue_dtor(&qp->hw_squeue); - hw_queue_dtor(&qp->hw_rqueue1); + hw_queue_dtor(&qp->hw_squeue); + hw_queue_dtor(&qp->hw_rqueue1); - if (qp_attr->rq_count > 1) - hw_queue_dtor(&qp->hw_rqueue2); - if (qp_attr->rq_count > 2) - hw_queue_dtor(&qp->hw_rqueue3); - kfree(qp); + if (qp_attr->rq_count > 1) + hw_queue_dtor(&qp->hw_rqueue2); + if (qp_attr->rq_count > 2) + hw_queue_dtor(&qp->hw_rqueue3); + kfree(qp); - return hret; + return hret; } int ehea_destroy_qp(struct ehea_qp *qp) { - u64 hret; - if (!qp) - return 0; + u64 hret; + if (!qp) + return 0; - if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { - ehea_error_data(qp->adapter, qp->fw_handle); - hret = ehea_destroy_qp_res(qp, FORCE_FREE); - } + if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { + ehea_error_data(qp->adapter, qp->fw_handle); + hret = ehea_destroy_qp_res(qp, FORCE_FREE); + } - if (hret != H_SUCCESS) { - ehea_error("destroy QP failed"); - return -EIO; - } + if (hret != H_SUCCESS) { + ehea_error("destroy QP failed"); + return -EIO; + } - return 0; + return 0; } int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) From 2187f287e2827556210e96c619f76f0f9dd928f0 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 28 Jun 2007 00:46:22 +0200 Subject: [PATCH 129/551] Extract chip specific code out of lasi_82596.c Changes to last version: - use netdev_alloc_skb - make init_rx_bufs just fail and not panic, if skb alloc fails - don/t free_irq, if request_irq failed Thomas. Extracted chip specific code out of lasi_82596.c and placed into a lib82596.c to make it usable for other 82596 drivers Signed-off-by: Thomas Bogendoerfer Signed-off-by: Jeff Garzik --- drivers/net/lasi_82596.c | 1460 ++------------------------------------ drivers/net/lib82596.c | 1434 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1483 insertions(+), 1411 deletions(-) create mode 100644 drivers/net/lib82596.c diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 741780e14b2c..efbae4b8398e 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -86,93 +86,36 @@ #include #include -#include #include #include -#include #include #define LASI_82596_DRIVER_VERSION "LASI 82596 driver - Revision: 1.30" -/* DEBUG flags - */ - -#define DEB_INIT 0x0001 -#define DEB_PROBE 0x0002 -#define DEB_SERIOUS 0x0004 -#define DEB_ERRORS 0x0008 -#define DEB_MULTI 0x0010 -#define DEB_TDR 0x0020 -#define DEB_OPEN 0x0040 -#define DEB_RESET 0x0080 -#define DEB_ADDCMD 0x0100 -#define DEB_STATUS 0x0200 -#define DEB_STARTTX 0x0400 -#define DEB_RXADDR 0x0800 -#define DEB_TXADDR 0x1000 -#define DEB_RXFRAME 0x2000 -#define DEB_INTS 0x4000 -#define DEB_STRUCT 0x8000 -#define DEB_ANY 0xffff - - -#define DEB(x,y) if (i596_debug & (x)) { y; } - - -#define CHECK_WBACK(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0) - -#define CHECK_INV(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0) - -#define CHECK_WBACK_INV(priv, addr,len) \ - do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0) - - #define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ #define PA_CPU_PORT_L_ACCESS 4 #define PA_CHANNEL_ATTENTION 8 +#define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */ -/* - * Define various macros for Channel Attention, word swapping etc., dependent - * on architecture. MVME and BVME are 680x0 based, otherwise it is Intel. - */ +#define DMA_ALLOC dma_alloc_noncoherent +#define DMA_FREE dma_free_noncoherent +#define DMA_WBACK(ndev, addr, len) \ + do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0) -#ifdef __BIG_ENDIAN -#define WSWAPrfd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPrbd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPiscp(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPscb(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPcmd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPtbd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define WSWAPchar(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) -#define ISCP_BUSY 0x00010000 -#define MACH_IS_APRICOT 0 -#else -#define WSWAPrfd(x) ((struct i596_rfd *)(x)) -#define WSWAPrbd(x) ((struct i596_rbd *)(x)) -#define WSWAPiscp(x) ((struct i596_iscp *)(x)) -#define WSWAPscb(x) ((struct i596_scb *)(x)) -#define WSWAPcmd(x) ((struct i596_cmd *)(x)) -#define WSWAPtbd(x) ((struct i596_tbd *)(x)) -#define WSWAPchar(x) ((char *)(x)) -#define ISCP_BUSY 0x0001 -#define MACH_IS_APRICOT 1 -#endif +#define DMA_INV(ndev, addr, len) \ + do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_FROM_DEVICE); } while (0) -/* - * The MPU_PORT command allows direct access to the 82596. With PORT access - * the following commands are available (p5-18). The 32-bit port command - * must be word-swapped with the most significant word written first. - * This only applies to VME boards. - */ -#define PORT_RESET 0x00 /* reset 82596 */ -#define PORT_SELFTEST 0x01 /* selftest */ -#define PORT_ALTSCP 0x02 /* alternate SCB address */ -#define PORT_ALTDUMP 0x03 /* Alternate DUMP address */ +#define DMA_WBACK_INV(ndev, addr, len) \ + do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0) -static int i596_debug = (DEB_SERIOUS|DEB_PROBE); +#define SYSBUS 0x0000006c; + +/* big endian CPU, 82596 "big" endian mode */ +#define SWAP32(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) +#define SWAP16(x) (x) + +#include "lib82596.c" MODULE_AUTHOR("Richard Hirst"); MODULE_DESCRIPTION("i82596 driver"); @@ -180,255 +123,15 @@ MODULE_LICENSE("GPL"); module_param(i596_debug, int, 0); MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask"); -/* Copy frames shorter than rx_copybreak, otherwise pass on up in - * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha). - */ -static int rx_copybreak = 100; - -#define MAX_DRIVERS 4 /* max count of drivers */ - -#define PKT_BUF_SZ 1536 -#define MAX_MC_CNT 64 - -#define I596_NULL ((u32)0xffffffff) - -#define CMD_EOL 0x8000 /* The last command of the list, stop. */ -#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ -#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ - -#define CMD_FLEX 0x0008 /* Enable flexible memory model */ - -enum commands { - CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, - CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7 -}; - -#define STAT_C 0x8000 /* Set to 0 after execution */ -#define STAT_B 0x4000 /* Command being executed */ -#define STAT_OK 0x2000 /* Command executed ok */ -#define STAT_A 0x1000 /* Command aborted */ - -#define CUC_START 0x0100 -#define CUC_RESUME 0x0200 -#define CUC_SUSPEND 0x0300 -#define CUC_ABORT 0x0400 -#define RX_START 0x0010 -#define RX_RESUME 0x0020 -#define RX_SUSPEND 0x0030 -#define RX_ABORT 0x0040 - -#define TX_TIMEOUT 5 - -#define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */ - - -struct i596_reg { - unsigned short porthi; - unsigned short portlo; - u32 ca; -}; - -#define EOF 0x8000 -#define SIZE_MASK 0x3fff - -struct i596_tbd { - unsigned short size; - unsigned short pad; - dma_addr_t next; - dma_addr_t data; - u32 cache_pad[5]; /* Total 32 bytes... */ -}; - -/* The command structure has two 'next' pointers; v_next is the address of - * the next command as seen by the CPU, b_next is the address of the next - * command as seen by the 82596. The b_next pointer, as used by the 82596 - * always references the status field of the next command, rather than the - * v_next field, because the 82596 is unaware of v_next. It may seem more - * logical to put v_next at the end of the structure, but we cannot do that - * because the 82596 expects other fields to be there, depending on command - * type. - */ - -struct i596_cmd { - struct i596_cmd *v_next; /* Address from CPUs viewpoint */ - unsigned short status; - unsigned short command; - dma_addr_t b_next; /* Address from i596 viewpoint */ -}; - -struct tx_cmd { - struct i596_cmd cmd; - dma_addr_t tbd; - unsigned short size; - unsigned short pad; - struct sk_buff *skb; /* So we can free it after tx */ - dma_addr_t dma_addr; -#ifdef __LP64__ - u32 cache_pad[6]; /* Total 64 bytes... */ -#else - u32 cache_pad[1]; /* Total 32 bytes... */ -#endif -}; - -struct tdr_cmd { - struct i596_cmd cmd; - unsigned short status; - unsigned short pad; -}; - -struct mc_cmd { - struct i596_cmd cmd; - short mc_cnt; - char mc_addrs[MAX_MC_CNT*6]; -}; - -struct sa_cmd { - struct i596_cmd cmd; - char eth_addr[8]; -}; - -struct cf_cmd { - struct i596_cmd cmd; - char i596_config[16]; -}; - -struct i596_rfd { - unsigned short stat; - unsigned short cmd; - dma_addr_t b_next; /* Address from i596 viewpoint */ - dma_addr_t rbd; - unsigned short count; - unsigned short size; - struct i596_rfd *v_next; /* Address from CPUs viewpoint */ - struct i596_rfd *v_prev; -#ifndef __LP64__ - u32 cache_pad[2]; /* Total 32 bytes... */ -#endif -}; - -struct i596_rbd { - /* hardware data */ - unsigned short count; - unsigned short zero1; - dma_addr_t b_next; - dma_addr_t b_data; /* Address from i596 viewpoint */ - unsigned short size; - unsigned short zero2; - /* driver data */ - struct sk_buff *skb; - struct i596_rbd *v_next; - dma_addr_t b_addr; /* This rbd addr from i596 view */ - unsigned char *v_data; /* Address from CPUs viewpoint */ - /* Total 32 bytes... */ -#ifdef __LP64__ - u32 cache_pad[4]; -#endif -}; - -/* These values as chosen so struct i596_private fits in one page... */ - -#define TX_RING_SIZE 32 -#define RX_RING_SIZE 16 - -struct i596_scb { - unsigned short status; - unsigned short command; - dma_addr_t cmd; - dma_addr_t rfd; - u32 crc_err; - u32 align_err; - u32 resource_err; - u32 over_err; - u32 rcvdt_err; - u32 short_err; - unsigned short t_on; - unsigned short t_off; -}; - -struct i596_iscp { - u32 stat; - dma_addr_t scb; -}; - -struct i596_scp { - u32 sysbus; - u32 pad; - dma_addr_t iscp; -}; - -struct i596_private { - volatile struct i596_scp scp __attribute__((aligned(32))); - volatile struct i596_iscp iscp __attribute__((aligned(32))); - volatile struct i596_scb scb __attribute__((aligned(32))); - struct sa_cmd sa_cmd __attribute__((aligned(32))); - struct cf_cmd cf_cmd __attribute__((aligned(32))); - struct tdr_cmd tdr_cmd __attribute__((aligned(32))); - struct mc_cmd mc_cmd __attribute__((aligned(32))); - struct i596_rfd rfds[RX_RING_SIZE] __attribute__((aligned(32))); - struct i596_rbd rbds[RX_RING_SIZE] __attribute__((aligned(32))); - struct tx_cmd tx_cmds[TX_RING_SIZE] __attribute__((aligned(32))); - struct i596_tbd tbds[TX_RING_SIZE] __attribute__((aligned(32))); - u32 stat; - int last_restart; - struct i596_rfd *rfd_head; - struct i596_rbd *rbd_head; - struct i596_cmd *cmd_tail; - struct i596_cmd *cmd_head; - int cmd_backlog; - u32 last_cmd; - struct net_device_stats stats; - int next_tx_cmd; - int options; - spinlock_t lock; - dma_addr_t dma_addr; - struct device *dev; -}; - -static const char init_setup[] = -{ - 0x8E, /* length, prefetch on */ - 0xC8, /* fifo to 8, monitor off */ - 0x80, /* don't save bad frames */ - 0x2E, /* No source address insertion, 8 byte preamble */ - 0x00, /* priority and backoff defaults */ - 0x60, /* interframe spacing */ - 0x00, /* slot time LSB */ - 0xf2, /* slot time and retries */ - 0x00, /* promiscuous mode */ - 0x00, /* collision detect */ - 0x40, /* minimum frame length */ - 0xff, - 0x00, - 0x7f /* *multi IA */ }; - -static int i596_open(struct net_device *dev); -static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t i596_interrupt(int irq, void *dev_id); -static int i596_close(struct net_device *dev); -static struct net_device_stats *i596_get_stats(struct net_device *dev); -static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); -static void i596_tx_timeout (struct net_device *dev); -static void print_eth(unsigned char *buf, char *str); -static void set_multicast_list(struct net_device *dev); - -static int rx_ring_size = RX_RING_SIZE; -static int ticks_limit = 100; -static int max_cmd_backlog = TX_RING_SIZE-1; - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void i596_poll_controller(struct net_device *dev); -#endif - - -static inline void CA(struct net_device *dev) +static inline void ca(struct net_device *dev) { gsc_writel(0, dev->base_addr + PA_CHANNEL_ATTENTION); } -static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) +static void mpu_port(struct net_device *dev, int c, dma_addr_t x) { - struct i596_private *lp = dev->priv; + struct i596_private *lp = netdev_priv(dev); u32 v = (u32) (c) | (u32) (x); u16 a, b; @@ -446,1078 +149,15 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS); } - -static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) -{ - CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); - while (--delcnt && lp->iscp.stat) { - udelay(10); - CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); - } - if (!delcnt) { - printk("%s: %s, iscp.stat %04x, didn't clear\n", - dev->name, str, lp->iscp.stat); - return -1; - } - else - return 0; -} - - -static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) -{ - CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); - while (--delcnt && lp->scb.command) { - udelay(10); - CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); - } - if (!delcnt) { - printk("%s: %s, status %4.4x, cmd %4.4x.\n", - dev->name, str, lp->scb.status, lp->scb.command); - return -1; - } - else - return 0; -} - - -static void i596_display_data(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - struct i596_cmd *cmd; - struct i596_rfd *rfd; - struct i596_rbd *rbd; - - printk("lp and scp at %p, .sysbus = %08x, .iscp = %08x\n", - &lp->scp, lp->scp.sysbus, lp->scp.iscp); - printk("iscp at %p, iscp.stat = %08x, .scb = %08x\n", - &lp->iscp, lp->iscp.stat, lp->iscp.scb); - printk("scb at %p, scb.status = %04x, .command = %04x," - " .cmd = %08x, .rfd = %08x\n", - &lp->scb, lp->scb.status, lp->scb.command, - lp->scb.cmd, lp->scb.rfd); - printk(" errors: crc %x, align %x, resource %x," - " over %x, rcvdt %x, short %x\n", - lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err, - lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err); - cmd = lp->cmd_head; - while (cmd != NULL) { - printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %08x\n", - cmd, cmd->status, cmd->command, cmd->b_next); - cmd = cmd->v_next; - } - rfd = lp->rfd_head; - printk("rfd_head = %p\n", rfd); - do { - printk(" %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x," - " count %04x\n", - rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd, - rfd->count); - rfd = rfd->v_next; - } while (rfd != lp->rfd_head); - rbd = lp->rbd_head; - printk("rbd_head = %p\n", rbd); - do { - printk(" %p .count %04x, b_next %08x, b_data %08x, size %04x\n", - rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size); - rbd = rbd->v_next; - } while (rbd != lp->rbd_head); - CHECK_INV(lp, lp, sizeof(struct i596_private)); -} - - -#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET) -static void i596_error(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000; - - pcc2[0x28] = 1; - pcc2[0x2b] = 0x1d; - printk("%s: Error interrupt\n", dev->name); - i596_display_data(dev); -} -#endif - -#define virt_to_dma(lp,v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)(lp))) - -static inline void init_rx_bufs(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - int i; - struct i596_rfd *rfd; - struct i596_rbd *rbd; - - /* First build the Receive Buffer Descriptor List */ - - for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { - dma_addr_t dma_addr; - struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ + 4); - - if (skb == NULL) - panic("%s: alloc_skb() failed", __FILE__); - skb_reserve(skb, 2); - dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ, - DMA_FROM_DEVICE); - skb->dev = dev; - rbd->v_next = rbd+1; - rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); - rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd)); - rbd->skb = skb; - rbd->v_data = skb->data; - rbd->b_data = WSWAPchar(dma_addr); - rbd->size = PKT_BUF_SZ; - } - lp->rbd_head = lp->rbds; - rbd = lp->rbds + rx_ring_size - 1; - rbd->v_next = lp->rbds; - rbd->b_next = WSWAPrbd(virt_to_dma(lp,lp->rbds)); - - /* Now build the Receive Frame Descriptor List */ - - for (i = 0, rfd = lp->rfds; i < rx_ring_size; i++, rfd++) { - rfd->rbd = I596_NULL; - rfd->v_next = rfd+1; - rfd->v_prev = rfd-1; - rfd->b_next = WSWAPrfd(virt_to_dma(lp,rfd+1)); - rfd->cmd = CMD_FLEX; - } - lp->rfd_head = lp->rfds; - lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - rfd = lp->rfds; - rfd->rbd = WSWAPrbd(virt_to_dma(lp,lp->rbd_head)); - rfd->v_prev = lp->rfds + rx_ring_size - 1; - rfd = lp->rfds + rx_ring_size - 1; - rfd->v_next = lp->rfds; - rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - rfd->cmd = CMD_EOL|CMD_FLEX; - - CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); -} - -static inline void remove_rx_bufs(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - struct i596_rbd *rbd; - int i; - - for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { - if (rbd->skb == NULL) - break; - dma_unmap_single(lp->dev, - (dma_addr_t)WSWAPchar(rbd->b_data), - PKT_BUF_SZ, DMA_FROM_DEVICE); - dev_kfree_skb(rbd->skb); - } -} - - -static void rebuild_rx_bufs(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - int i; - - /* Ensure rx frame/buffer descriptors are tidy */ - - for (i = 0; i < rx_ring_size; i++) { - lp->rfds[i].rbd = I596_NULL; - lp->rfds[i].cmd = CMD_FLEX; - } - lp->rfds[rx_ring_size-1].cmd = CMD_EOL|CMD_FLEX; - lp->rfd_head = lp->rfds; - lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - lp->rbd_head = lp->rbds; - lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds)); - - CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); -} - - -static int init_i596_mem(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - unsigned long flags; - - disable_irq(dev->irq); /* disable IRQs from LAN */ - DEB(DEB_INIT, - printk("RESET 82596 port: %lx (with IRQ %d disabled)\n", - (dev->base_addr + PA_I82596_RESET), - dev->irq)); - - gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */ - udelay(100); /* Wait 100us - seems to help */ - - /* change the scp address */ - - lp->last_cmd = jiffies; - - - lp->scp.sysbus = 0x0000006c; - lp->scp.iscp = WSWAPiscp(virt_to_dma(lp,&(lp->iscp))); - lp->iscp.scb = WSWAPscb(virt_to_dma(lp,&(lp->scb))); - lp->iscp.stat = ISCP_BUSY; - lp->cmd_backlog = 0; - - lp->cmd_head = NULL; - lp->scb.cmd = I596_NULL; - - DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name)); - - CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp)); - CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp)); - - MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp)); - - CA(dev); - - if (wait_istat(dev, lp, 1000, "initialization timed out")) - goto failed; - DEB(DEB_INIT, printk("%s: i82596 initialization successful\n", dev->name)); - - /* Ensure rx frame/buffer descriptors are tidy */ - rebuild_rx_bufs(dev); - - lp->scb.command = 0; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); - - enable_irq(dev->irq); /* enable IRQs from LAN */ - - DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name)); - memcpy(lp->cf_cmd.i596_config, init_setup, sizeof(init_setup)); - lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd)); - i596_add_cmd(dev, &lp->cf_cmd.cmd); - - DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name)); - memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6); - lp->sa_cmd.cmd.command = CmdSASetup; - CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd)); - i596_add_cmd(dev, &lp->sa_cmd.cmd); - - DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name)); - lp->tdr_cmd.cmd.command = CmdTDR; - CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd)); - i596_add_cmd(dev, &lp->tdr_cmd.cmd); - - spin_lock_irqsave (&lp->lock, flags); - - if (wait_cmd(dev, lp, 1000, "timed out waiting to issue RX_START")) { - spin_unlock_irqrestore (&lp->lock, flags); - goto failed; - } - DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name)); - lp->scb.command = RX_START; - lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); - - CA(dev); - - spin_unlock_irqrestore (&lp->lock, flags); - - if (wait_cmd(dev, lp, 1000, "RX_START not processed")) - goto failed; - DEB(DEB_INIT, printk("%s: Receive unit started OK\n", dev->name)); - - return 0; - -failed: - printk("%s: Failed to initialise 82596\n", dev->name); - MPU_PORT(dev, PORT_RESET, 0); - return -1; -} - - -static inline int i596_rx(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - struct i596_rfd *rfd; - struct i596_rbd *rbd; - int frames = 0; - - DEB(DEB_RXFRAME, printk("i596_rx(), rfd_head %p, rbd_head %p\n", - lp->rfd_head, lp->rbd_head)); - - - rfd = lp->rfd_head; /* Ref next frame to check */ - - CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); - while ((rfd->stat) & STAT_C) { /* Loop while complete frames */ - if (rfd->rbd == I596_NULL) - rbd = NULL; - else if (rfd->rbd == lp->rbd_head->b_addr) { - rbd = lp->rbd_head; - CHECK_INV(lp, rbd, sizeof(struct i596_rbd)); - } - else { - printk("%s: rbd chain broken!\n", dev->name); - /* XXX Now what? */ - rbd = NULL; - } - DEB(DEB_RXFRAME, printk(" rfd %p, rfd.rbd %08x, rfd.stat %04x\n", - rfd, rfd->rbd, rfd->stat)); - - if (rbd != NULL && ((rfd->stat) & STAT_OK)) { - /* a good frame */ - int pkt_len = rbd->count & 0x3fff; - struct sk_buff *skb = rbd->skb; - int rx_in_place = 0; - - DEB(DEB_RXADDR,print_eth(rbd->v_data, "received")); - frames++; - - /* Check if the packet is long enough to just accept - * without copying to a properly sized skbuff. - */ - - if (pkt_len > rx_copybreak) { - struct sk_buff *newskb; - dma_addr_t dma_addr; - - dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); - /* Get fresh skbuff to replace filled one. */ - newskb = dev_alloc_skb(PKT_BUF_SZ + 4); - if (newskb == NULL) { - skb = NULL; /* drop pkt */ - goto memory_squeeze; - } - skb_reserve(newskb, 2); - - /* Pass up the skb already on the Rx ring. */ - skb_put(skb, pkt_len); - rx_in_place = 1; - rbd->skb = newskb; - newskb->dev = dev; - dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); - rbd->v_data = newskb->data; - rbd->b_data = WSWAPchar(dma_addr); - CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); - } - else - skb = dev_alloc_skb(pkt_len + 2); -memory_squeeze: - if (skb == NULL) { - /* XXX tulip.c can defer packets here!! */ - printk("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; - } - else { - if (!rx_in_place) { - /* 16 byte align the data fields */ - dma_sync_single_for_cpu(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); - skb_reserve(skb, 2); - memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len); - dma_sync_single_for_device(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); - } - skb->len = pkt_len; - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes+=pkt_len; - } - } - else { - DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n", - dev->name, rfd->stat)); - lp->stats.rx_errors++; - if ((rfd->stat) & 0x0001) - lp->stats.collisions++; - if ((rfd->stat) & 0x0080) - lp->stats.rx_length_errors++; - if ((rfd->stat) & 0x0100) - lp->stats.rx_over_errors++; - if ((rfd->stat) & 0x0200) - lp->stats.rx_fifo_errors++; - if ((rfd->stat) & 0x0400) - lp->stats.rx_frame_errors++; - if ((rfd->stat) & 0x0800) - lp->stats.rx_crc_errors++; - if ((rfd->stat) & 0x1000) - lp->stats.rx_length_errors++; - } - - /* Clear the buffer descriptor count and EOF + F flags */ - - if (rbd != NULL && (rbd->count & 0x4000)) { - rbd->count = 0; - lp->rbd_head = rbd->v_next; - CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); - } - - /* Tidy the frame descriptor, marking it as end of list */ - - rfd->rbd = I596_NULL; - rfd->stat = 0; - rfd->cmd = CMD_EOL|CMD_FLEX; - rfd->count = 0; - - /* Remove end-of-list from old end descriptor */ - - rfd->v_prev->cmd = CMD_FLEX; - - /* Update record of next frame descriptor to process */ - - lp->scb.rfd = rfd->b_next; - lp->rfd_head = rfd->v_next; - CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd)); - CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd)); - rfd = lp->rfd_head; - CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); - } - - DEB(DEB_RXFRAME, printk("frames %d\n", frames)); - - return 0; -} - - -static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) -{ - struct i596_cmd *ptr; - - while (lp->cmd_head != NULL) { - ptr = lp->cmd_head; - lp->cmd_head = ptr->v_next; - lp->cmd_backlog--; - - switch ((ptr->command) & 0x7) { - case CmdTx: - { - struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; - struct sk_buff *skb = tx_cmd->skb; - dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); - - dev_kfree_skb(skb); - - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - - ptr->v_next = NULL; - ptr->b_next = I596_NULL; - tx_cmd->cmd.command = 0; /* Mark as free */ - break; - } - default: - ptr->v_next = NULL; - ptr->b_next = I596_NULL; - } - CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd)); - } - - wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out"); - lp->scb.cmd = I596_NULL; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); -} - - -static inline void i596_reset(struct net_device *dev, struct i596_private *lp) -{ - unsigned long flags; - - DEB(DEB_RESET, printk("i596_reset\n")); - - spin_lock_irqsave (&lp->lock, flags); - - wait_cmd(dev, lp, 100, "i596_reset timed out"); - - netif_stop_queue(dev); - - /* FIXME: this command might cause an lpmc */ - lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); - CA(dev); - - /* wait for shutdown */ - wait_cmd(dev, lp, 1000, "i596_reset 2 timed out"); - spin_unlock_irqrestore (&lp->lock, flags); - - i596_cleanup_cmd(dev,lp); - i596_rx(dev); - - netif_start_queue(dev); - init_i596_mem(dev); -} - - -static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) -{ - struct i596_private *lp = dev->priv; - unsigned long flags; - - DEB(DEB_ADDCMD, printk("i596_add_cmd cmd_head %p\n", lp->cmd_head)); - - cmd->status = 0; - cmd->command |= (CMD_EOL | CMD_INTR); - cmd->v_next = NULL; - cmd->b_next = I596_NULL; - CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd)); - - spin_lock_irqsave (&lp->lock, flags); - - if (lp->cmd_head != NULL) { - lp->cmd_tail->v_next = cmd; - lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status)); - CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd)); - } else { - lp->cmd_head = cmd; - wait_cmd(dev, lp, 100, "i596_add_cmd timed out"); - lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status)); - lp->scb.command = CUC_START; - CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); - CA(dev); - } - lp->cmd_tail = cmd; - lp->cmd_backlog++; - - spin_unlock_irqrestore (&lp->lock, flags); - - if (lp->cmd_backlog > max_cmd_backlog) { - unsigned long tickssofar = jiffies - lp->last_cmd; - - if (tickssofar < ticks_limit) - return; - - printk("%s: command unit timed out, status resetting.\n", dev->name); -#if 1 - i596_reset(dev, lp); -#endif - } -} - -#if 0 -/* this function makes a perfectly adequate probe... but we have a - device list */ -static int i596_test(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - volatile int *tint; - u32 data; - - tint = (volatile int *)(&(lp->scp)); - data = virt_to_dma(lp,tint); - - tint[1] = -1; - CHECK_WBACK(lp, tint, PAGE_SIZE); - - MPU_PORT(dev, 1, data); - - for(data = 1000000; data; data--) { - CHECK_INV(lp, tint, PAGE_SIZE); - if(tint[1] != -1) - break; - - } - - printk("i596_test result %d\n", tint[1]); - -} -#endif - - -static int i596_open(struct net_device *dev) -{ - DEB(DEB_OPEN, printk("%s: i596_open() irq %d.\n", dev->name, dev->irq)); - - if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) { - printk("%s: IRQ %d not free\n", dev->name, dev->irq); - goto out; - } - - init_rx_bufs(dev); - - if (init_i596_mem(dev)) { - printk("%s: Failed to init memory\n", dev->name); - goto out_remove_rx_bufs; - } - - netif_start_queue(dev); - - return 0; - -out_remove_rx_bufs: - remove_rx_bufs(dev); - free_irq(dev->irq, dev); -out: - return -EAGAIN; -} - -static void i596_tx_timeout (struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - - /* Transmitter timeout, serious problems. */ - DEB(DEB_ERRORS, printk("%s: transmit timed out, status resetting.\n", - dev->name)); - - lp->stats.tx_errors++; - - /* Try to restart the adaptor */ - if (lp->last_restart == lp->stats.tx_packets) { - DEB(DEB_ERRORS, printk("Resetting board.\n")); - /* Shutdown and restart */ - i596_reset (dev, lp); - } else { - /* Issue a channel attention signal */ - DEB(DEB_ERRORS, printk("Kicking board.\n")); - lp->scb.command = CUC_START | RX_START; - CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); - CA (dev); - lp->last_restart = lp->stats.tx_packets; - } - - dev->trans_start = jiffies; - netif_wake_queue (dev); -} - - -static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - struct tx_cmd *tx_cmd; - struct i596_tbd *tbd; - short length = skb->len; - dev->trans_start = jiffies; - - DEB(DEB_STARTTX, printk("%s: i596_start_xmit(%x,%p) called\n", dev->name, - skb->len, skb->data)); - - if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) - return 0; - length = ETH_ZLEN; - } - - netif_stop_queue(dev); - - tx_cmd = lp->tx_cmds + lp->next_tx_cmd; - tbd = lp->tbds + lp->next_tx_cmd; - - if (tx_cmd->cmd.command) { - DEB(DEB_ERRORS, printk("%s: xmit ring full, dropping packet.\n", - dev->name)); - lp->stats.tx_dropped++; - - dev_kfree_skb(skb); - } else { - if (++lp->next_tx_cmd == TX_RING_SIZE) - lp->next_tx_cmd = 0; - tx_cmd->tbd = WSWAPtbd(virt_to_dma(lp,tbd)); - tbd->next = I596_NULL; - - tx_cmd->cmd.command = CMD_FLEX | CmdTx; - tx_cmd->skb = skb; - - tx_cmd->pad = 0; - tx_cmd->size = 0; - tbd->pad = 0; - tbd->size = EOF | length; - - tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len, - DMA_TO_DEVICE); - tbd->data = WSWAPchar(tx_cmd->dma_addr); - - DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); - CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd)); - CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd)); - i596_add_cmd(dev, &tx_cmd->cmd); - - lp->stats.tx_packets++; - lp->stats.tx_bytes += length; - } - - netif_start_queue(dev); - - return 0; -} - -static void print_eth(unsigned char *add, char *str) -{ - int i; - - printk("i596 0x%p, ", add); - for (i = 0; i < 6; i++) - printk(" %02X", add[i + 6]); - printk(" -->"); - for (i = 0; i < 6; i++) - printk(" %02X", add[i]); - printk(" %02X%02X, %s\n", add[12], add[13], str); -} - - #define LAN_PROM_ADDR 0xF0810000 -static int __devinit i82596_probe(struct net_device *dev, - struct device *gen_dev) -{ - int i; - struct i596_private *lp; - char eth_addr[6]; - dma_addr_t dma_addr; - - /* This lot is ensure things have been cache line aligned. */ - BUILD_BUG_ON(sizeof(struct i596_rfd) != 32); - BUILD_BUG_ON(sizeof(struct i596_rbd) & 31); - BUILD_BUG_ON(sizeof(struct tx_cmd) & 31); - BUILD_BUG_ON(sizeof(struct i596_tbd) != 32); -#ifndef __LP64__ - BUILD_BUG_ON(sizeof(struct i596_private) > 4096); -#endif - - if (!dev->base_addr || !dev->irq) - return -ENODEV; - - if (pdc_lan_station_id(eth_addr, dev->base_addr)) { - for (i=0; i < 6; i++) { - eth_addr[i] = gsc_readb(LAN_PROM_ADDR + i); - } - printk(KERN_INFO "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__); - } - - dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev, - sizeof(struct i596_private), &dma_addr, GFP_KERNEL); - if (!dev->mem_start) { - printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__); - return -ENOMEM; - } - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = eth_addr[i]; - - /* The 82596-specific entries in the device structure. */ - dev->open = i596_open; - dev->stop = i596_close; - dev->hard_start_xmit = i596_start_xmit; - dev->get_stats = i596_get_stats; - dev->set_multicast_list = set_multicast_list; - dev->tx_timeout = i596_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = i596_poll_controller; -#endif - - dev->priv = (void *)(dev->mem_start); - - lp = dev->priv; - memset(lp, 0, sizeof(struct i596_private)); - - lp->scb.command = 0; - lp->scb.cmd = I596_NULL; - lp->scb.rfd = I596_NULL; - spin_lock_init(&lp->lock); - lp->dma_addr = dma_addr; - lp->dev = gen_dev; - - CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private)); - - i = register_netdev(dev); - if (i) { - lp = dev->priv; - dma_free_noncoherent(lp->dev, sizeof(struct i596_private), - (void *)dev->mem_start, lp->dma_addr); - return i; - }; - - DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr)); - for (i = 0; i < 6; i++) - DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i])); - DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq)); - DEB(DEB_INIT, printk(KERN_INFO "%s: lp at 0x%p (%d bytes), lp->scb at 0x%p\n", - dev->name, lp, (int)sizeof(struct i596_private), &lp->scb)); - - return 0; -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void i596_poll_controller(struct net_device *dev) -{ - disable_irq(dev->irq); - i596_interrupt(dev->irq, dev); - enable_irq(dev->irq); -} -#endif - -static irqreturn_t i596_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct i596_private *lp; - unsigned short status, ack_cmd = 0; - - if (dev == NULL) { - printk("%s: irq %d for unknown device.\n", __FUNCTION__, irq); - return IRQ_NONE; - } - - lp = dev->priv; - - spin_lock (&lp->lock); - - wait_cmd(dev, lp, 100, "i596 interrupt, timeout"); - status = lp->scb.status; - - DEB(DEB_INTS, printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n", - dev->name, irq, status)); - - ack_cmd = status & 0xf000; - - if (!ack_cmd) { - DEB(DEB_ERRORS, printk("%s: interrupt with no events\n", dev->name)); - spin_unlock (&lp->lock); - return IRQ_NONE; - } - - if ((status & 0x8000) || (status & 0x2000)) { - struct i596_cmd *ptr; - - if ((status & 0x8000)) - DEB(DEB_INTS, printk("%s: i596 interrupt completed command.\n", dev->name)); - if ((status & 0x2000)) - DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700)); - - while (lp->cmd_head != NULL) { - CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd)); - if (!(lp->cmd_head->status & STAT_C)) - break; - - ptr = lp->cmd_head; - - DEB(DEB_STATUS, printk("cmd_head->status = %04x, ->command = %04x\n", - lp->cmd_head->status, lp->cmd_head->command)); - lp->cmd_head = ptr->v_next; - lp->cmd_backlog--; - - switch ((ptr->command) & 0x7) { - case CmdTx: - { - struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; - struct sk_buff *skb = tx_cmd->skb; - - if ((ptr->status) & STAT_OK) { - DEB(DEB_TXADDR, print_eth(skb->data, "tx-done")); - } else { - lp->stats.tx_errors++; - if ((ptr->status) & 0x0020) - lp->stats.collisions++; - if (!((ptr->status) & 0x0040)) - lp->stats.tx_heartbeat_errors++; - if ((ptr->status) & 0x0400) - lp->stats.tx_carrier_errors++; - if ((ptr->status) & 0x0800) - lp->stats.collisions++; - if ((ptr->status) & 0x1000) - lp->stats.tx_aborted_errors++; - } - dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); - dev_kfree_skb_irq(skb); - - tx_cmd->cmd.command = 0; /* Mark free */ - break; - } - case CmdTDR: - { - unsigned short status = ((struct tdr_cmd *)ptr)->status; - - if (status & 0x8000) { - DEB(DEB_ANY, printk("%s: link ok.\n", dev->name)); - } else { - if (status & 0x4000) - printk("%s: Transceiver problem.\n", dev->name); - if (status & 0x2000) - printk("%s: Termination problem.\n", dev->name); - if (status & 0x1000) - printk("%s: Short circuit.\n", dev->name); - - DEB(DEB_TDR, printk("%s: Time %d.\n", dev->name, status & 0x07ff)); - } - break; - } - case CmdConfigure: - /* Zap command so set_multicast_list() knows it is free */ - ptr->command = 0; - break; - } - ptr->v_next = NULL; - ptr->b_next = I596_NULL; - CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd)); - lp->last_cmd = jiffies; - } - - /* This mess is arranging that only the last of any outstanding - * commands has the interrupt bit set. Should probably really - * only add to the cmd queue when the CU is stopped. - */ - ptr = lp->cmd_head; - while ((ptr != NULL) && (ptr != lp->cmd_tail)) { - struct i596_cmd *prev = ptr; - - ptr->command &= 0x1fff; - ptr = ptr->v_next; - CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd)); - } - - if ((lp->cmd_head != NULL)) - ack_cmd |= CUC_START; - lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status)); - CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb)); - } - if ((status & 0x1000) || (status & 0x4000)) { - if ((status & 0x4000)) - DEB(DEB_INTS, printk("%s: i596 interrupt received a frame.\n", dev->name)); - i596_rx(dev); - /* Only RX_START if stopped - RGH 07-07-96 */ - if (status & 0x1000) { - if (netif_running(dev)) { - DEB(DEB_ERRORS, printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status)); - ack_cmd |= RX_START; - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; - rebuild_rx_bufs(dev); - } - } - } - wait_cmd(dev, lp, 100, "i596 interrupt, timeout"); - lp->scb.command = ack_cmd; - CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); - - /* DANGER: I suspect that some kind of interrupt - acknowledgement aside from acking the 82596 might be needed - here... but it's running acceptably without */ - - CA(dev); - - wait_cmd(dev, lp, 100, "i596 interrupt, exit timeout"); - DEB(DEB_INTS, printk("%s: exiting interrupt.\n", dev->name)); - - spin_unlock (&lp->lock); - return IRQ_HANDLED; -} - -static int i596_close(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - unsigned long flags; - - netif_stop_queue(dev); - - DEB(DEB_INIT, printk("%s: Shutting down ethercard, status was %4.4x.\n", - dev->name, lp->scb.status)); - - spin_lock_irqsave(&lp->lock, flags); - - wait_cmd(dev, lp, 100, "close1 timed out"); - lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); - - CA(dev); - - wait_cmd(dev, lp, 100, "close2 timed out"); - spin_unlock_irqrestore(&lp->lock, flags); - DEB(DEB_STRUCT,i596_display_data(dev)); - i596_cleanup_cmd(dev,lp); - - disable_irq(dev->irq); - - free_irq(dev->irq, dev); - remove_rx_bufs(dev); - - return 0; -} - -static struct net_device_stats * - i596_get_stats(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - - return &lp->stats; -} - -/* - * Set or clear the multicast filter for this adaptor. - */ - -static void set_multicast_list(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - int config = 0, cnt; - - DEB(DEB_MULTI, printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", - dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", - dev->flags & IFF_ALLMULTI ? "ON" : "OFF")); - - if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) { - lp->cf_cmd.i596_config[8] |= 0x01; - config = 1; - } - if (!(dev->flags & IFF_PROMISC) && (lp->cf_cmd.i596_config[8] & 0x01)) { - lp->cf_cmd.i596_config[8] &= ~0x01; - config = 1; - } - if ((dev->flags & IFF_ALLMULTI) && (lp->cf_cmd.i596_config[11] & 0x20)) { - lp->cf_cmd.i596_config[11] &= ~0x20; - config = 1; - } - if (!(dev->flags & IFF_ALLMULTI) && !(lp->cf_cmd.i596_config[11] & 0x20)) { - lp->cf_cmd.i596_config[11] |= 0x20; - config = 1; - } - if (config) { - if (lp->cf_cmd.cmd.command) - printk("%s: config change request already queued\n", - dev->name); - else { - lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd)); - i596_add_cmd(dev, &lp->cf_cmd.cmd); - } - } - - cnt = dev->mc_count; - if (cnt > MAX_MC_CNT) - { - cnt = MAX_MC_CNT; - printk("%s: Only %d multicast addresses supported", - dev->name, cnt); - } - - if (dev->mc_count > 0) { - struct dev_mc_list *dmi; - unsigned char *cp; - struct mc_cmd *cmd; - - cmd = &lp->mc_cmd; - cmd->cmd.command = CmdMulticastList; - cmd->mc_cnt = dev->mc_count * 6; - cp = cmd->mc_addrs; - for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) { - memcpy(cp, dmi->dmi_addr, 6); - if (i596_debug > 1) - DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5])); - } - CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd)); - i596_add_cmd(dev, &cmd->cmd); - } -} - -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "lasi_82596 debug mask"); - -static int num_drivers; -static struct net_device *netdevs[MAX_DRIVERS]; - static int __devinit lan_init_chip(struct parisc_device *dev) { struct net_device *netdevice; + struct i596_private *lp; int retval; - - if (num_drivers >= MAX_DRIVERS) { - /* max count of possible i82596 drivers reached */ - return -ENOMEM; - } - - if (num_drivers == 0) - printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n"); + int i; if (!dev->irq) { printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", @@ -1528,28 +168,45 @@ lan_init_chip(struct parisc_device *dev) printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start, dev->irq); - netdevice = alloc_etherdev(0); + netdevice = alloc_etherdev(sizeof(struct i596_private)); if (!netdevice) return -ENOMEM; + SET_NETDEV_DEV(netdevice, &dev->dev); + parisc_set_drvdata (dev, netdevice); netdevice->base_addr = dev->hpa.start; netdevice->irq = dev->irq; - retval = i82596_probe(netdevice, &dev->dev); + if (pdc_lan_station_id(netdevice->dev_addr, netdevice->base_addr)) { + for (i = 0; i < 6; i++) { + netdevice->dev_addr[i] = gsc_readb(LAN_PROM_ADDR + i); + } + printk(KERN_INFO + "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__); + } + + lp = netdev_priv(netdevice); + lp->options = dev->id.sversion == 0x72 ? OPT_SWAP_PORT : 0; + + retval = i82596_probe(netdevice); if (retval) { free_netdev(netdevice); return -ENODEV; } - - if (dev->id.sversion == 0x72) { - ((struct i596_private *)netdevice->priv)->options = OPT_SWAP_PORT; - } - - netdevs[num_drivers++] = netdevice; - return retval; } +static int __devexit lan_remove_chip (struct parisc_device *pdev) +{ + struct net_device *dev = parisc_get_drvdata(pdev); + struct i596_private *lp = netdev_priv(dev); + + unregister_netdev (dev); + DMA_FREE(&pdev->dev, sizeof(struct i596_private), + (void *)lp->dma, lp->dma_addr); + free_netdev (dev); + return 0; +} static struct parisc_device_id lan_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a }, @@ -1563,12 +220,12 @@ static struct parisc_driver lan_driver = { .name = "lasi_82596", .id_table = lan_tbl, .probe = lan_init_chip, + .remove = __devexit_p(lan_remove_chip), }; static int __devinit lasi_82596_init(void) { - if (debug >= 0) - i596_debug = debug; + printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n"); return register_parisc_driver(&lan_driver); } @@ -1576,25 +233,6 @@ module_init(lasi_82596_init); static void __exit lasi_82596_exit(void) { - int i; - - for (i=0; ipriv; - dma_free_noncoherent(lp->dev, sizeof(struct i596_private), - (void *)netdevice->mem_start, lp->dma_addr); - free_netdev(netdevice); - } - num_drivers = 0; - unregister_parisc_driver(&lan_driver); } diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c new file mode 100644 index 000000000000..5884f5bd04a4 --- /dev/null +++ b/drivers/net/lib82596.c @@ -0,0 +1,1434 @@ +/* lasi_82596.c -- driver for the intel 82596 ethernet controller, as + munged into HPPA boxen . + + This driver is based upon 82596.c, original credits are below... + but there were too many hoops which HP wants jumped through to + keep this code in there in a sane manner. + + 3 primary sources of the mess -- + 1) hppa needs *lots* of cacheline flushing to keep this kind of + MMIO running. + + 2) The 82596 needs to see all of its pointers as their physical + address. Thus virt_to_bus/bus_to_virt are *everywhere*. + + 3) The implementation HP is using seems to be significantly pickier + about when and how the command and RX units are started. some + command ordering was changed. + + Examination of the mach driver leads one to believe that there + might be a saner way to pull this off... anyone who feels like a + full rewrite can be my guest. + + Split 02/13/2000 Sam Creasey (sammy@oh.verio.com) + + 02/01/2000 Initial modifications for parisc by Helge Deller (deller@gmx.de) + 03/02/2000 changes for better/correct(?) cache-flushing (deller) +*/ + +/* 82596.c: A generic 82596 ethernet driver for linux. */ +/* + Based on Apricot.c + Written 1994 by Mark Evans. + This driver is for the Apricot 82596 bus-master interface + + Modularised 12/94 Mark Evans + + + Modified to support the 82596 ethernet chips on 680x0 VME boards. + by Richard Hirst + Renamed to be 82596.c + + 980825: Changed to receive directly in to sk_buffs which are + allocated at open() time. Eliminates copy on incoming frames + (small ones are still copied). Shared data now held in a + non-cached page, so we can run on 68060 in copyback mode. + + TBD: + * look at deferring rx frames rather than discarding (as per tulip) + * handle tx ring full as per tulip + * performace test to tune rx_copybreak + + Most of my modifications relate to the braindead big-endian + implementation by Intel. When the i596 is operating in + 'big-endian' mode, it thinks a 32 bit value of 0x12345678 + should be stored as 0x56781234. This is a real pain, when + you have linked lists which are shared by the 680x0 and the + i596. + + Driver skeleton + Written 1993 by Donald Becker. + Copyright 1993 United States Government as represented by the Director, + National Security Agency. This software may only be used and distributed + according to the terms of the GNU General Public License as modified by SRC, + incorporated herein by reference. + + The author may be reached as becker@scyld.com, or C/O + Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403 + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* DEBUG flags + */ + +#define DEB_INIT 0x0001 +#define DEB_PROBE 0x0002 +#define DEB_SERIOUS 0x0004 +#define DEB_ERRORS 0x0008 +#define DEB_MULTI 0x0010 +#define DEB_TDR 0x0020 +#define DEB_OPEN 0x0040 +#define DEB_RESET 0x0080 +#define DEB_ADDCMD 0x0100 +#define DEB_STATUS 0x0200 +#define DEB_STARTTX 0x0400 +#define DEB_RXADDR 0x0800 +#define DEB_TXADDR 0x1000 +#define DEB_RXFRAME 0x2000 +#define DEB_INTS 0x4000 +#define DEB_STRUCT 0x8000 +#define DEB_ANY 0xffff + + +#define DEB(x, y) if (i596_debug & (x)) { y; } + + +/* + * The MPU_PORT command allows direct access to the 82596. With PORT access + * the following commands are available (p5-18). The 32-bit port command + * must be word-swapped with the most significant word written first. + * This only applies to VME boards. + */ +#define PORT_RESET 0x00 /* reset 82596 */ +#define PORT_SELFTEST 0x01 /* selftest */ +#define PORT_ALTSCP 0x02 /* alternate SCB address */ +#define PORT_ALTDUMP 0x03 /* Alternate DUMP address */ + +static int i596_debug = (DEB_SERIOUS|DEB_PROBE); + +/* Copy frames shorter than rx_copybreak, otherwise pass on up in + * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha). + */ +static int rx_copybreak = 100; + +#define PKT_BUF_SZ 1536 +#define MAX_MC_CNT 64 + +#define ISCP_BUSY 0x0001 + +#define I596_NULL ((u32)0xffffffff) + +#define CMD_EOL 0x8000 /* The last command of the list, stop. */ +#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ +#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ + +#define CMD_FLEX 0x0008 /* Enable flexible memory model */ + +enum commands { + CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, + CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7 +}; + +#define STAT_C 0x8000 /* Set to 0 after execution */ +#define STAT_B 0x4000 /* Command being executed */ +#define STAT_OK 0x2000 /* Command executed ok */ +#define STAT_A 0x1000 /* Command aborted */ + +#define CUC_START 0x0100 +#define CUC_RESUME 0x0200 +#define CUC_SUSPEND 0x0300 +#define CUC_ABORT 0x0400 +#define RX_START 0x0010 +#define RX_RESUME 0x0020 +#define RX_SUSPEND 0x0030 +#define RX_ABORT 0x0040 + +#define TX_TIMEOUT 5 + + +struct i596_reg { + unsigned short porthi; + unsigned short portlo; + u32 ca; +}; + +#define EOF 0x8000 +#define SIZE_MASK 0x3fff + +struct i596_tbd { + unsigned short size; + unsigned short pad; + dma_addr_t next; + dma_addr_t data; + u32 cache_pad[5]; /* Total 32 bytes... */ +}; + +/* The command structure has two 'next' pointers; v_next is the address of + * the next command as seen by the CPU, b_next is the address of the next + * command as seen by the 82596. The b_next pointer, as used by the 82596 + * always references the status field of the next command, rather than the + * v_next field, because the 82596 is unaware of v_next. It may seem more + * logical to put v_next at the end of the structure, but we cannot do that + * because the 82596 expects other fields to be there, depending on command + * type. + */ + +struct i596_cmd { + struct i596_cmd *v_next; /* Address from CPUs viewpoint */ + unsigned short status; + unsigned short command; + dma_addr_t b_next; /* Address from i596 viewpoint */ +}; + +struct tx_cmd { + struct i596_cmd cmd; + dma_addr_t tbd; + unsigned short size; + unsigned short pad; + struct sk_buff *skb; /* So we can free it after tx */ + dma_addr_t dma_addr; +#ifdef __LP64__ + u32 cache_pad[6]; /* Total 64 bytes... */ +#else + u32 cache_pad[1]; /* Total 32 bytes... */ +#endif +}; + +struct tdr_cmd { + struct i596_cmd cmd; + unsigned short status; + unsigned short pad; +}; + +struct mc_cmd { + struct i596_cmd cmd; + short mc_cnt; + char mc_addrs[MAX_MC_CNT*6]; +}; + +struct sa_cmd { + struct i596_cmd cmd; + char eth_addr[8]; +}; + +struct cf_cmd { + struct i596_cmd cmd; + char i596_config[16]; +}; + +struct i596_rfd { + unsigned short stat; + unsigned short cmd; + dma_addr_t b_next; /* Address from i596 viewpoint */ + dma_addr_t rbd; + unsigned short count; + unsigned short size; + struct i596_rfd *v_next; /* Address from CPUs viewpoint */ + struct i596_rfd *v_prev; +#ifndef __LP64__ + u32 cache_pad[2]; /* Total 32 bytes... */ +#endif +}; + +struct i596_rbd { + /* hardware data */ + unsigned short count; + unsigned short zero1; + dma_addr_t b_next; + dma_addr_t b_data; /* Address from i596 viewpoint */ + unsigned short size; + unsigned short zero2; + /* driver data */ + struct sk_buff *skb; + struct i596_rbd *v_next; + dma_addr_t b_addr; /* This rbd addr from i596 view */ + unsigned char *v_data; /* Address from CPUs viewpoint */ + /* Total 32 bytes... */ +#ifdef __LP64__ + u32 cache_pad[4]; +#endif +}; + +/* These values as chosen so struct i596_dma fits in one page... */ + +#define TX_RING_SIZE 32 +#define RX_RING_SIZE 16 + +struct i596_scb { + unsigned short status; + unsigned short command; + dma_addr_t cmd; + dma_addr_t rfd; + u32 crc_err; + u32 align_err; + u32 resource_err; + u32 over_err; + u32 rcvdt_err; + u32 short_err; + unsigned short t_on; + unsigned short t_off; +}; + +struct i596_iscp { + u32 stat; + dma_addr_t scb; +}; + +struct i596_scp { + u32 sysbus; + u32 pad; + dma_addr_t iscp; +}; + +struct i596_dma { + struct i596_scp scp __attribute__((aligned(32))); + volatile struct i596_iscp iscp __attribute__((aligned(32))); + volatile struct i596_scb scb __attribute__((aligned(32))); + struct sa_cmd sa_cmd __attribute__((aligned(32))); + struct cf_cmd cf_cmd __attribute__((aligned(32))); + struct tdr_cmd tdr_cmd __attribute__((aligned(32))); + struct mc_cmd mc_cmd __attribute__((aligned(32))); + struct i596_rfd rfds[RX_RING_SIZE] __attribute__((aligned(32))); + struct i596_rbd rbds[RX_RING_SIZE] __attribute__((aligned(32))); + struct tx_cmd tx_cmds[TX_RING_SIZE] __attribute__((aligned(32))); + struct i596_tbd tbds[TX_RING_SIZE] __attribute__((aligned(32))); +}; + +struct i596_private { + struct i596_dma *dma; + u32 stat; + int last_restart; + struct i596_rfd *rfd_head; + struct i596_rbd *rbd_head; + struct i596_cmd *cmd_tail; + struct i596_cmd *cmd_head; + int cmd_backlog; + u32 last_cmd; + struct net_device_stats stats; + int next_tx_cmd; + int options; + spinlock_t lock; /* serialize access to chip */ + dma_addr_t dma_addr; + void __iomem *mpu_port; + void __iomem *ca; +}; + +static const char init_setup[] = +{ + 0x8E, /* length, prefetch on */ + 0xC8, /* fifo to 8, monitor off */ + 0x80, /* don't save bad frames */ + 0x2E, /* No source address insertion, 8 byte preamble */ + 0x00, /* priority and backoff defaults */ + 0x60, /* interframe spacing */ + 0x00, /* slot time LSB */ + 0xf2, /* slot time and retries */ + 0x00, /* promiscuous mode */ + 0x00, /* collision detect */ + 0x40, /* minimum frame length */ + 0xff, + 0x00, + 0x7f /* *multi IA */ }; + +static int i596_open(struct net_device *dev); +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); +static irqreturn_t i596_interrupt(int irq, void *dev_id); +static int i596_close(struct net_device *dev); +static struct net_device_stats *i596_get_stats(struct net_device *dev); +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); +static void i596_tx_timeout (struct net_device *dev); +static void print_eth(unsigned char *buf, char *str); +static void set_multicast_list(struct net_device *dev); +static inline void ca(struct net_device *dev); +static void mpu_port(struct net_device *dev, int c, dma_addr_t x); + +static int rx_ring_size = RX_RING_SIZE; +static int ticks_limit = 100; +static int max_cmd_backlog = TX_RING_SIZE-1; + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void i596_poll_controller(struct net_device *dev); +#endif + + +static inline int wait_istat(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str) +{ + DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp)); + while (--delcnt && dma->iscp.stat) { + udelay(10); + DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp)); + } + if (!delcnt) { + printk(KERN_ERR "%s: %s, iscp.stat %04x, didn't clear\n", + dev->name, str, SWAP16(dma->iscp.stat)); + return -1; + } else + return 0; +} + + +static inline int wait_cmd(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str) +{ + DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb)); + while (--delcnt && dma->scb.command) { + udelay(10); + DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb)); + } + if (!delcnt) { + printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n", + dev->name, str, + SWAP16(dma->scb.status), + SWAP16(dma->scb.command)); + return -1; + } else + return 0; +} + + +static void i596_display_data(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + struct i596_cmd *cmd; + struct i596_rfd *rfd; + struct i596_rbd *rbd; + + printk(KERN_DEBUG "lp and scp at %p, .sysbus = %08x, .iscp = %08x\n", + &dma->scp, dma->scp.sysbus, SWAP32(dma->scp.iscp)); + printk(KERN_DEBUG "iscp at %p, iscp.stat = %08x, .scb = %08x\n", + &dma->iscp, SWAP32(dma->iscp.stat), SWAP32(dma->iscp.scb)); + printk(KERN_DEBUG "scb at %p, scb.status = %04x, .command = %04x," + " .cmd = %08x, .rfd = %08x\n", + &dma->scb, SWAP16(dma->scb.status), SWAP16(dma->scb.command), + SWAP16(dma->scb.cmd), SWAP32(dma->scb.rfd)); + printk(KERN_DEBUG " errors: crc %x, align %x, resource %x," + " over %x, rcvdt %x, short %x\n", + SWAP32(dma->scb.crc_err), SWAP32(dma->scb.align_err), + SWAP32(dma->scb.resource_err), SWAP32(dma->scb.over_err), + SWAP32(dma->scb.rcvdt_err), SWAP32(dma->scb.short_err)); + cmd = lp->cmd_head; + while (cmd != NULL) { + printk(KERN_DEBUG + "cmd at %p, .status = %04x, .command = %04x," + " .b_next = %08x\n", + cmd, SWAP16(cmd->status), SWAP16(cmd->command), + SWAP32(cmd->b_next)); + cmd = cmd->v_next; + } + rfd = lp->rfd_head; + printk(KERN_DEBUG "rfd_head = %p\n", rfd); + do { + printk(KERN_DEBUG + " %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x," + " count %04x\n", + rfd, SWAP16(rfd->stat), SWAP16(rfd->cmd), + SWAP32(rfd->b_next), SWAP32(rfd->rbd), + SWAP16(rfd->count)); + rfd = rfd->v_next; + } while (rfd != lp->rfd_head); + rbd = lp->rbd_head; + printk(KERN_DEBUG "rbd_head = %p\n", rbd); + do { + printk(KERN_DEBUG + " %p .count %04x, b_next %08x, b_data %08x," + " size %04x\n", + rbd, SWAP16(rbd->count), SWAP32(rbd->b_next), + SWAP32(rbd->b_data), SWAP16(rbd->size)); + rbd = rbd->v_next; + } while (rbd != lp->rbd_head); + DMA_INV(dev, dma, sizeof(struct i596_dma)); +} + + +#define virt_to_dma(lp, v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)((lp)->dma))) + +static inline int init_rx_bufs(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + int i; + struct i596_rfd *rfd; + struct i596_rbd *rbd; + + /* First build the Receive Buffer Descriptor List */ + + for (i = 0, rbd = dma->rbds; i < rx_ring_size; i++, rbd++) { + dma_addr_t dma_addr; + struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4); + + if (skb == NULL) + return -1; + skb_reserve(skb, 2); + dma_addr = dma_map_single(dev->dev.parent, skb->data, + PKT_BUF_SZ, DMA_FROM_DEVICE); + rbd->v_next = rbd+1; + rbd->b_next = SWAP32(virt_to_dma(lp, rbd+1)); + rbd->b_addr = SWAP32(virt_to_dma(lp, rbd)); + rbd->skb = skb; + rbd->v_data = skb->data; + rbd->b_data = SWAP32(dma_addr); + rbd->size = SWAP16(PKT_BUF_SZ); + } + lp->rbd_head = dma->rbds; + rbd = dma->rbds + rx_ring_size - 1; + rbd->v_next = dma->rbds; + rbd->b_next = SWAP32(virt_to_dma(lp, dma->rbds)); + + /* Now build the Receive Frame Descriptor List */ + + for (i = 0, rfd = dma->rfds; i < rx_ring_size; i++, rfd++) { + rfd->rbd = I596_NULL; + rfd->v_next = rfd+1; + rfd->v_prev = rfd-1; + rfd->b_next = SWAP32(virt_to_dma(lp, rfd+1)); + rfd->cmd = SWAP16(CMD_FLEX); + } + lp->rfd_head = dma->rfds; + dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds)); + rfd = dma->rfds; + rfd->rbd = SWAP32(virt_to_dma(lp, lp->rbd_head)); + rfd->v_prev = dma->rfds + rx_ring_size - 1; + rfd = dma->rfds + rx_ring_size - 1; + rfd->v_next = dma->rfds; + rfd->b_next = SWAP32(virt_to_dma(lp, dma->rfds)); + rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX); + + DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma)); + return 0; +} + +static inline void remove_rx_bufs(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_rbd *rbd; + int i; + + for (i = 0, rbd = lp->dma->rbds; i < rx_ring_size; i++, rbd++) { + if (rbd->skb == NULL) + break; + dma_unmap_single(dev->dev.parent, + (dma_addr_t)SWAP32(rbd->b_data), + PKT_BUF_SZ, DMA_FROM_DEVICE); + dev_kfree_skb(rbd->skb); + } +} + + +static void rebuild_rx_bufs(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + int i; + + /* Ensure rx frame/buffer descriptors are tidy */ + + for (i = 0; i < rx_ring_size; i++) { + dma->rfds[i].rbd = I596_NULL; + dma->rfds[i].cmd = SWAP16(CMD_FLEX); + } + dma->rfds[rx_ring_size-1].cmd = SWAP16(CMD_EOL|CMD_FLEX); + lp->rfd_head = dma->rfds; + dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds)); + lp->rbd_head = dma->rbds; + dma->rfds[0].rbd = SWAP32(virt_to_dma(lp, dma->rbds)); + + DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma)); +} + + +static int init_i596_mem(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + unsigned long flags; + + mpu_port(dev, PORT_RESET, 0); + udelay(100); /* Wait 100us - seems to help */ + + /* change the scp address */ + + lp->last_cmd = jiffies; + + dma->scp.sysbus = SYSBUS; + dma->scp.iscp = SWAP32(virt_to_dma(lp, &(dma->iscp))); + dma->iscp.scb = SWAP32(virt_to_dma(lp, &(dma->scb))); + dma->iscp.stat = SWAP32(ISCP_BUSY); + lp->cmd_backlog = 0; + + lp->cmd_head = NULL; + dma->scb.cmd = I596_NULL; + + DEB(DEB_INIT, printk(KERN_DEBUG "%s: starting i82596.\n", dev->name)); + + DMA_WBACK(dev, &(dma->scp), sizeof(struct i596_scp)); + DMA_WBACK(dev, &(dma->iscp), sizeof(struct i596_iscp)); + DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb)); + + mpu_port(dev, PORT_ALTSCP, virt_to_dma(lp, &dma->scp)); + ca(dev); + if (wait_istat(dev, dma, 1000, "initialization timed out")) + goto failed; + DEB(DEB_INIT, printk(KERN_DEBUG + "%s: i82596 initialization successful\n", + dev->name)); + + if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) { + printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq); + goto failed; + } + + /* Ensure rx frame/buffer descriptors are tidy */ + rebuild_rx_bufs(dev); + + dma->scb.command = 0; + DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb)); + + DEB(DEB_INIT, printk(KERN_DEBUG + "%s: queuing CmdConfigure\n", dev->name)); + memcpy(dma->cf_cmd.i596_config, init_setup, 14); + dma->cf_cmd.cmd.command = SWAP16(CmdConfigure); + DMA_WBACK(dev, &(dma->cf_cmd), sizeof(struct cf_cmd)); + i596_add_cmd(dev, &dma->cf_cmd.cmd); + + DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name)); + memcpy(dma->sa_cmd.eth_addr, dev->dev_addr, 6); + dma->sa_cmd.cmd.command = SWAP16(CmdSASetup); + DMA_WBACK(dev, &(dma->sa_cmd), sizeof(struct sa_cmd)); + i596_add_cmd(dev, &dma->sa_cmd.cmd); + + DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name)); + dma->tdr_cmd.cmd.command = SWAP16(CmdTDR); + DMA_WBACK(dev, &(dma->tdr_cmd), sizeof(struct tdr_cmd)); + i596_add_cmd(dev, &dma->tdr_cmd.cmd); + + spin_lock_irqsave (&lp->lock, flags); + + if (wait_cmd(dev, dma, 1000, "timed out waiting to issue RX_START")) { + spin_unlock_irqrestore (&lp->lock, flags); + goto failed_free_irq; + } + DEB(DEB_INIT, printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name)); + dma->scb.command = SWAP16(RX_START); + dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds)); + DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb)); + + ca(dev); + + spin_unlock_irqrestore (&lp->lock, flags); + if (wait_cmd(dev, dma, 1000, "RX_START not processed")) + goto failed_free_irq; + DEB(DEB_INIT, printk(KERN_DEBUG + "%s: Receive unit started OK\n", dev->name)); + return 0; + +failed_free_irq: + free_irq(dev->irq, dev); +failed: + printk(KERN_ERR "%s: Failed to initialise 82596\n", dev->name); + mpu_port(dev, PORT_RESET, 0); + return -1; +} + + +static inline int i596_rx(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_rfd *rfd; + struct i596_rbd *rbd; + int frames = 0; + + DEB(DEB_RXFRAME, printk(KERN_DEBUG + "i596_rx(), rfd_head %p, rbd_head %p\n", + lp->rfd_head, lp->rbd_head)); + + + rfd = lp->rfd_head; /* Ref next frame to check */ + + DMA_INV(dev, rfd, sizeof(struct i596_rfd)); + while (rfd->stat & SWAP16(STAT_C)) { /* Loop while complete frames */ + if (rfd->rbd == I596_NULL) + rbd = NULL; + else if (rfd->rbd == lp->rbd_head->b_addr) { + rbd = lp->rbd_head; + DMA_INV(dev, rbd, sizeof(struct i596_rbd)); + } else { + printk(KERN_ERR "%s: rbd chain broken!\n", dev->name); + /* XXX Now what? */ + rbd = NULL; + } + DEB(DEB_RXFRAME, printk(KERN_DEBUG + " rfd %p, rfd.rbd %08x, rfd.stat %04x\n", + rfd, rfd->rbd, rfd->stat)); + + if (rbd != NULL && (rfd->stat & SWAP16(STAT_OK))) { + /* a good frame */ + int pkt_len = SWAP16(rbd->count) & 0x3fff; + struct sk_buff *skb = rbd->skb; + int rx_in_place = 0; + + DEB(DEB_RXADDR, print_eth(rbd->v_data, "received")); + frames++; + + /* Check if the packet is long enough to just accept + * without copying to a properly sized skbuff. + */ + + if (pkt_len > rx_copybreak) { + struct sk_buff *newskb; + dma_addr_t dma_addr; + + dma_unmap_single(dev->dev.parent, + (dma_addr_t)SWAP32(rbd->b_data), + PKT_BUF_SZ, DMA_FROM_DEVICE); + /* Get fresh skbuff to replace filled one. */ + newskb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4); + if (newskb == NULL) { + skb = NULL; /* drop pkt */ + goto memory_squeeze; + } + skb_reserve(newskb, 2); + + /* Pass up the skb already on the Rx ring. */ + skb_put(skb, pkt_len); + rx_in_place = 1; + rbd->skb = newskb; + dma_addr = dma_map_single(dev->dev.parent, + newskb->data, + PKT_BUF_SZ, + DMA_FROM_DEVICE); + rbd->v_data = newskb->data; + rbd->b_data = SWAP32(dma_addr); + DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd)); + } else + skb = netdev_alloc_skb(dev, pkt_len + 2); +memory_squeeze: + if (skb == NULL) { + /* XXX tulip.c can defer packets here!! */ + printk(KERN_ERR + "%s: i596_rx Memory squeeze, dropping packet.\n", + dev->name); + lp->stats.rx_dropped++; + } else { + if (!rx_in_place) { + /* 16 byte align the data fields */ + dma_sync_single_for_cpu(dev->dev.parent, + (dma_addr_t)SWAP32(rbd->b_data), + PKT_BUF_SZ, DMA_FROM_DEVICE); + skb_reserve(skb, 2); + memcpy(skb_put(skb, pkt_len), rbd->v_data, pkt_len); + dma_sync_single_for_device(dev->dev.parent, + (dma_addr_t)SWAP32(rbd->b_data), + PKT_BUF_SZ, DMA_FROM_DEVICE); + } + skb->len = pkt_len; + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; + } + } else { + DEB(DEB_ERRORS, printk(KERN_DEBUG + "%s: Error, rfd.stat = 0x%04x\n", + dev->name, rfd->stat)); + lp->stats.rx_errors++; + if (rfd->stat & SWAP16(0x0100)) + lp->stats.collisions++; + if (rfd->stat & SWAP16(0x8000)) + lp->stats.rx_length_errors++; + if (rfd->stat & SWAP16(0x0001)) + lp->stats.rx_over_errors++; + if (rfd->stat & SWAP16(0x0002)) + lp->stats.rx_fifo_errors++; + if (rfd->stat & SWAP16(0x0004)) + lp->stats.rx_frame_errors++; + if (rfd->stat & SWAP16(0x0008)) + lp->stats.rx_crc_errors++; + if (rfd->stat & SWAP16(0x0010)) + lp->stats.rx_length_errors++; + } + + /* Clear the buffer descriptor count and EOF + F flags */ + + if (rbd != NULL && (rbd->count & SWAP16(0x4000))) { + rbd->count = 0; + lp->rbd_head = rbd->v_next; + DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd)); + } + + /* Tidy the frame descriptor, marking it as end of list */ + + rfd->rbd = I596_NULL; + rfd->stat = 0; + rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX); + rfd->count = 0; + + /* Update record of next frame descriptor to process */ + + lp->dma->scb.rfd = rfd->b_next; + lp->rfd_head = rfd->v_next; + DMA_WBACK_INV(dev, rfd, sizeof(struct i596_rfd)); + + /* Remove end-of-list from old end descriptor */ + + rfd->v_prev->cmd = SWAP16(CMD_FLEX); + DMA_WBACK_INV(dev, rfd->v_prev, sizeof(struct i596_rfd)); + rfd = lp->rfd_head; + DMA_INV(dev, rfd, sizeof(struct i596_rfd)); + } + + DEB(DEB_RXFRAME, printk(KERN_DEBUG "frames %d\n", frames)); + + return 0; +} + + +static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) +{ + struct i596_cmd *ptr; + + while (lp->cmd_head != NULL) { + ptr = lp->cmd_head; + lp->cmd_head = ptr->v_next; + lp->cmd_backlog--; + + switch (SWAP16(ptr->command) & 0x7) { + case CmdTx: + { + struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; + struct sk_buff *skb = tx_cmd->skb; + dma_unmap_single(dev->dev.parent, + tx_cmd->dma_addr, + skb->len, DMA_TO_DEVICE); + + dev_kfree_skb(skb); + + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + + ptr->v_next = NULL; + ptr->b_next = I596_NULL; + tx_cmd->cmd.command = 0; /* Mark as free */ + break; + } + default: + ptr->v_next = NULL; + ptr->b_next = I596_NULL; + } + DMA_WBACK_INV(dev, ptr, sizeof(struct i596_cmd)); + } + + wait_cmd(dev, lp->dma, 100, "i596_cleanup_cmd timed out"); + lp->dma->scb.cmd = I596_NULL; + DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb)); +} + + +static inline void i596_reset(struct net_device *dev, struct i596_private *lp) +{ + unsigned long flags; + + DEB(DEB_RESET, printk(KERN_DEBUG "i596_reset\n")); + + spin_lock_irqsave (&lp->lock, flags); + + wait_cmd(dev, lp->dma, 100, "i596_reset timed out"); + + netif_stop_queue(dev); + + /* FIXME: this command might cause an lpmc */ + lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT); + DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb)); + ca(dev); + + /* wait for shutdown */ + wait_cmd(dev, lp->dma, 1000, "i596_reset 2 timed out"); + spin_unlock_irqrestore (&lp->lock, flags); + + i596_cleanup_cmd(dev, lp); + i596_rx(dev); + + netif_start_queue(dev); + init_i596_mem(dev); +} + + +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + unsigned long flags; + + DEB(DEB_ADDCMD, printk(KERN_DEBUG "i596_add_cmd cmd_head %p\n", + lp->cmd_head)); + + cmd->status = 0; + cmd->command |= SWAP16(CMD_EOL | CMD_INTR); + cmd->v_next = NULL; + cmd->b_next = I596_NULL; + DMA_WBACK(dev, cmd, sizeof(struct i596_cmd)); + + spin_lock_irqsave (&lp->lock, flags); + + if (lp->cmd_head != NULL) { + lp->cmd_tail->v_next = cmd; + lp->cmd_tail->b_next = SWAP32(virt_to_dma(lp, &cmd->status)); + DMA_WBACK(dev, lp->cmd_tail, sizeof(struct i596_cmd)); + } else { + lp->cmd_head = cmd; + wait_cmd(dev, dma, 100, "i596_add_cmd timed out"); + dma->scb.cmd = SWAP32(virt_to_dma(lp, &cmd->status)); + dma->scb.command = SWAP16(CUC_START); + DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb)); + ca(dev); + } + lp->cmd_tail = cmd; + lp->cmd_backlog++; + + spin_unlock_irqrestore (&lp->lock, flags); + + if (lp->cmd_backlog > max_cmd_backlog) { + unsigned long tickssofar = jiffies - lp->last_cmd; + + if (tickssofar < ticks_limit) + return; + + printk(KERN_ERR + "%s: command unit timed out, status resetting.\n", + dev->name); +#if 1 + i596_reset(dev, lp); +#endif + } +} + +static int i596_open(struct net_device *dev) +{ + DEB(DEB_OPEN, printk(KERN_DEBUG + "%s: i596_open() irq %d.\n", dev->name, dev->irq)); + + if (init_rx_bufs(dev)) { + printk(KERN_ERR "%s: Failed to init rx bufs\n", dev->name); + return -EAGAIN; + } + if (init_i596_mem(dev)) { + printk(KERN_ERR "%s: Failed to init memory\n", dev->name); + goto out_remove_rx_bufs; + } + netif_start_queue(dev); + + return 0; + +out_remove_rx_bufs: + remove_rx_bufs(dev); + return -EAGAIN; +} + +static void i596_tx_timeout (struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + + /* Transmitter timeout, serious problems. */ + DEB(DEB_ERRORS, printk(KERN_DEBUG + "%s: transmit timed out, status resetting.\n", + dev->name)); + + lp->stats.tx_errors++; + + /* Try to restart the adaptor */ + if (lp->last_restart == lp->stats.tx_packets) { + DEB(DEB_ERRORS, printk(KERN_DEBUG "Resetting board.\n")); + /* Shutdown and restart */ + i596_reset (dev, lp); + } else { + /* Issue a channel attention signal */ + DEB(DEB_ERRORS, printk(KERN_DEBUG "Kicking board.\n")); + lp->dma->scb.command = SWAP16(CUC_START | RX_START); + DMA_WBACK_INV(dev, &(lp->dma->scb), sizeof(struct i596_scb)); + ca (dev); + lp->last_restart = lp->stats.tx_packets; + } + + dev->trans_start = jiffies; + netif_wake_queue (dev); +} + + +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct tx_cmd *tx_cmd; + struct i596_tbd *tbd; + short length = skb->len; + dev->trans_start = jiffies; + + DEB(DEB_STARTTX, printk(KERN_DEBUG + "%s: i596_start_xmit(%x,%p) called\n", + dev->name, skb->len, skb->data)); + + if (length < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + return 0; + length = ETH_ZLEN; + } + + netif_stop_queue(dev); + + tx_cmd = lp->dma->tx_cmds + lp->next_tx_cmd; + tbd = lp->dma->tbds + lp->next_tx_cmd; + + if (tx_cmd->cmd.command) { + DEB(DEB_ERRORS, printk(KERN_DEBUG + "%s: xmit ring full, dropping packet.\n", + dev->name)); + lp->stats.tx_dropped++; + + dev_kfree_skb(skb); + } else { + if (++lp->next_tx_cmd == TX_RING_SIZE) + lp->next_tx_cmd = 0; + tx_cmd->tbd = SWAP32(virt_to_dma(lp, tbd)); + tbd->next = I596_NULL; + + tx_cmd->cmd.command = SWAP16(CMD_FLEX | CmdTx); + tx_cmd->skb = skb; + + tx_cmd->pad = 0; + tx_cmd->size = 0; + tbd->pad = 0; + tbd->size = SWAP16(EOF | length); + + tx_cmd->dma_addr = dma_map_single(dev->dev.parent, skb->data, + skb->len, DMA_TO_DEVICE); + tbd->data = SWAP32(tx_cmd->dma_addr); + + DEB(DEB_TXADDR, print_eth(skb->data, "tx-queued")); + DMA_WBACK_INV(dev, tx_cmd, sizeof(struct tx_cmd)); + DMA_WBACK_INV(dev, tbd, sizeof(struct i596_tbd)); + i596_add_cmd(dev, &tx_cmd->cmd); + + lp->stats.tx_packets++; + lp->stats.tx_bytes += length; + } + + netif_start_queue(dev); + + return 0; +} + +static void print_eth(unsigned char *add, char *str) +{ + int i; + + printk(KERN_DEBUG "i596 0x%p, ", add); + for (i = 0; i < 6; i++) + printk(" %02X", add[i + 6]); + printk(" -->"); + for (i = 0; i < 6; i++) + printk(" %02X", add[i]); + printk(" %02X%02X, %s\n", add[12], add[13], str); +} + +static int __devinit i82596_probe(struct net_device *dev) +{ + int i; + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma; + + /* This lot is ensure things have been cache line aligned. */ + BUILD_BUG_ON(sizeof(struct i596_rfd) != 32); + BUILD_BUG_ON(sizeof(struct i596_rbd) & 31); + BUILD_BUG_ON(sizeof(struct tx_cmd) & 31); + BUILD_BUG_ON(sizeof(struct i596_tbd) != 32); +#ifndef __LP64__ + BUILD_BUG_ON(sizeof(struct i596_dma) > 4096); +#endif + + if (!dev->base_addr || !dev->irq) + return -ENODEV; + + dma = (struct i596_dma *) DMA_ALLOC(dev->dev.parent, + sizeof(struct i596_dma), &lp->dma_addr, GFP_KERNEL); + if (!dma) { + printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__); + return -ENOMEM; + } + + /* The 82596-specific entries in the device structure. */ + dev->open = i596_open; + dev->stop = i596_close; + dev->hard_start_xmit = i596_start_xmit; + dev->get_stats = i596_get_stats; + dev->set_multicast_list = set_multicast_list; + dev->tx_timeout = i596_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = i596_poll_controller; +#endif + + memset(dma, 0, sizeof(struct i596_dma)); + lp->dma = dma; + + dma->scb.command = 0; + dma->scb.cmd = I596_NULL; + dma->scb.rfd = I596_NULL; + spin_lock_init(&lp->lock); + + DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma)); + + i = register_netdev(dev); + if (i) { + DMA_FREE(dev->dev.parent, sizeof(struct i596_dma), + (void *)dma, lp->dma_addr); + return i; + }; + + DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,", + dev->name, dev->base_addr)); + for (i = 0; i < 6; i++) + DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i])); + DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq)); + DEB(DEB_INIT, printk(KERN_INFO + "%s: dma at 0x%p (%d bytes), lp->scb at 0x%p\n", + dev->name, dma, (int)sizeof(struct i596_dma), + &dma->scb)); + + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void i596_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + i596_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + +static irqreturn_t i596_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct i596_private *lp; + struct i596_dma *dma; + unsigned short status, ack_cmd = 0; + + if (dev == NULL) { + printk(KERN_WARNING "%s: irq %d for unknown device.\n", + __FUNCTION__, irq); + return IRQ_NONE; + } + + lp = netdev_priv(dev); + dma = lp->dma; + + spin_lock (&lp->lock); + + wait_cmd(dev, dma, 100, "i596 interrupt, timeout"); + status = SWAP16(dma->scb.status); + + DEB(DEB_INTS, printk(KERN_DEBUG + "%s: i596 interrupt, IRQ %d, status %4.4x.\n", + dev->name, irq, status)); + + ack_cmd = status & 0xf000; + + if (!ack_cmd) { + DEB(DEB_ERRORS, printk(KERN_DEBUG + "%s: interrupt with no events\n", + dev->name)); + spin_unlock (&lp->lock); + return IRQ_NONE; + } + + if ((status & 0x8000) || (status & 0x2000)) { + struct i596_cmd *ptr; + + if ((status & 0x8000)) + DEB(DEB_INTS, + printk(KERN_DEBUG + "%s: i596 interrupt completed command.\n", + dev->name)); + if ((status & 0x2000)) + DEB(DEB_INTS, + printk(KERN_DEBUG + "%s: i596 interrupt command unit inactive %x.\n", + dev->name, status & 0x0700)); + + while (lp->cmd_head != NULL) { + DMA_INV(dev, lp->cmd_head, sizeof(struct i596_cmd)); + if (!(lp->cmd_head->status & SWAP16(STAT_C))) + break; + + ptr = lp->cmd_head; + + DEB(DEB_STATUS, + printk(KERN_DEBUG + "cmd_head->status = %04x, ->command = %04x\n", + SWAP16(lp->cmd_head->status), + SWAP16(lp->cmd_head->command))); + lp->cmd_head = ptr->v_next; + lp->cmd_backlog--; + + switch (SWAP16(ptr->command) & 0x7) { + case CmdTx: + { + struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; + struct sk_buff *skb = tx_cmd->skb; + + if (ptr->status & SWAP16(STAT_OK)) { + DEB(DEB_TXADDR, + print_eth(skb->data, "tx-done")); + } else { + lp->stats.tx_errors++; + if (ptr->status & SWAP16(0x0020)) + lp->stats.collisions++; + if (!(ptr->status & SWAP16(0x0040))) + lp->stats.tx_heartbeat_errors++; + if (ptr->status & SWAP16(0x0400)) + lp->stats.tx_carrier_errors++; + if (ptr->status & SWAP16(0x0800)) + lp->stats.collisions++; + if (ptr->status & SWAP16(0x1000)) + lp->stats.tx_aborted_errors++; + } + dma_unmap_single(dev->dev.parent, + tx_cmd->dma_addr, + skb->len, DMA_TO_DEVICE); + dev_kfree_skb_irq(skb); + + tx_cmd->cmd.command = 0; /* Mark free */ + break; + } + case CmdTDR: + { + unsigned short status = SWAP16(((struct tdr_cmd *)ptr)->status); + + if (status & 0x8000) { + DEB(DEB_ANY, + printk(KERN_DEBUG "%s: link ok.\n", + dev->name)); + } else { + if (status & 0x4000) + printk(KERN_ERR + "%s: Transceiver problem.\n", + dev->name); + if (status & 0x2000) + printk(KERN_ERR + "%s: Termination problem.\n", + dev->name); + if (status & 0x1000) + printk(KERN_ERR + "%s: Short circuit.\n", + dev->name); + + DEB(DEB_TDR, + printk(KERN_DEBUG "%s: Time %d.\n", + dev->name, status & 0x07ff)); + } + break; + } + case CmdConfigure: + /* + * Zap command so set_multicast_list() know + * it is free + */ + ptr->command = 0; + break; + } + ptr->v_next = NULL; + ptr->b_next = I596_NULL; + DMA_WBACK(dev, ptr, sizeof(struct i596_cmd)); + lp->last_cmd = jiffies; + } + + /* This mess is arranging that only the last of any outstanding + * commands has the interrupt bit set. Should probably really + * only add to the cmd queue when the CU is stopped. + */ + ptr = lp->cmd_head; + while ((ptr != NULL) && (ptr != lp->cmd_tail)) { + struct i596_cmd *prev = ptr; + + ptr->command &= SWAP16(0x1fff); + ptr = ptr->v_next; + DMA_WBACK_INV(dev, prev, sizeof(struct i596_cmd)); + } + + if (lp->cmd_head != NULL) + ack_cmd |= CUC_START; + dma->scb.cmd = SWAP32(virt_to_dma(lp, &lp->cmd_head->status)); + DMA_WBACK_INV(dev, &dma->scb, sizeof(struct i596_scb)); + } + if ((status & 0x1000) || (status & 0x4000)) { + if ((status & 0x4000)) + DEB(DEB_INTS, + printk(KERN_DEBUG + "%s: i596 interrupt received a frame.\n", + dev->name)); + i596_rx(dev); + /* Only RX_START if stopped - RGH 07-07-96 */ + if (status & 0x1000) { + if (netif_running(dev)) { + DEB(DEB_ERRORS, + printk(KERN_DEBUG + "%s: i596 interrupt receive unit inactive, status 0x%x\n", + dev->name, status)); + ack_cmd |= RX_START; + lp->stats.rx_errors++; + lp->stats.rx_fifo_errors++; + rebuild_rx_bufs(dev); + } + } + } + wait_cmd(dev, dma, 100, "i596 interrupt, timeout"); + dma->scb.command = SWAP16(ack_cmd); + DMA_WBACK(dev, &dma->scb, sizeof(struct i596_scb)); + + /* DANGER: I suspect that some kind of interrupt + acknowledgement aside from acking the 82596 might be needed + here... but it's running acceptably without */ + + ca(dev); + + wait_cmd(dev, dma, 100, "i596 interrupt, exit timeout"); + DEB(DEB_INTS, printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name)); + + spin_unlock (&lp->lock); + return IRQ_HANDLED; +} + +static int i596_close(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + unsigned long flags; + + netif_stop_queue(dev); + + DEB(DEB_INIT, + printk(KERN_DEBUG + "%s: Shutting down ethercard, status was %4.4x.\n", + dev->name, SWAP16(lp->dma->scb.status))); + + spin_lock_irqsave(&lp->lock, flags); + + wait_cmd(dev, lp->dma, 100, "close1 timed out"); + lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT); + DMA_WBACK(dev, &lp->dma->scb, sizeof(struct i596_scb)); + + ca(dev); + + wait_cmd(dev, lp->dma, 100, "close2 timed out"); + spin_unlock_irqrestore(&lp->lock, flags); + DEB(DEB_STRUCT, i596_display_data(dev)); + i596_cleanup_cmd(dev, lp); + + free_irq(dev->irq, dev); + remove_rx_bufs(dev); + + return 0; +} + +static struct net_device_stats *i596_get_stats(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + + return &lp->stats; +} + +/* + * Set or clear the multicast filter for this adaptor. + */ + +static void set_multicast_list(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + struct i596_dma *dma = lp->dma; + int config = 0, cnt; + + DEB(DEB_MULTI, + printk(KERN_DEBUG + "%s: set multicast list, %d entries, promisc %s, allmulti %s\n", + dev->name, dev->mc_count, + dev->flags & IFF_PROMISC ? "ON" : "OFF", + dev->flags & IFF_ALLMULTI ? "ON" : "OFF")); + + if ((dev->flags & IFF_PROMISC) && + !(dma->cf_cmd.i596_config[8] & 0x01)) { + dma->cf_cmd.i596_config[8] |= 0x01; + config = 1; + } + if (!(dev->flags & IFF_PROMISC) && + (dma->cf_cmd.i596_config[8] & 0x01)) { + dma->cf_cmd.i596_config[8] &= ~0x01; + config = 1; + } + if ((dev->flags & IFF_ALLMULTI) && + (dma->cf_cmd.i596_config[11] & 0x20)) { + dma->cf_cmd.i596_config[11] &= ~0x20; + config = 1; + } + if (!(dev->flags & IFF_ALLMULTI) && + !(dma->cf_cmd.i596_config[11] & 0x20)) { + dma->cf_cmd.i596_config[11] |= 0x20; + config = 1; + } + if (config) { + if (dma->cf_cmd.cmd.command) + printk(KERN_INFO + "%s: config change request already queued\n", + dev->name); + else { + dma->cf_cmd.cmd.command = SWAP16(CmdConfigure); + DMA_WBACK_INV(dev, &dma->cf_cmd, sizeof(struct cf_cmd)); + i596_add_cmd(dev, &dma->cf_cmd.cmd); + } + } + + cnt = dev->mc_count; + if (cnt > MAX_MC_CNT) { + cnt = MAX_MC_CNT; + printk(KERN_NOTICE "%s: Only %d multicast addresses supported", + dev->name, cnt); + } + + if (dev->mc_count > 0) { + struct dev_mc_list *dmi; + unsigned char *cp; + struct mc_cmd *cmd; + + cmd = &dma->mc_cmd; + cmd->cmd.command = SWAP16(CmdMulticastList); + cmd->mc_cnt = SWAP16(dev->mc_count * 6); + cp = cmd->mc_addrs; + for (dmi = dev->mc_list; + cnt && dmi != NULL; + dmi = dmi->next, cnt--, cp += 6) { + memcpy(cp, dmi->dmi_addr, 6); + if (i596_debug > 1) + DEB(DEB_MULTI, + printk(KERN_DEBUG + "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, cp[0], cp[1], cp[2], cp[3], cp[4], cp[5])); + } + DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd)); + i596_add_cmd(dev, &cmd->cmd); + } +} From f2ec8030085a27c4ba8e95a10a96f248efb34177 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 28 Jun 2007 00:49:06 +0200 Subject: [PATCH 130/551] Ethernet driver for EISA only SNI RM200/RM400 machines Changes to last version: - spelling fix - cleaned up probe code Thomas. Ethernet driver for EISA only SNI RM200/RM400 machines Signed-off-by: Thomas Bogendoerfer Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 7 ++ drivers/net/Makefile | 1 + drivers/net/sni_82596.c | 185 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/net/sni_82596.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dbf773356326..5cc3d517e39b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -431,6 +431,13 @@ config LASI_82596 Say Y here to support the builtin Intel 82596 ethernet controller found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet. +config SNI_82596 + tristate "SNI RM ethernet" + depends on NET_ETHERNET && SNI_RM + help + Say Y here to support the on-board Intel 82596 ethernet controller + built into SNI RM machines. + config MIPS_JAZZ_SONIC tristate "MIPS JAZZ onboard SONIC Ethernet support" depends on MACH_JAZZ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a77affa4f6e6..eb62fb48e4b7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -157,6 +157,7 @@ obj-$(CONFIG_ELPLUS) += 3c505.o obj-$(CONFIG_AC3200) += ac3200.o 8390.o obj-$(CONFIG_APRICOT) += 82596.o obj-$(CONFIG_LASI_82596) += lasi_82596.o +obj-$(CONFIG_SNI_82596) += sni_82596.o obj-$(CONFIG_MVME16x_NET) += 82596.o obj-$(CONFIG_BVME6000_NET) += 82596.o obj-$(CONFIG_SC92031) += sc92031.o diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c new file mode 100644 index 000000000000..2cf6794acb4f --- /dev/null +++ b/drivers/net/sni_82596.c @@ -0,0 +1,185 @@ +/* + * sni_82596.c -- driver for intel 82596 ethernet controller, as + * used in older SNI RM machines + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SNI_82596_DRIVER_VERSION "SNI RM 82596 driver - Revision: 0.01" + +static const char sni_82596_string[] = "snirm_82596"; + +#define DMA_ALLOC dma_alloc_coherent +#define DMA_FREE dma_free_coherent +#define DMA_WBACK(priv, addr, len) do { } while (0) +#define DMA_INV(priv, addr, len) do { } while (0) +#define DMA_WBACK_INV(priv, addr, len) do { } while (0) + +#define SYSBUS 0x00004400 + +/* big endian CPU, 82596 little endian */ +#define SWAP32(x) cpu_to_le32((u32)(x)) +#define SWAP16(x) cpu_to_le16((u16)(x)) + +#define OPT_MPU_16BIT 0x01 + +#include "lib82596.c" + +MODULE_AUTHOR("Thomas Bogendoerfer"); +MODULE_DESCRIPTION("i82596 driver"); +MODULE_LICENSE("GPL"); +module_param(i596_debug, int, 0); +MODULE_PARM_DESC(i596_debug, "82596 debug mask"); + +static inline void ca(struct net_device *dev) +{ + struct i596_private *lp = netdev_priv(dev); + + writel(0, lp->ca); +} + + +static void mpu_port(struct net_device *dev, int c, dma_addr_t x) +{ + struct i596_private *lp = netdev_priv(dev); + + u32 v = (u32) (c) | (u32) (x); + + if (lp->options & OPT_MPU_16BIT) { + writew(v & 0xffff, lp->mpu_port); + wmb(); /* order writes to MPU port */ + udelay(1); + writew(v >> 16, lp->mpu_port); + } else { + writel(v, lp->mpu_port); + wmb(); /* order writes to MPU port */ + udelay(1); + writel(v, lp->mpu_port); + } +} + + +static int __devinit sni_82596_probe(struct platform_device *dev) +{ + struct net_device *netdevice; + struct i596_private *lp; + struct resource *res, *ca, *idprom, *options; + int retval = -ENOMEM; + void __iomem *mpu_addr; + void __iomem *ca_addr; + u8 __iomem *eth_addr; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + ca = platform_get_resource(dev, IORESOURCE_MEM, 1); + options = platform_get_resource(dev, 0, 0); + idprom = platform_get_resource(dev, IORESOURCE_MEM, 2); + if (!res || !ca || !options || !idprom) + return -ENODEV; + mpu_addr = ioremap_nocache(res->start, 4); + if (!mpu_addr) + return -ENOMEM; + ca_addr = ioremap_nocache(ca->start, 4); + if (!ca_addr) + goto probe_failed_free_mpu; + + printk(KERN_INFO "Found i82596 at 0x%x\n", res->start); + + netdevice = alloc_etherdev(sizeof(struct i596_private)); + if (!netdevice) + goto probe_failed_free_ca; + + SET_NETDEV_DEV(netdevice, &dev->dev); + platform_set_drvdata (dev, netdevice); + + netdevice->base_addr = res->start; + netdevice->irq = platform_get_irq(dev, 0); + + eth_addr = ioremap_nocache(idprom->start, 0x10); + if (!eth_addr) + goto probe_failed; + + /* someone seems to like messed up stuff */ + netdevice->dev_addr[0] = readb(eth_addr + 0x0b); + netdevice->dev_addr[1] = readb(eth_addr + 0x0a); + netdevice->dev_addr[2] = readb(eth_addr + 0x09); + netdevice->dev_addr[3] = readb(eth_addr + 0x08); + netdevice->dev_addr[4] = readb(eth_addr + 0x07); + netdevice->dev_addr[5] = readb(eth_addr + 0x06); + iounmap(eth_addr); + + if (!netdevice->irq) { + printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", + __FILE__, netdevice->base_addr); + goto probe_failed; + } + + lp = netdev_priv(netdevice); + lp->options = options->flags & IORESOURCE_BITS; + lp->ca = ca_addr; + lp->mpu_port = mpu_addr; + + retval = i82596_probe(netdevice); + if (retval == 0) + return 0; + +probe_failed: + free_netdev(netdevice); +probe_failed_free_ca: + iounmap(ca_addr); +probe_failed_free_mpu: + iounmap(mpu_addr); + return retval; +} + +static int __devexit sni_82596_driver_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct i596_private *lp = netdev_priv(dev); + + unregister_netdev(dev); + DMA_FREE(dev->dev.parent, sizeof(struct i596_private), + lp->dma, lp->dma_addr); + iounmap(lp->ca); + iounmap(lp->mpu_port); + free_netdev (dev); + return 0; +} + +static struct platform_driver sni_82596_driver = { + .probe = sni_82596_probe, + .remove = __devexit_p(sni_82596_driver_remove), + .driver = { + .name = sni_82596_string, + }, +}; + +static int __devinit sni_82596_init(void) +{ + printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n"); + return platform_driver_register(&sni_82596_driver); +} + + +static void __exit sni_82596_exit(void) +{ + platform_driver_unregister(&sni_82596_driver); +} + +module_init(sni_82596_init); +module_exit(sni_82596_exit); From b524fe646c9a226a847e30ca1221dc22e952f16b Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 2 May 2007 09:44:03 -0500 Subject: [PATCH 131/551] [GFS2] flush the glock completely in inode_go_sync Fix for bz #231910 When filemap_fdatawrite() is called on the inode mapping in data=ordered mode, it will add the glock to the log. In inode_go_sync(), if you do the gfs2_log_flush() before this, after the filemap_fdatawrite() call, the glock and its associated data buffers will be on the log again. This means you can demote a lock from exclusive, without having it flushed from the log. The attached patch simply moves the gfs2_log_flush up to after the filemap_fdatawrite() call. Originally, I tried moving the gfs2_log_flush to after gfs2_meta_sync(), but that caused me to trip the following assert. GFS2: fsid=cypher-36:test.0: fatal: assertion "!buffer_busy(bh)" failed GFS2: fsid=cypher-36:test.0: function = gfs2_ail_empty_gl, file = fs/gfs2/glops.c, line = 61 It appears that gfs2_log_flush() puts some of the glocks buffers in the busy state and the filemap_fdatawrite() call is necessary to flush them. This makes me worry slightly that a related problem could happen because of moving the gfs2_log_flush() after the initial filemap_fdatawrite(), but I assume that gfs2_ail_empty_gl() would catch that case as well. Signed-off-by: Benjamin E. Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/glops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 7b82657a9910..777ca46010e8 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -156,9 +156,9 @@ static void inode_go_sync(struct gfs2_glock *gl) ip = NULL; if (test_bit(GLF_DIRTY, &gl->gl_flags)) { - gfs2_log_flush(gl->gl_sbd, gl); if (ip) filemap_fdatawrite(ip->i_inode.i_mapping); + gfs2_log_flush(gl->gl_sbd, gl); gfs2_meta_sync(gl); if (ip) { struct address_space *mapping = ip->i_inode.i_mapping; From 3168b0780d06ace875696f8a648d04d6089654e5 Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Tue, 8 May 2007 09:18:58 +0100 Subject: [PATCH 132/551] [DLM] fix a couple of races Fix two races in fs/dlm/config.c: (1) Grab the configfs subsystem semaphore before calling config_group_find_obj() in get_space(). This solves a potential race between get_space() and concurrent mkdir(2) or rmdir(2). (2) Grab a reference on the found config_item _while_ holding the configfs subsystem semaphore in get_comm(), and not after it. This solves a potential race between get_comm() and concurrent rmdir(2). Signed-off-by: Satyam Sharma Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/config.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 822abdcd1434..5a3d390cc826 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -748,9 +748,16 @@ static ssize_t node_weight_write(struct node *nd, const char *buf, size_t len) static struct space *get_space(char *name) { + struct config_item *i; + if (!space_list) return NULL; - return to_space(config_group_find_obj(space_list, name)); + + down(&space_list->cg_subsys->su_sem); + i = config_group_find_obj(space_list, name); + up(&space_list->cg_subsys->su_sem); + + return to_space(i); } static void put_space(struct space *sp) @@ -776,20 +783,20 @@ static struct comm *get_comm(int nodeid, struct sockaddr_storage *addr) if (cm->nodeid != nodeid) continue; found = 1; + config_item_get(i); break; } else { if (!cm->addr_count || memcmp(cm->addr[0], addr, sizeof(*addr))) continue; found = 1; + config_item_get(i); break; } } up(&clusters_root.subsys.su_sem); - if (found) - config_item_get(i); - else + if (!found) cm = NULL; return cm; } From 7ae8fa8451dfb3879ecbc04f2760a707dc65b988 Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Wed, 9 May 2007 09:37:57 -0500 Subject: [PATCH 133/551] [GFS2] kernel changes to support new gfs2_grow command This is another revision of my gfs2 kernel patch that allows gfs2_grow to function properly. Steve Whitehouse expressed some concerns about the previous patch and I restructured it based on his comments. The previous patch was doing the statfs_change at file close time, under its own transaction. The current patch does the statfs_change inside the gfs2_commit_write function, which keeps it under the umbrella of the inode transaction. I can't call ri_update to re-read the rindex file during the transaction because the transaction may have outstanding unwritten buffers attached to the rgrps that would be otherwise blown away. So instead, I created a new function, gfs2_ri_total, that will re-read the rindex file just to total the file system space for the sake of the statfs_change. The ri_update will happen later, when gfs2 realizes the version number has changed, as it happened before my patch. Since the statfs_change is happening at write_commit time and there may be multiple writes to the rindex file for one grow operation. So one consequence of this restructuring is that instead of getting one kernel message to indicate the change, you may see several. For example, before when you did a gfs2_grow, you'd get a single message like: GFS2: File system extended by 247876 blocks (968MB) Now you get something like: GFS2: File system extended by 207896 blocks (812MB) GFS2: File system extended by 39980 blocks (156MB) This version has also been successfully run against the hours-long "gfs2_fsck_hellfire" test that does several gfs2_grow and gfs2_fsck while interjecting file system damage. It does this repeatedly under a variety Resource Group conditions. Signed-off-By: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_address.c | 29 ++++++++++++++++++++- fs/gfs2/ops_address.h | 5 +++- fs/gfs2/rgrp.c | 60 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 30c15622174f..846c0ff75cff 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -449,6 +449,30 @@ out_uninit: return error; } +/** + * adjust_fs_space - Adjusts the free space available due to gfs2_grow + * @inode: the rindex inode + */ +static void adjust_fs_space(struct inode *inode) +{ + struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; + u64 fs_total, new_free; + + /* Total up the file system space, according to the latest rindex. */ + fs_total = gfs2_ri_total(sdp); + + spin_lock(&sdp->sd_statfs_spin); + if (fs_total > (m_sc->sc_total + l_sc->sc_total)) + new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); + else + new_free = 0; + spin_unlock(&sdp->sd_statfs_spin); + fs_warn(sdp, "File system extended by %llu blocks.\n", new_free); + gfs2_statfs_change(sdp, new_free, new_free, 0); +} + /** * gfs2_commit_write - Commit write to a file * @file: The file to write to @@ -511,6 +535,9 @@ static int gfs2_commit_write(struct file *file, struct page *page, di->di_size = cpu_to_be64(inode->i_size); } + if (inode == sdp->sd_rindex) + adjust_fs_space(inode); + brelse(dibh); gfs2_trans_end(sdp); if (al->al_requested) { diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h index 35aaee4aa7e1..56c30daf895b 100644 --- a/fs/gfs2/ops_address.h +++ b/fs/gfs2/ops_address.h @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -18,5 +18,8 @@ extern const struct address_space_operations gfs2_file_aops; extern int gfs2_get_block(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create); extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); +extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); +extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, + s64 dinodes); #endif /* __OPS_ADDRESS_DOT_H__ */ diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 1727f5012efe..e857f405353b 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -430,6 +430,38 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) return 0; } +/** + * gfs2_ri_total - Total up the file system space, according to the rindex. + * + */ +u64 gfs2_ri_total(struct gfs2_sbd *sdp) +{ + u64 total_data = 0; + struct inode *inode = sdp->sd_rindex; + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_rindex_host ri; + char buf[sizeof(struct gfs2_rindex)]; + struct file_ra_state ra_state; + int error, rgrps; + + mutex_lock(&sdp->sd_rindex_mutex); + file_ra_state_init(&ra_state, inode->i_mapping); + for (rgrps = 0;; rgrps++) { + loff_t pos = rgrps * sizeof(struct gfs2_rindex); + + if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) + break; + error = gfs2_internal_read(ip, &ra_state, buf, &pos, + sizeof(struct gfs2_rindex)); + if (error != sizeof(struct gfs2_rindex)) + break; + gfs2_rindex_in(&ri, buf); + total_data += ri.ri_data; + } + mutex_unlock(&sdp->sd_rindex_mutex); + return total_data; +} + /** * gfs2_ri_update - Pull in a new resource index from the disk * @gl: The glock covering the rindex inode @@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip) u64 junk = ip->i_di.di_size; int error; - if (do_div(junk, sizeof(struct gfs2_rindex))) { + /* If someone is holding the rindex file with a glock, they must + be updating it, in which case we may have partial entries. + In this case, we ignore the partials. */ + if (!gfs2_glock_is_held_excl(ip->i_gl) && + !gfs2_glock_is_held_shrd(ip->i_gl) && + do_div(junk, sizeof(struct gfs2_rindex))) { gfs2_consist_inode(ip); return -EIO; } @@ -457,6 +494,9 @@ static int gfs2_ri_update(struct gfs2_inode *ip) file_ra_state_init(&ra_state, inode->i_mapping); for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); + + if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) + break; error = gfs2_internal_read(ip, &ra_state, buf, &pos, sizeof(struct gfs2_rindex)); if (!error) @@ -978,18 +1018,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = &ip->i_alloc; - int error; + int error = 0; if (gfs2_assert_warn(sdp, al->al_requested)) return -EINVAL; - error = gfs2_rindex_hold(sdp, &al->al_ri_gh); + /* We need to hold the rindex unless the inode we're using is + the rindex itself, in which case it's already held. */ + if (ip != GFS2_I(sdp->sd_rindex)) + error = gfs2_rindex_hold(sdp, &al->al_ri_gh); + else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ + error = gfs2_ri_update(ip); + if (error) return error; error = get_local_rgrp(ip); if (error) { - gfs2_glock_dq_uninit(&al->al_ri_gh); + if (ip != GFS2_I(sdp->sd_rindex)) + gfs2_glock_dq_uninit(&al->al_ri_gh); return error; } @@ -1019,7 +1066,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip) al->al_rgd = NULL; gfs2_glock_dq_uninit(&al->al_rgd_gh); - gfs2_glock_dq_uninit(&al->al_ri_gh); + if (ip != GFS2_I(sdp->sd_rindex)) + gfs2_glock_dq_uninit(&al->al_ri_gh); } /** From 6c53267f05dc6689ff662efeec426d25d2c0ab84 Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Thu, 10 May 2007 16:54:38 -0500 Subject: [PATCH 134/551] [GFS2] Kernel changes to support new gfs2_grow command (part 2) To avoid code redundancy, I separated out the operational "guts" into a new function called read_rindex_entry. Then I made two functions: the closer-to-original gfs2_ri_update (without the special condition checks) and gfs2_ri_update_special that's designed with that condition in mind. (I don't like the name, but if you have a suggestion, I'm all ears). Oh, and there's an added benefit: we don't need all the ugly gotos anymore. ;) This patch has been tested with gfs2_fsck_hellfire (which runs for three and a half hours, btw). Signed-off-By: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_address.c | 3 +- fs/gfs2/rgrp.c | 143 +++++++++++++++++++++++++++--------------- 2 files changed, 95 insertions(+), 51 deletions(-) diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 846c0ff75cff..e0b4e8c2b68d 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode) else new_free = 0; spin_unlock(&sdp->sd_statfs_spin); - fs_warn(sdp, "File system extended by %llu blocks.\n", new_free); + fs_warn(sdp, "File system extended by %llu blocks.\n", + (unsigned long long)new_free); gfs2_statfs_change(sdp, new_free, new_free, 0); } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e857f405353b..48a6461d601c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -463,9 +463,62 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) } /** - * gfs2_ri_update - Pull in a new resource index from the disk + * read_rindex_entry - Pull in a new resource index entry from the disk * @gl: The glock covering the rindex inode * + * Returns: 0 on success, error code otherwise + */ + +static int read_rindex_entry(struct gfs2_inode *ip, + struct file_ra_state *ra_state) +{ + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); + char buf[sizeof(struct gfs2_rindex)]; + int error; + struct gfs2_rgrpd *rgd; + + error = gfs2_internal_read(ip, ra_state, buf, &pos, + sizeof(struct gfs2_rindex)); + if (!error) + return 0; + if (error != sizeof(struct gfs2_rindex)) { + if (error > 0) + error = -EIO; + return error; + } + + rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); + error = -ENOMEM; + if (!rgd) + return error; + + mutex_init(&rgd->rd_mutex); + lops_init_le(&rgd->rd_le, &gfs2_rg_lops); + rgd->rd_sbd = sdp; + + list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); + list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); + + gfs2_rindex_in(&rgd->rd_ri, buf); + error = compute_bitstructs(rgd); + if (error) + return error; + + error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, + &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); + if (error) + return error; + + rgd->rd_gl->gl_object = rgd; + rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + return error; +} + +/** + * gfs2_ri_update - Pull in a new resource index from the disk + * @ip: pointer to the rindex inode + * * Returns: 0 on successful update, error code otherwise */ @@ -473,18 +526,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct inode *inode = &ip->i_inode; - struct gfs2_rgrpd *rgd; - char buf[sizeof(struct gfs2_rindex)]; struct file_ra_state ra_state; u64 junk = ip->i_di.di_size; int error; - /* If someone is holding the rindex file with a glock, they must - be updating it, in which case we may have partial entries. - In this case, we ignore the partials. */ - if (!gfs2_glock_is_held_excl(ip->i_gl) && - !gfs2_glock_is_held_shrd(ip->i_gl) && - do_div(junk, sizeof(struct gfs2_rindex))) { + if (do_div(junk, sizeof(struct gfs2_rindex))) { gfs2_consist_inode(ip); return -EIO; } @@ -493,52 +539,49 @@ static int gfs2_ri_update(struct gfs2_inode *ip) file_ra_state_init(&ra_state, inode->i_mapping); for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { - loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); - - if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) - break; - error = gfs2_internal_read(ip, &ra_state, buf, &pos, - sizeof(struct gfs2_rindex)); - if (!error) - break; - if (error != sizeof(struct gfs2_rindex)) { - if (error > 0) - error = -EIO; - goto fail; + error = read_rindex_entry(ip, &ra_state); + if (error) { + clear_rgrpdi(sdp); + return error; } - - rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); - error = -ENOMEM; - if (!rgd) - goto fail; - - mutex_init(&rgd->rd_mutex); - lops_init_le(&rgd->rd_le, &gfs2_rg_lops); - rgd->rd_sbd = sdp; - - list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); - list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); - - gfs2_rindex_in(&rgd->rd_ri, buf); - error = compute_bitstructs(rgd); - if (error) - goto fail; - - error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, - &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); - if (error) - goto fail; - - rgd->rd_gl->gl_object = rgd; - rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; } sdp->sd_rindex_vn = ip->i_gl->gl_vn; return 0; +} -fail: - clear_rgrpdi(sdp); - return error; +/** + * gfs2_ri_update_special - Pull in a new resource index from the disk + * + * This is a special version that's safe to call from gfs2_inplace_reserve_i. + * In this case we know that we don't have any resource groups in memory yet. + * + * @ip: pointer to the rindex inode + * + * Returns: 0 on successful update, error code otherwise + */ +static int gfs2_ri_update_special(struct gfs2_inode *ip) +{ + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + struct inode *inode = &ip->i_inode; + struct file_ra_state ra_state; + int error; + + file_ra_state_init(&ra_state, inode->i_mapping); + for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { + /* Ignore partials */ + if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > + ip->i_di.di_size) + break; + error = read_rindex_entry(ip, &ra_state); + if (error) { + clear_rgrpdi(sdp); + return error; + } + } + + sdp->sd_rindex_vn = ip->i_gl->gl_vn; + return 0; } /** @@ -1028,7 +1071,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) if (ip != GFS2_I(sdp->sd_rindex)) error = gfs2_rindex_hold(sdp, &al->al_ri_gh); else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ - error = gfs2_ri_update(ip); + error = gfs2_ri_update_special(ip); if (error) return error; From 0507ecf50f22e433592f5ec3a36dc831aaec2e02 Mon Sep 17 00:00:00 2001 From: Nate Diller Date: Thu, 10 May 2007 22:41:28 -0700 Subject: [PATCH 135/551] [GFS2] use zero_user_page Use zero_user_page() instead of open-coding it. Signed-off-by: Nate Diller Cc: Steven Whitehouse Signed-off-by: Andrew Morton --- fs/gfs2/bmap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index c53a5d2d0590..1c40c4bbf379 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -885,7 +885,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping) unsigned blocksize, iblock, length, pos; struct buffer_head *bh; struct page *page; - void *kaddr; int err; page = grab_cache_page(mapping, index); @@ -933,10 +932,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping) if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + offset, 0, length); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); + zero_user_page(page, offset, length, KM_USER0); unlock: unlock_page(page); From cd81a4bac67d44742ab0aa1848f4a78e9d7e1093 Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Mon, 14 May 2007 12:42:18 -0500 Subject: [PATCH 136/551] [GFS2] Addendum patch 2 for gfs2_grow This addendum patch 2 corrects three things: 1. It fixes a stupid mistake in the previous addendum that broke gfs2. Ref: https://www.redhat.com/archives/cluster-devel/2007-May/msg00162.html 2. It fixes a problem that Dave Teigland pointed out regarding the external declarations in ops_address.h being in the wrong place. 3. It recasts a couple more %llu printks to (unsigned long long) as requested by Steve Whitehouse. I would have loved to put this all in one revised patch, but there was a rush to get some patches for RHEL5. Therefore, the previous patches were applied to the git tree "as is" and therefore, I'm posting another addendum. Sorry. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 7 ++++--- fs/gfs2/ops_address.c | 1 + fs/gfs2/ops_address.h | 3 --- fs/gfs2/rgrp.c | 6 +++--- fs/gfs2/rgrp.h | 1 + 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 1815429a2978..c66c718013ef 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1823,7 +1823,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip) print_dbg(gi, " Inode:\n"); print_dbg(gi, " num = %llu/%llu\n", - ip->i_num.no_formal_ino, ip->i_num.no_addr); + (unsigned long long)ip->i_num.no_formal_ino, + (unsigned long long)ip->i_num.no_addr); print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); print_dbg(gi, " i_flags ="); for (x = 0; x < 32; x++) @@ -1909,8 +1910,8 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl) } if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", - gl->gl_demote_state, - (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ)); + gl->gl_demote_state, (unsigned long long) + (jiffies - gl->gl_demote_time)*(1000000/HZ)); } if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { if (!test_bit(GLF_LOCK, &gl->gl_flags) && diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index e0b4e8c2b68d..4913ef57b095 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -32,6 +32,7 @@ #include "trans.h" #include "rgrp.h" #include "ops_file.h" +#include "super.h" #include "util.h" #include "glops.h" diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h index 56c30daf895b..fa1b5b3d28b9 100644 --- a/fs/gfs2/ops_address.h +++ b/fs/gfs2/ops_address.h @@ -18,8 +18,5 @@ extern const struct address_space_operations gfs2_file_aops; extern int gfs2_get_block(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create); extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); -extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); -extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, - s64 dinodes); #endif /* __OPS_ADDRESS_DOT_H__ */ diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 48a6461d601c..a62c0f2d26d3 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -527,10 +527,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct inode *inode = &ip->i_inode; struct file_ra_state ra_state; - u64 junk = ip->i_di.di_size; + u64 rgrp_count = ip->i_di.di_size; int error; - if (do_div(junk, sizeof(struct gfs2_rindex))) { + if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { gfs2_consist_inode(ip); return -EIO; } @@ -538,7 +538,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip) clear_rgrpdi(sdp); file_ra_state_init(&ra_state, inode->i_mapping); - for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { + for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) { error = read_rindex_entry(ip, &ra_state); if (error) { clear_rgrpdi(sdp); diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index b01e0cfc99b5..b4c6adfc6f2e 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -65,5 +65,6 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, int flags); void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); +u64 gfs2_ri_total(struct gfs2_sbd *sdp); #endif /* __RGRP_DOT_H__ */ From 41d7db0ab437bc84f8a6e77cccc626ce937605ac Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 14 May 2007 17:43:26 +0100 Subject: [PATCH 137/551] [GFS2] Reduce size of struct gdlm_lock This patch removes the completion (which is rather large) from struct gdlm_lock in favour of using the wait_on_bit() functions. We don't need to add any extra fields to the structure to do this, so we save 32 bytes (on x86_64) per structure. This adds up to quite a lot when we may potentially have millions of these lock structures, Signed-off-by: Steven Whitehouse Acked-by: David Teigland --- fs/gfs2/locking/dlm/lock.c | 11 ++++++++--- fs/gfs2/locking/dlm/lock_dlm.h | 2 +- fs/gfs2/locking/dlm/thread.c | 11 +++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c index c305255bfe8a..542a797ac89a 100644 --- a/fs/gfs2/locking/dlm/lock.c +++ b/fs/gfs2/locking/dlm/lock.c @@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, lp->cur = DLM_LOCK_IV; lp->lvb = NULL; lp->hold_null = NULL; - init_completion(&lp->ast_wait); INIT_LIST_HEAD(&lp->clist); INIT_LIST_HEAD(&lp->blist); INIT_LIST_HEAD(&lp->delay_list); @@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp) lp->lksb.sb_lvbptr = NULL; } +static int gdlm_ast_wait(void *word) +{ + schedule(); + return 0; +} + /* This can do a synchronous dlm request (requiring a lock_dlm thread to get the completion) because gfs won't call hold_lvb() during a callback (from the context of a lock_dlm thread). */ @@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp) lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; set_bit(LFL_NOBAST, &lpn->flags); set_bit(LFL_INLOCK, &lpn->flags); + set_bit(LFL_AST_WAIT, &lpn->flags); - init_completion(&lpn->ast_wait); gdlm_do_lock(lpn); - wait_for_completion(&lpn->ast_wait); + wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE); error = lpn->lksb.sb_status; if (error) { printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h index d074c6e6f9bf..24d70f73b651 100644 --- a/fs/gfs2/locking/dlm/lock_dlm.h +++ b/fs/gfs2/locking/dlm/lock_dlm.h @@ -101,6 +101,7 @@ enum { LFL_NOBAST = 10, LFL_HEADQUE = 11, LFL_UNLOCK_DELETE = 12, + LFL_AST_WAIT = 13, }; struct gdlm_lock { @@ -117,7 +118,6 @@ struct gdlm_lock { unsigned long flags; /* lock_dlm flags LFL_ */ int bast_mode; /* protected by async_lock */ - struct completion ast_wait; struct list_head clist; /* complete */ struct list_head blist; /* blocking */ diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c index 9cf1f168eaf8..1aca51e45092 100644 --- a/fs/gfs2/locking/dlm/thread.c +++ b/fs/gfs2/locking/dlm/thread.c @@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode) ls->fscb(ls->sdp, cb, &lp->lockname); } +static void wake_up_ast(struct gdlm_lock *lp) +{ + clear_bit(LFL_AST_WAIT, &lp->flags); + smp_mb__after_clear_bit(); + wake_up_bit(&lp->flags, LFL_AST_WAIT); +} + static void process_complete(struct gdlm_lock *lp) { struct gdlm_ls *ls = lp->ls; @@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp) */ if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { - complete(&lp->ast_wait); + wake_up_ast(lp); return; } @@ -214,7 +221,7 @@ out: if (test_bit(LFL_INLOCK, &lp->flags)) { clear_bit(LFL_NOBLOCK, &lp->flags); lp->cur = lp->req; - complete(&lp->ast_wait); + wake_up_ast(lp); return; } From dbb7cae2a36170cd17ffbe286ec0c91a998740ff Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 15 May 2007 15:37:50 +0100 Subject: [PATCH 138/551] [GFS2] Clean up inode number handling This patch cleans up the inode number handling code. The main difference is that instead of looking up the inodes using a struct gfs2_inum_host we now use just the no_addr member of this structure. The tests relating to no_formal_ino can then be done by the calling code. This has advantages in that we want to do different things in different code paths if the no_formal_ino doesn't match. In the NFS patch we want to return -ESTALE, but in the ->lookup() path, its a bug in the fs if the no_formal_ino doesn't match and thus we can withdraw in this case. In order to later fix bz #201012, we need to be able to look up an inode without knowing no_formal_ino, as the only information that is known to us is the on-disk location of the inode in question. This patch will also help us to fix bz #236099 at a later date by cleaning up a lot of the code in that area. There are no user visible changes as a result of this patch and there are no changes to the on-disk format either. Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 2 +- fs/gfs2/dir.c | 56 ++++++++++++++++++++------ fs/gfs2/dir.h | 9 +++-- fs/gfs2/glock.c | 4 +- fs/gfs2/incore.h | 4 +- fs/gfs2/inode.c | 80 ++++++++++++++----------------------- fs/gfs2/inode.h | 18 ++++++--- fs/gfs2/meta_io.h | 2 +- fs/gfs2/ondisk.c | 37 +++++------------ fs/gfs2/ops_address.c | 4 +- fs/gfs2/ops_dentry.c | 24 ++++------- fs/gfs2/ops_export.c | 29 ++++++++------ fs/gfs2/ops_file.c | 4 +- fs/gfs2/ops_fstype.c | 16 ++++---- fs/gfs2/ops_inode.c | 20 +++++----- fs/gfs2/rgrp.c | 6 +-- fs/gfs2/super.c | 2 +- fs/gfs2/util.c | 4 +- include/linux/gfs2_ondisk.h | 11 +---- 19 files changed, 162 insertions(+), 170 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 1c40c4bbf379..e76a887a89b2 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1040,7 +1040,7 @@ static int trunc_end(struct gfs2_inode *ip) ip->i_di.di_height = 0; ip->i_di.di_goal_meta = ip->i_di.di_goal_data = - ip->i_num.no_addr; + ip->i_no_addr; gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); } ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index a96fa07b3f3b..9cdd71cef59c 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, if (dip->i_di.di_entries != g.offset) { fs_warn(sdp, "Number of entries corrupt in dir %llu, " "ip->i_di.di_entries (%u) != g.offset (%u)\n", - (unsigned long long)dip->i_num.no_addr, + (unsigned long long)dip->i_no_addr, dip->i_di.di_entries, g.offset); error = -EIO; @@ -1488,24 +1488,54 @@ out: * Returns: errno */ -int gfs2_dir_search(struct inode *dir, const struct qstr *name, - struct gfs2_inum_host *inum, unsigned int *type) +struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) { struct buffer_head *bh; struct gfs2_dirent *dent; + struct inode *inode; + + dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); + if (dent) { + if (IS_ERR(dent)) + return ERR_PTR(PTR_ERR(dent)); + inode = gfs2_inode_lookup(dir->i_sb, + be64_to_cpu(dent->de_inum.no_addr), + be16_to_cpu(dent->de_type)); + brelse(bh); + return inode; + } + return ERR_PTR(-ENOENT); +} + +int gfs2_dir_check(struct inode *dir, const struct qstr *name, + const struct gfs2_inode *ip) +{ + struct buffer_head *bh; + struct gfs2_dirent *dent; + int ret = -ENOENT; dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); if (dent) { if (IS_ERR(dent)) return PTR_ERR(dent); - if (inum) - gfs2_inum_in(inum, (char *)&dent->de_inum); - if (type) - *type = be16_to_cpu(dent->de_type); + if (ip) { + if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr) + goto out; + if (be64_to_cpu(dent->de_inum.no_formal_ino) != + ip->i_no_formal_ino) + goto out; + if (unlikely(IF2DT(ip->i_inode.i_mode) != + be16_to_cpu(dent->de_type))) { + gfs2_consist_inode(GFS2_I(dir)); + ret = -EIO; + goto out; + } + } + ret = 0; +out: brelse(bh); - return 0; } - return -ENOENT; + return ret; } static int dir_new_leaf(struct inode *inode, const struct qstr *name) @@ -1565,7 +1595,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) */ int gfs2_dir_add(struct inode *inode, const struct qstr *name, - const struct gfs2_inum_host *inum, unsigned type) + const struct gfs2_inode *nip, unsigned type) { struct gfs2_inode *ip = GFS2_I(inode); struct buffer_head *bh; @@ -1580,7 +1610,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, if (IS_ERR(dent)) return PTR_ERR(dent); dent = gfs2_init_dirent(inode, dent, name, bh); - gfs2_inum_out(inum, (char *)&dent->de_inum); + gfs2_inum_out(nip, dent); dent->de_type = cpu_to_be16(type); if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { leaf = (struct gfs2_leaf *)bh->b_data; @@ -1700,7 +1730,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) */ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, - struct gfs2_inum_host *inum, unsigned int new_type) + const struct gfs2_inode *nip, unsigned int new_type) { struct buffer_head *bh; struct gfs2_dirent *dent; @@ -1715,7 +1745,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, return PTR_ERR(dent); gfs2_trans_add_bh(dip->i_gl, bh, 1); - gfs2_inum_out(inum, (char *)&dent->de_inum); + gfs2_inum_out(nip, dent); dent->de_type = cpu_to_be16(new_type); if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 48fe89046bba..8a468cac9328 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h @@ -16,15 +16,16 @@ struct inode; struct gfs2_inode; struct gfs2_inum; -int gfs2_dir_search(struct inode *dir, const struct qstr *filename, - struct gfs2_inum_host *inum, unsigned int *type); +struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename); +int gfs2_dir_check(struct inode *dir, const struct qstr *filename, + const struct gfs2_inode *ip); int gfs2_dir_add(struct inode *inode, const struct qstr *filename, - const struct gfs2_inum_host *inum, unsigned int type); + const struct gfs2_inode *ip, unsigned int type); int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, filldir_t filldir); int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, - struct gfs2_inum_host *new_inum, unsigned int new_type); + const struct gfs2_inode *nip, unsigned int new_type); int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c66c718013ef..b3ed58551e74 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1823,8 +1823,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip) print_dbg(gi, " Inode:\n"); print_dbg(gi, " num = %llu/%llu\n", - (unsigned long long)ip->i_num.no_formal_ino, - (unsigned long long)ip->i_num.no_addr); + (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr); print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); print_dbg(gi, " i_flags ="); for (x = 0; x < 32; x++) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index d995441373ab..00c3004a4c22 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -213,8 +213,8 @@ enum { struct gfs2_inode { struct inode i_inode; - struct gfs2_inum_host i_num; - + u64 i_no_addr; + u64 i_no_formal_ino; unsigned long i_flags; /* GIF_... */ struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index df0b8b3018b9..58f5a67e1c35 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -41,9 +41,9 @@ static int iget_test(struct inode *inode, void *opaque) { struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_inum_host *inum = opaque; + u64 *no_addr = opaque; - if (ip->i_num.no_addr == inum->no_addr && + if (ip->i_no_addr == *no_addr && inode->i_private != NULL) return 1; @@ -53,37 +53,37 @@ static int iget_test(struct inode *inode, void *opaque) static int iget_set(struct inode *inode, void *opaque) { struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_inum_host *inum = opaque; + u64 *no_addr = opaque; - ip->i_num = *inum; - inode->i_ino = inum->no_addr; + inode->i_ino = (unsigned long)*no_addr; + ip->i_no_addr = *no_addr; return 0; } -struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) +struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) { - return ilookup5(sb, (unsigned long)inum->no_addr, - iget_test, inum); + unsigned long hash = (unsigned long)no_addr; + return ilookup5(sb, hash, iget_test, &no_addr); } -static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) +static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) { - return iget5_locked(sb, (unsigned long)inum->no_addr, - iget_test, iget_set, inum); + unsigned long hash = (unsigned long)no_addr; + return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); } /** * gfs2_inode_lookup - Lookup an inode * @sb: The super block - * @inum: The inode number + * @no_addr: The inode number * @type: The type of the inode * * Returns: A VFS inode, or an error */ -struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) +struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type) { - struct inode *inode = gfs2_iget(sb, inum); + struct inode *inode = gfs2_iget(sb, no_addr); struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_glock *io_gl; int error; @@ -110,12 +110,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i inode->i_op = &gfs2_dev_iops; } - error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); if (unlikely(error)) goto fail; ip->i_gl->gl_object = ip; - error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl); + error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); if (unlikely(error)) goto fail_put; @@ -144,14 +144,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) struct gfs2_dinode_host *di = &ip->i_di; const struct gfs2_dinode *str = buf; - if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { + if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) { if (gfs2_consist_inode(ip)) gfs2_dinode_print(ip); return -EIO; } - if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) - return -ESTALE; - + ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); ip->i_inode.i_mode = be32_to_cpu(str->di_mode); ip->i_inode.i_rdev = 0; switch (ip->i_inode.i_mode & S_IFMT) { @@ -247,7 +245,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) if (error) goto out_qs; - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); if (!rgd) { gfs2_consist_inode(ip); error = -EIO; @@ -366,8 +364,6 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, struct super_block *sb = dir->i_sb; struct gfs2_inode *dip = GFS2_I(dir); struct gfs2_holder d_gh; - struct gfs2_inum_host inum; - unsigned int type; int error; struct inode *inode = NULL; int unlock = 0; @@ -395,12 +391,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, goto out; } - error = gfs2_dir_search(dir, name, &inum, &type); - if (error) - goto out; - - inode = gfs2_inode_lookup(sb, &inum, type); - + inode = gfs2_dir_search(dir, name); + if (IS_ERR(inode)) + error = PTR_ERR(inode); out: if (unlock) gfs2_glock_dq_uninit(&d_gh); @@ -548,7 +541,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, if (!dip->i_inode.i_nlink) return -EPERM; - error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); + error = gfs2_dir_check(&dip->i_inode, name, NULL); switch (error) { case -ENOENT: error = 0; @@ -588,8 +581,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, *gid = current->fsgid; } -static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, - u64 *generation) +static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); int error; @@ -605,7 +597,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, if (error) goto out_ipreserv; - inum->no_addr = gfs2_alloc_di(dip, generation); + *no_addr = gfs2_alloc_di(dip, generation); gfs2_trans_end(sdp); @@ -760,7 +752,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, goto fail_quota_locks; } - error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); + error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); if (error) goto fail_end_trans; @@ -844,7 +836,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, struct gfs2_inode *dip = ghs->gh_gl->gl_object; struct inode *dir = &dip->i_inode; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); - struct gfs2_inum_host inum; + struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; int error; u64 generation; @@ -864,7 +856,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, if (error) goto fail_gunlock; - error = alloc_dinode(dip, &inum, &generation); + error = alloc_dinode(dip, &inum.no_addr, &generation); if (error) goto fail_gunlock; @@ -877,7 +869,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, if (error) goto fail_gunlock2; - inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode)); + inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode)); if (IS_ERR(inode)) goto fail_gunlock2; @@ -976,10 +968,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, */ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, - struct gfs2_inode *ip) + const struct gfs2_inode *ip) { - struct gfs2_inum_host inum; - unsigned int type; int error; if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) @@ -997,18 +987,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, if (error) return error; - error = gfs2_dir_search(&dip->i_inode, name, &inum, &type); + error = gfs2_dir_check(&dip->i_inode, name, ip); if (error) return error; - if (!gfs2_inum_equal(&inum, &ip->i_num)) - return -ENOENT; - - if (IF2DT(ip->i_inode.i_mode) != type) { - gfs2_consist_inode(dip); - return -EIO; - } - return 0; } diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index b57f448b15bc..05fc095d8540 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -10,17 +10,17 @@ #ifndef __INODE_DOT_H__ #define __INODE_DOT_H__ -static inline int gfs2_is_stuffed(struct gfs2_inode *ip) +static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) { return !ip->i_di.di_height; } -static inline int gfs2_is_jdata(struct gfs2_inode *ip) +static inline int gfs2_is_jdata(const struct gfs2_inode *ip) { return ip->i_di.di_flags & GFS2_DIF_JDATA; } -static inline int gfs2_is_dir(struct gfs2_inode *ip) +static inline int gfs2_is_dir(const struct gfs2_inode *ip) { return S_ISDIR(ip->i_inode.i_mode); } @@ -32,9 +32,15 @@ static inline void gfs2_set_inode_blocks(struct inode *inode) (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); } +static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, + u64 no_formal_ino) +{ + return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; +} + void gfs2_inode_attr_in(struct gfs2_inode *ip); -struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); -struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); +struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type); +struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); int gfs2_inode_refresh(struct gfs2_inode *ip); @@ -47,7 +53,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, struct gfs2_inode *ip); int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, - struct gfs2_inode *ip); + const struct gfs2_inode *ip); int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); int gfs2_glock_nq_atime(struct gfs2_holder *gh); diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index e037425bc042..527bf19d9690 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h @@ -63,7 +63,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, struct buffer_head **bhp) { - return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp); + return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp); } struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c index d9ecfd23a49e..cd4cf055c37d 100644 --- a/fs/gfs2/ondisk.c +++ b/fs/gfs2/ondisk.c @@ -33,26 +33,10 @@ * first arg: the cpu-order structure */ -void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf) +void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent) { - const struct gfs2_inum *str = buf; - - no->no_formal_ino = be64_to_cpu(str->no_formal_ino); - no->no_addr = be64_to_cpu(str->no_addr); -} - -void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf) -{ - struct gfs2_inum *str = buf; - - str->no_formal_ino = cpu_to_be64(no->no_formal_ino); - str->no_addr = cpu_to_be64(no->no_addr); -} - -static void gfs2_inum_print(const struct gfs2_inum_host *no) -{ - printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); - printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); + dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); + dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); } static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) @@ -74,9 +58,10 @@ void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); sb->sb_bsize = be32_to_cpu(str->sb_bsize); sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); - - gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir); - gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir); + sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); + sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); + sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); + sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); @@ -146,9 +131,8 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) str->di_header.__pad0 = 0; str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); str->di_header.__pad1 = 0; - - gfs2_inum_out(&ip->i_num, &str->di_num); - + str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); + str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); str->di_mode = cpu_to_be32(ip->i_inode.i_mode); str->di_uid = cpu_to_be32(ip->i_inode.i_uid); str->di_gid = cpu_to_be32(ip->i_inode.i_gid); @@ -178,7 +162,8 @@ void gfs2_dinode_print(const struct gfs2_inode *ip) { const struct gfs2_dinode_host *di = &ip->i_di; - gfs2_inum_print(&ip->i_num); + printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)ip->i_no_formal_ino); + printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)ip->i_no_addr); printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 4913ef57b095..fb84478e1df6 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -757,8 +757,8 @@ static unsigned limit = 0; return; fs_warn(sdp, "ip = %llu %llu\n", - (unsigned long long)ip->i_num.no_formal_ino, - (unsigned long long)ip->i_num.no_addr); + (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr); for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) fs_warn(sdp, "ip->i_cache[%u] = %s\n", diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index a6fdc52f554a..793e334d098e 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c @@ -21,6 +21,7 @@ #include "glock.h" #include "ops_dentry.h" #include "util.h" +#include "inode.h" /** * gfs2_drevalidate - Check directory lookup consistency @@ -40,14 +41,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) struct gfs2_inode *dip = GFS2_I(parent->d_inode); struct inode *inode = dentry->d_inode; struct gfs2_holder d_gh; - struct gfs2_inode *ip; - struct gfs2_inum_host inum; - unsigned int type; + struct gfs2_inode *ip = NULL; int error; int had_lock=0; - if (inode && is_bad_inode(inode)) - goto invalid; + if (inode) { + if (is_bad_inode(inode)) + goto invalid; + ip = GFS2_I(inode); + } if (sdp->sd_args.ar_localcaching) goto valid; @@ -59,7 +61,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) goto fail; } - error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type); + error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip); switch (error) { case 0: if (!inode) @@ -73,16 +75,6 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) goto fail_gunlock; } - ip = GFS2_I(inode); - - if (!gfs2_inum_equal(&ip->i_num, &inum)) - goto invalid_gunlock; - - if (IF2DT(ip->i_inode.i_mode) != type) { - gfs2_consist_inode(dip); - goto fail_gunlock; - } - valid_gunlock: if (!had_lock) gfs2_glock_dq_uninit(&d_gh); diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index aad918337a46..51a8a14deb29 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c @@ -75,10 +75,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, (connectable && *len < GFS2_LARGE_FH_SIZE)) return 255; - fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); - fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); - fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); - fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); + fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); + fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); + fh[2] = cpu_to_be32(ip->i_no_addr >> 32); + fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); *len = GFS2_SMALL_FH_SIZE; if (!connectable || inode == sb->s_root->d_inode) @@ -90,10 +90,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, igrab(inode); spin_unlock(&dentry->d_lock); - fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); - fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); - fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); - fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); + fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); + fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); + fh[6] = cpu_to_be32(ip->i_no_addr >> 32); + fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); fh[8] = cpu_to_be32(inode->i_mode); fh[9] = 0; /* pad to double word */ @@ -144,7 +144,8 @@ static int gfs2_get_name(struct dentry *parent, char *name, ip = GFS2_I(inode); *name = 0; - gnfd.inum = ip->i_num; + gnfd.inum.no_addr = ip->i_no_addr; + gnfd.inum.no_formal_ino = ip->i_no_formal_ino; gnfd.name = name; error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); @@ -202,9 +203,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) /* System files? */ - inode = gfs2_ilookup(sb, inum); + inode = gfs2_ilookup(sb, inum->no_addr); if (inode) { - if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { iput(inode); return ERR_PTR(-ESTALE); } @@ -236,7 +237,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) gfs2_glock_dq_uninit(&rgd_gh); gfs2_glock_dq_uninit(&ri_gh); - inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); + inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode); if (!inode) goto fail; if (IS_ERR(inode)) { @@ -249,6 +250,10 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) iput(inode); goto fail; } + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { + iput(inode); + goto fail; + } error = -EIO; if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 064df8804582..550032c3b5f7 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -502,7 +502,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); struct lm_lockname name = - { .ln_number = ip->i_num.no_addr, + { .ln_number = ip->i_no_addr, .ln_type = LM_TYPE_PLOCK }; if (!(fl->fl_flags & FL_POSIX)) @@ -557,7 +557,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) gfs2_glock_dq_uninit(fl_gh); } else { error = gfs2_glock_get(GFS2_SB(&ip->i_inode), - ip->i_num.no_addr, &gfs2_flock_glops, + ip->i_no_addr, &gfs2_flock_glops, CREATE, &gl); if (error) goto out; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 2c5f8e7def0d..c682371717ff 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -236,17 +236,17 @@ fail: return error; } -static struct inode *gfs2_lookup_root(struct super_block *sb, - struct gfs2_inum_host *inum) +static inline struct inode *gfs2_lookup_root(struct super_block *sb, + u64 no_addr) { - return gfs2_inode_lookup(sb, inum, DT_DIR); + return gfs2_inode_lookup(sb, no_addr, DT_DIR); } static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) { struct super_block *sb = sdp->sd_vfs; struct gfs2_holder sb_gh; - struct gfs2_inum_host *inum; + u64 no_addr; struct inode *inode; int error = 0; @@ -289,10 +289,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); /* Get the root inode */ - inum = &sdp->sd_sb.sb_root_dir; + no_addr = sdp->sd_sb.sb_root_dir.no_addr; if (sb->s_type == &gfs2meta_fs_type) - inum = &sdp->sd_sb.sb_master_dir; - inode = gfs2_lookup_root(sb, inum); + no_addr = sdp->sd_sb.sb_master_dir.no_addr; + inode = gfs2_lookup_root(sb, no_addr); if (IS_ERR(inode)) { error = PTR_ERR(inode); fs_err(sdp, "can't read in root inode: %d\n", error); @@ -449,7 +449,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) if (undo) goto fail_qinode; - inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir); + inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr); if (IS_ERR(inode)) { error = PTR_ERR(inode); fs_err(sdp, "can't read in master directory: %d\n", error); diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index d85f6e05cb95..f8ecfec4064b 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -157,7 +157,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, if (error) goto out_gunlock; - error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL); + error = gfs2_dir_check(dir, &dentry->d_name, NULL); switch (error) { case -ENOENT: break; @@ -217,8 +217,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, goto out_ipres; } - error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, - IF2DT(inode->i_mode)); + error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); if (error) goto out_end_trans; @@ -275,7 +274,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); @@ -420,7 +419,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); - gfs2_inum_out(&dip->i_num, &dent->de_inum); + gfs2_inum_out(dip, dent); dent->de_type = cpu_to_be16(DT_DIR); gfs2_dinode_out(ip, di); @@ -472,7 +471,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); error = gfs2_glock_nq_m(3, ghs); @@ -614,7 +613,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, * this is the case of the target file already existing * so we unlink before doing the rename */ - nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr); + nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); if (nrgd) gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); } @@ -653,7 +652,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, if (error) goto out_gunlock; - error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL); + error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); switch (error) { case -ENOENT: error = 0; @@ -750,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, if (error) goto out_end_trans; - error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR); + error = gfs2_dir_mvino(ip, &name, nip, DT_DIR); if (error) goto out_end_trans; } else { @@ -768,8 +767,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, if (error) goto out_end_trans; - error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, - IF2DT(ip->i_inode.i_mode)); + error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); if (error) goto out_end_trans; diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index a62c0f2d26d3..30eb428065c5 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1470,7 +1470,7 @@ void gfs2_unlink_di(struct inode *inode) struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_rgrpd *rgd; - u64 blkno = ip->i_num.no_addr; + u64 blkno = ip->i_no_addr; rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); if (!rgd) @@ -1505,9 +1505,9 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) { - gfs2_free_uninit_di(rgd, ip->i_num.no_addr); + gfs2_free_uninit_di(rgd, ip->i_no_addr); gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); - gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); + gfs2_meta_wipe(ip, ip->i_no_addr, 1); } /** diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 4fdda974dc83..faccffd19907 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -360,7 +360,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) name.len = sprintf(buf, "journal%u", sdp->sd_journals); name.hash = gfs2_disk_hash(name.name, name.len); - error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL); + error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); if (error == -ENOENT) { error = 0; break; diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 601eaa1b9ed6..3f5edc54e80a 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -115,8 +115,8 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide, "GFS2: fsid=%s: inode = %llu %llu\n" "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", sdp->sd_fsname, - sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino, - (unsigned long long)ip->i_num.no_addr, + sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr, sdp->sd_fsname, function, file, line); return rv; } diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 8b7e4c1e32ae..a82ec8c62eff 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -59,13 +59,6 @@ struct gfs2_inum_host { __u64 no_addr; }; -static inline int gfs2_inum_equal(const struct gfs2_inum_host *ino1, - const struct gfs2_inum_host *ino2) -{ - return ino1->no_formal_ino == ino2->no_formal_ino && - ino1->no_addr == ino2->no_addr; -} - /* * Generic metadata head structure * Every inplace buffer logged in the journal must start with this. @@ -509,9 +502,9 @@ struct gfs2_quota_change_host { #ifdef __KERNEL__ /* Translation functions */ +struct gfs2_inode; -extern void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf); -extern void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf); +extern void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent); extern void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf); extern void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf); extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf); From 2a87ab080607d009b8b2a8706f4e27d70402ca9c Mon Sep 17 00:00:00 2001 From: Abhijith Das Date: Wed, 16 May 2007 17:02:19 -0500 Subject: [PATCH 139/551] [GFS2] Quotas non-functional - fix bug This patch fixes an error in the quota code where a 'struct gfs2_quota_lvb*' was being passed to gfs2_adjust_quota() instead of a 'struct gfs2_quota_data*'. Also moved 'struct gfs2_quota_lvb' from fs/gfs2/incore.h to include/linux/gfs2_ondisk.h as per Steve's suggestion. Signed-off-by: Abhijith Das Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 8 -------- fs/gfs2/quota.c | 4 +++- include/linux/gfs2_ondisk.h | 8 ++++++++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 00c3004a4c22..b2079fcd2513 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -275,14 +275,6 @@ enum { QDF_LOCKED = 2, }; -struct gfs2_quota_lvb { - __be32 qb_magic; - u32 __pad; - __be64 qb_limit; /* Hard limit of # blocks to alloc */ - __be64 qb_warn; /* Warn user when alloc is above this # */ - __be64 qb_value; /* Current # blocks allocated */ -}; - struct gfs2_quota_data { struct list_head qd_list; unsigned int qd_count; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c186857e48a8..fcd3ee2c5b96 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -627,6 +627,8 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, err = 0; qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC); qd->qd_qb.qb_value = cpu_to_be64(value); + ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC); + ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value); unlock: unlock_page(page); page_cache_release(page); @@ -709,7 +711,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) offset = qd2offset(qd); error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, (struct gfs2_quota_data *) - qd->qd_gl->gl_lvb); + qd); if (error) goto out_end_trans; diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index a82ec8c62eff..028f9810ba07 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -500,6 +500,14 @@ struct gfs2_quota_change_host { __u32 qc_id; }; +struct gfs2_quota_lvb { + __be32 qb_magic; + u32 __pad; + __be64 qb_limit; /* Hard limit of # blocks to alloc */ + __be64 qb_warn; /* Warn user when alloc is above this # */ + __be64 qb_value; /* Current # blocks allocated */ +}; + #ifdef __KERNEL__ /* Translation functions */ struct gfs2_inode; From 916297aad5de2363dccd531873eda55d4d6afb57 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 16 May 2007 15:56:13 -0400 Subject: [PATCH 140/551] [DLM] keep dlm from panicing when traversing rsb list in debugfs This problem was originally reported against GFS6.1, but the same issue exists in upstream DLM. This patch keeps the rsb iterator assigning under the rsbtbl list lock. Each time we process an rsb we grab a reference to it to make sure it is not freed out from underneath us, and then put it when we get the next rsb in the list or move onto another list. Signed-off-by: Josef Bacik Signed-off-by: Steven Whitehouse --- fs/dlm/debug_fs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 61ba670b9e02..9e27a1675794 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -17,6 +17,7 @@ #include #include "dlm_internal.h" +#include "lock.h" #define DLM_DEBUG_BUF_LEN 4096 static char debug_buf[DLM_DEBUG_BUF_LEN]; @@ -166,6 +167,9 @@ static int rsb_iter_next(struct rsb_iter *ri) read_lock(&ls->ls_rsbtbl[i].lock); if (!list_empty(&ls->ls_rsbtbl[i].list)) { ri->next = ls->ls_rsbtbl[i].list.next; + ri->rsb = list_entry(ri->next, struct dlm_rsb, + res_hashchain); + dlm_hold_rsb(ri->rsb); read_unlock(&ls->ls_rsbtbl[i].lock); break; } @@ -176,6 +180,7 @@ static int rsb_iter_next(struct rsb_iter *ri) if (ri->entry >= ls->ls_rsbtbl_size) return 1; } else { + struct dlm_rsb *old = ri->rsb; i = ri->entry; read_lock(&ls->ls_rsbtbl[i].lock); ri->next = ri->next->next; @@ -184,11 +189,13 @@ static int rsb_iter_next(struct rsb_iter *ri) ri->next = NULL; ri->entry++; read_unlock(&ls->ls_rsbtbl[i].lock); + dlm_put_rsb(old); goto top; } + ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain); read_unlock(&ls->ls_rsbtbl[i].lock); + dlm_put_rsb(old); } - ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain); return 0; } From 85e86edf951a8a39954c0ba1edbe4a58827dcd5c Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 08:58:15 -0500 Subject: [PATCH 141/551] [DLM] block scand during recovery [1/6] Don't let dlm_scand run during recovery since it may try to do a resource directory removal while the directory nodes are changing. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lock.c | 47 +++++++++++++++++++++++----------------------- fs/dlm/lock.h | 2 ++ fs/dlm/lockspace.c | 8 ++++++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index d8d6e729f96b..09668ec2e279 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -194,17 +194,17 @@ void dlm_dump_rsb(struct dlm_rsb *r) /* Threads cannot use the lockspace while it's being recovered */ -static inline void lock_recovery(struct dlm_ls *ls) +static inline void dlm_lock_recovery(struct dlm_ls *ls) { down_read(&ls->ls_in_recovery); } -static inline void unlock_recovery(struct dlm_ls *ls) +void dlm_unlock_recovery(struct dlm_ls *ls) { up_read(&ls->ls_in_recovery); } -static inline int lock_recovery_try(struct dlm_ls *ls) +int dlm_lock_recovery_try(struct dlm_ls *ls) { return down_read_trylock(&ls->ls_in_recovery); } @@ -985,11 +985,10 @@ void dlm_scan_rsbs(struct dlm_ls *ls) { int i; - if (dlm_locking_stopped(ls)) - return; - for (i = 0; i < ls->ls_rsbtbl_size; i++) { shrink_bucket(ls, i); + if (dlm_locking_stopped(ls)) + break; cond_resched(); } } @@ -2274,7 +2273,7 @@ int dlm_lock(dlm_lockspace_t *lockspace, if (!ls) return -EINVAL; - lock_recovery(ls); + dlm_lock_recovery(ls); if (convert) error = find_lkb(ls, lksb->sb_lkid, &lkb); @@ -2302,7 +2301,7 @@ int dlm_lock(dlm_lockspace_t *lockspace, if (error == -EAGAIN) error = 0; out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); dlm_put_lockspace(ls); return error; } @@ -2322,7 +2321,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace, if (!ls) return -EINVAL; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -2344,7 +2343,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace, out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); dlm_put_lockspace(ls); return error; } @@ -3424,7 +3423,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) } } - if (lock_recovery_try(ls)) + if (dlm_lock_recovery_try(ls)) break; schedule(); } @@ -3503,7 +3502,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) log_error(ls, "unknown message type %d", ms->m_type); } - unlock_recovery(ls); + dlm_unlock_recovery(ls); out: dlm_put_lockspace(ls); dlm_astd_wake(); @@ -4040,7 +4039,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, struct dlm_args args; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = create_lkb(ls, &lkb); if (error) { @@ -4094,7 +4093,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); spin_unlock(&ua->proc->locks_spin); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); return error; } @@ -4106,7 +4105,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4146,7 +4145,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } @@ -4159,7 +4158,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4194,7 +4193,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } @@ -4207,7 +4206,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4231,7 +4230,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } @@ -4314,7 +4313,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) { struct dlm_lkb *lkb, *safe; - lock_recovery(ls); + dlm_lock_recovery(ls); while (1) { lkb = del_proc_lock(ls, proc); @@ -4347,7 +4346,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) } mutex_unlock(&ls->ls_clear_proc_locks); - unlock_recovery(ls); + dlm_unlock_recovery(ls); } static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) @@ -4429,12 +4428,12 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc, if (nodeid != dlm_our_nodeid()) { error = send_purge(ls, nodeid, pid); } else { - lock_recovery(ls); + dlm_lock_recovery(ls); if (pid == current->pid) purge_proc_locks(ls, proc); else do_purge(ls, nodeid, pid); - unlock_recovery(ls); + dlm_unlock_recovery(ls); } return error; } diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 64fc4ec40668..19403aa08739 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -24,6 +24,8 @@ void dlm_put_rsb(struct dlm_rsb *r); void dlm_hold_rsb(struct dlm_rsb *r); int dlm_put_lkb(struct dlm_lkb *lkb); void dlm_scan_rsbs(struct dlm_ls *ls); +int dlm_lock_recovery_try(struct dlm_ls *ls); +void dlm_unlock_recovery(struct dlm_ls *ls); int dlm_purge_locks(struct dlm_ls *ls); void dlm_purge_mstcpy_locks(struct dlm_rsb *r); diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a677b2a5eed4..414a108df934 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -234,8 +234,12 @@ static int dlm_scand(void *data) struct dlm_ls *ls; while (!kthread_should_stop()) { - list_for_each_entry(ls, &lslist, ls_list) - dlm_scan_rsbs(ls); + list_for_each_entry(ls, &lslist, ls_list) { + if (dlm_lock_recovery_try(ls)) { + dlm_scan_rsbs(ls); + dlm_unlock_recovery(ls); + } + } schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); } return 0; From 3ae1acf93a21512512f8a78430fcde5992dd208e Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 08:59:31 -0500 Subject: [PATCH 142/551] [DLM] add lock timeouts and warnings [2/6] New features: lock timeouts and time warnings. If the DLM_LKF_TIMEOUT flag is set, then the request/conversion will be canceled after waiting the specified number of centiseconds (specified per lock). This feature is only available for locks requested through libdlm (can be enabled for kernel dlm users if there's a use for it.) If the new DLM_LSFL_TIMEWARN flag is set when creating the lockspace, then a warning message will be sent to userspace (using genetlink) after a request/conversion has been waiting for a given number of centiseconds (configurable per node). The time warnings will be used in the future to do deadlock detection in userspace. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/Makefile | 1 + fs/dlm/config.c | 8 +- fs/dlm/config.h | 1 + fs/dlm/dlm_internal.h | 10 +++ fs/dlm/lock.c | 146 ++++++++++++++++++++++++++++++++- fs/dlm/lock.h | 4 +- fs/dlm/lockspace.c | 10 ++- fs/dlm/main.c | 11 ++- fs/dlm/member.c | 5 +- fs/dlm/netlink.c | 155 ++++++++++++++++++++++++++++++++++++ fs/dlm/recoverd.c | 4 +- fs/dlm/user.c | 2 +- include/linux/Kbuild | 1 + include/linux/dlm.h | 7 +- include/linux/dlm_netlink.h | 56 +++++++++++++ 15 files changed, 409 insertions(+), 12 deletions(-) create mode 100644 fs/dlm/netlink.c create mode 100644 include/linux/dlm_netlink.h diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile index 604cf7dc5f39..d248e60951ba 100644 --- a/fs/dlm/Makefile +++ b/fs/dlm/Makefile @@ -8,6 +8,7 @@ dlm-y := ast.o \ member.o \ memory.o \ midcomms.o \ + netlink.o \ lowcomms.o \ rcom.o \ recover.o \ diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 5a3d390cc826..2909abf1bbc3 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -90,6 +90,7 @@ struct cluster { unsigned int cl_scan_secs; unsigned int cl_log_debug; unsigned int cl_protocol; + unsigned int cl_timewarn_cs; }; enum { @@ -103,6 +104,7 @@ enum { CLUSTER_ATTR_SCAN_SECS, CLUSTER_ATTR_LOG_DEBUG, CLUSTER_ATTR_PROTOCOL, + CLUSTER_ATTR_TIMEWARN_CS, }; struct cluster_attribute { @@ -162,6 +164,7 @@ CLUSTER_ATTR(toss_secs, 1); CLUSTER_ATTR(scan_secs, 1); CLUSTER_ATTR(log_debug, 0); CLUSTER_ATTR(protocol, 0); +CLUSTER_ATTR(timewarn_cs, 1); static struct configfs_attribute *cluster_attrs[] = { [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, @@ -174,6 +177,7 @@ static struct configfs_attribute *cluster_attrs[] = { [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr, [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, + [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, NULL, }; @@ -916,6 +920,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num) #define DEFAULT_SCAN_SECS 5 #define DEFAULT_LOG_DEBUG 0 #define DEFAULT_PROTOCOL 0 +#define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ struct dlm_config_info dlm_config = { .ci_tcp_port = DEFAULT_TCP_PORT, @@ -927,6 +932,7 @@ struct dlm_config_info dlm_config = { .ci_toss_secs = DEFAULT_TOSS_SECS, .ci_scan_secs = DEFAULT_SCAN_SECS, .ci_log_debug = DEFAULT_LOG_DEBUG, - .ci_protocol = DEFAULT_PROTOCOL + .ci_protocol = DEFAULT_PROTOCOL, + .ci_timewarn_cs = DEFAULT_TIMEWARN_CS }; diff --git a/fs/dlm/config.h b/fs/dlm/config.h index 967cc3d72e5e..a3170fe22090 100644 --- a/fs/dlm/config.h +++ b/fs/dlm/config.h @@ -27,6 +27,7 @@ struct dlm_config_info { int ci_scan_secs; int ci_log_debug; int ci_protocol; + int ci_timewarn_cs; }; extern struct dlm_config_info dlm_config; diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 30994d68f6a0..65a5fc076b8a 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -213,8 +213,10 @@ struct dlm_args { #define DLM_IFL_OVERLAP_UNLOCK 0x00080000 #define DLM_IFL_OVERLAP_CANCEL 0x00100000 #define DLM_IFL_ENDOFLIFE 0x00200000 +#define DLM_IFL_WATCH_TIMEWARN 0x00400000 #define DLM_IFL_USER 0x00000001 #define DLM_IFL_ORPHAN 0x00000002 +#define DLM_IFL_TIMEOUT_CANCEL 0x00000004 struct dlm_lkb { struct dlm_rsb *lkb_resource; /* the rsb */ @@ -243,6 +245,9 @@ struct dlm_lkb { struct list_head lkb_wait_reply; /* waiting for remote reply */ struct list_head lkb_astqueue; /* need ast to be sent */ struct list_head lkb_ownqueue; /* list of locks for a process */ + struct list_head lkb_time_list; + unsigned long lkb_timestamp; + unsigned long lkb_timeout_cs; char *lkb_lvbptr; struct dlm_lksb *lkb_lksb; /* caller's status block */ @@ -447,6 +452,9 @@ struct dlm_ls { struct mutex ls_orphans_mutex; struct list_head ls_orphans; + struct mutex ls_timeout_mutex; + struct list_head ls_timeout; + struct list_head ls_nodes; /* current nodes in ls */ struct list_head ls_nodes_gone; /* dead node list, recovery */ int ls_num_nodes; /* number of nodes in ls */ @@ -472,6 +480,7 @@ struct dlm_ls { struct task_struct *ls_recoverd_task; struct mutex ls_recoverd_active; spinlock_t ls_recover_lock; + unsigned long ls_recover_begin; /* jiffies timestamp */ uint32_t ls_recover_status; /* DLM_RS_ */ uint64_t ls_recover_seq; struct dlm_recover *ls_recover_args; @@ -501,6 +510,7 @@ struct dlm_ls { #define LSFL_RCOM_READY 3 #define LSFL_RCOM_WAIT 4 #define LSFL_UEVENT_WAIT 5 +#define LSFL_TIMEWARN 6 /* much of this is just saving user space pointers associated with the lock that we pass back to the user lib with an ast */ diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 09668ec2e279..ab986dfbe6d3 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -82,10 +82,13 @@ static int send_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int mode); static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb); static int send_remove(struct dlm_rsb *r); static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); +static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, struct dlm_message *ms); static int receive_extralen(struct dlm_message *ms); static void do_purge(struct dlm_ls *ls, int nodeid, int pid); +static void del_timeout(struct dlm_lkb *lkb); +void dlm_timeout_warn(struct dlm_lkb *lkb); /* * Lock compatibilty matrix - thanks Steve @@ -286,8 +289,17 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) if (is_master_copy(lkb)) return; + del_timeout(lkb); + DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb);); + /* if the operation was a cancel, then return -DLM_ECANCEL, if a + timeout caused the cancel then return -ETIMEDOUT */ + if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) { + lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL; + rv = -ETIMEDOUT; + } + lkb->lkb_lksb->sb_status = rv; lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; @@ -581,6 +593,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) kref_init(&lkb->lkb_ref); INIT_LIST_HEAD(&lkb->lkb_ownqueue); INIT_LIST_HEAD(&lkb->lkb_rsb_lookup); + INIT_LIST_HEAD(&lkb->lkb_time_list); get_random_bytes(&bucket, sizeof(bucket)); bucket &= (ls->ls_lkbtbl_size - 1); @@ -993,6 +1006,125 @@ void dlm_scan_rsbs(struct dlm_ls *ls) } } +static void add_timeout(struct dlm_lkb *lkb) +{ + struct dlm_ls *ls = lkb->lkb_resource->res_ls; + + if (is_master_copy(lkb)) + return; + + if (lkb->lkb_exflags & DLM_LKF_TIMEOUT) + goto add_it; + + if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) && + !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { + lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN; + goto add_it; + } + return; + + add_it: + DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb);); + mutex_lock(&ls->ls_timeout_mutex); + hold_lkb(lkb); + lkb->lkb_timestamp = jiffies; + list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout); + mutex_unlock(&ls->ls_timeout_mutex); +} + +static void del_timeout(struct dlm_lkb *lkb) +{ + struct dlm_ls *ls = lkb->lkb_resource->res_ls; + + mutex_lock(&ls->ls_timeout_mutex); + if (!list_empty(&lkb->lkb_time_list)) { + list_del_init(&lkb->lkb_time_list); + unhold_lkb(lkb); + } + mutex_unlock(&ls->ls_timeout_mutex); +} + +/* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and + lkb_lksb_timeout without lock_rsb? Note: we can't lock timeout_mutex + and then lock rsb because of lock ordering in add_timeout. We may need + to specify some special timeout-related bits in the lkb that are just to + be accessed under the timeout_mutex. */ + +void dlm_scan_timeout(struct dlm_ls *ls) +{ + struct dlm_rsb *r; + struct dlm_lkb *lkb; + int do_cancel, do_warn; + + for (;;) { + if (dlm_locking_stopped(ls)) + break; + + do_cancel = 0; + do_warn = 0; + mutex_lock(&ls->ls_timeout_mutex); + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) { + + if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) && + time_after_eq(jiffies, lkb->lkb_timestamp + + lkb->lkb_timeout_cs * HZ/100)) + do_cancel = 1; + + if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) && + time_after_eq(jiffies, lkb->lkb_timestamp + + dlm_config.ci_timewarn_cs * HZ/100)) + do_warn = 1; + + if (!do_cancel && !do_warn) + continue; + hold_lkb(lkb); + break; + } + mutex_unlock(&ls->ls_timeout_mutex); + + if (!do_cancel && !do_warn) + break; + + r = lkb->lkb_resource; + hold_rsb(r); + lock_rsb(r); + + if (do_warn) { + /* clear flag so we only warn once */ + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; + if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT)) + del_timeout(lkb); + dlm_timeout_warn(lkb); + } + + if (do_cancel) { + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; + lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; + del_timeout(lkb); + _cancel_lock(r, lkb); + } + + unlock_rsb(r); + unhold_rsb(r); + dlm_put_lkb(lkb); + } +} + +/* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping + dlm_recoverd before checking/setting ls_recover_begin. */ + +void dlm_adjust_timeouts(struct dlm_ls *ls) +{ + struct dlm_lkb *lkb; + long adj = jiffies - ls->ls_recover_begin; + + ls->ls_recover_begin = 0; + mutex_lock(&ls->ls_timeout_mutex); + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) + lkb->lkb_timestamp += adj; + mutex_unlock(&ls->ls_timeout_mutex); +} + /* lkb is master or local copy */ static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) @@ -1902,6 +2034,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args) if (is_overlap(lkb)) goto out; + /* don't let scand try to do a cancel */ + del_timeout(lkb); + if (lkb->lkb_flags & DLM_IFL_RESEND) { lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL; rv = -EBUSY; @@ -1933,6 +2068,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args) if (is_overlap_unlock(lkb)) goto out; + /* don't let scand try to do a cancel */ + del_timeout(lkb); + if (lkb->lkb_flags & DLM_IFL_RESEND) { lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK; rv = -EBUSY; @@ -1993,6 +2131,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) error = -EINPROGRESS; add_lkb(r, lkb, DLM_LKSTS_WAITING); send_blocking_asts(r, lkb); + add_timeout(lkb); goto out; } @@ -2040,6 +2179,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) del_lkb(r, lkb); add_lkb(r, lkb, DLM_LKSTS_CONVERT); send_blocking_asts(r, lkb); + add_timeout(lkb); goto out; } @@ -3110,9 +3250,10 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms) lkb->lkb_remid = ms->m_lkid; if (is_altmode(lkb)) munge_altmode(lkb, ms); - if (result) + if (result) { add_lkb(r, lkb, DLM_LKSTS_WAITING); - else { + add_timeout(lkb); + } else { grant_lock_pc(r, lkb, ms); queue_cast(r, lkb, 0); } @@ -3178,6 +3319,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, munge_demoted(lkb, ms); del_lkb(r, lkb); add_lkb(r, lkb, DLM_LKSTS_CONVERT); + add_timeout(lkb); break; case 0: diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 19403aa08739..6b5b71f0e9dd 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -26,6 +26,8 @@ int dlm_put_lkb(struct dlm_lkb *lkb); void dlm_scan_rsbs(struct dlm_ls *ls); int dlm_lock_recovery_try(struct dlm_ls *ls); void dlm_unlock_recovery(struct dlm_ls *ls); +void dlm_scan_timeout(struct dlm_ls *ls); +void dlm_adjust_timeouts(struct dlm_ls *ls); int dlm_purge_locks(struct dlm_ls *ls); void dlm_purge_mstcpy_locks(struct dlm_rsb *r); diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 414a108df934..339a204d7479 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -237,6 +237,7 @@ static int dlm_scand(void *data) list_for_each_entry(ls, &lslist, ls_list) { if (dlm_lock_recovery_try(ls)) { dlm_scan_rsbs(ls); + dlm_scan_timeout(ls); dlm_unlock_recovery(ls); } } @@ -421,11 +422,16 @@ static int new_lockspace(char *name, int namelen, void **lockspace, goto out; memcpy(ls->ls_name, name, namelen); ls->ls_namelen = namelen; - ls->ls_exflags = flags; ls->ls_lvblen = lvblen; ls->ls_count = 0; ls->ls_flags = 0; + /* ls_exflags are forced to match among nodes, and we don't + need to require all nodes to have TIMEWARN active */ + if (flags & DLM_LSFL_TIMEWARN) + set_bit(LSFL_TIMEWARN, &ls->ls_flags); + ls->ls_exflags = (flags & ~DLM_LSFL_TIMEWARN); + size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; @@ -465,6 +471,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, mutex_init(&ls->ls_waiters_mutex); INIT_LIST_HEAD(&ls->ls_orphans); mutex_init(&ls->ls_orphans_mutex); + INIT_LIST_HEAD(&ls->ls_timeout); + mutex_init(&ls->ls_timeout_mutex); INIT_LIST_HEAD(&ls->ls_nodes); INIT_LIST_HEAD(&ls->ls_nodes_gone); diff --git a/fs/dlm/main.c b/fs/dlm/main.c index 162fbae58fe5..eca2907f2386 100644 --- a/fs/dlm/main.c +++ b/fs/dlm/main.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -25,6 +25,8 @@ void dlm_unregister_debugfs(void); static inline int dlm_register_debugfs(void) { return 0; } static inline void dlm_unregister_debugfs(void) { } #endif +int dlm_netlink_init(void); +void dlm_netlink_exit(void); static int __init init_dlm(void) { @@ -50,10 +52,16 @@ static int __init init_dlm(void) if (error) goto out_debug; + error = dlm_netlink_init(); + if (error) + goto out_user; + printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); return 0; + out_user: + dlm_user_exit(); out_debug: dlm_unregister_debugfs(); out_config: @@ -68,6 +76,7 @@ static int __init init_dlm(void) static void __exit exit_dlm(void) { + dlm_netlink_exit(); dlm_user_exit(); dlm_config_exit(); dlm_memory_exit(); diff --git a/fs/dlm/member.c b/fs/dlm/member.c index 85e2897bd740..f08faec3d854 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -284,6 +284,9 @@ int dlm_ls_stop(struct dlm_ls *ls) dlm_recoverd_suspend(ls); ls->ls_recover_status = 0; dlm_recoverd_resume(ls); + + if (!ls->ls_recover_begin) + ls->ls_recover_begin = jiffies; return 0; } diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c new file mode 100644 index 000000000000..804b32cd22c1 --- /dev/null +++ b/fs/dlm/netlink.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + */ + +#include +#include +#include + +#include "dlm_internal.h" + +static uint32_t dlm_nl_seqnum; +static uint32_t listener_nlpid; + +static struct genl_family family = { + .id = GENL_ID_GENERATE, + .name = DLM_GENL_NAME, + .version = DLM_GENL_VERSION, +}; + +static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size) +{ + struct sk_buff *skb; + void *data; + + skb = genlmsg_new(size, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + /* add the message headers */ + data = genlmsg_put(skb, 0, dlm_nl_seqnum++, &family, 0, cmd); + if (!data) { + nlmsg_free(skb); + return -EINVAL; + } + + *skbp = skb; + return 0; +} + +static struct dlm_lock_data *mk_data(struct sk_buff *skb) +{ + struct nlattr *ret; + + ret = nla_reserve(skb, DLM_TYPE_LOCK, sizeof(struct dlm_lock_data)); + if (!ret) + return NULL; + return nla_data(ret); +} + +static int send_data(struct sk_buff *skb) +{ + struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); + void *data = genlmsg_data(genlhdr); + int rv; + + rv = genlmsg_end(skb, data); + if (rv < 0) { + nlmsg_free(skb); + return rv; + } + + return genlmsg_unicast(skb, listener_nlpid); +} + +static int user_cmd(struct sk_buff *skb, struct genl_info *info) +{ + listener_nlpid = info->snd_pid; + printk("user_cmd nlpid %u\n", listener_nlpid); + return 0; +} + +static struct genl_ops dlm_nl_ops = { + .cmd = DLM_CMD_HELLO, + .doit = user_cmd, +}; + +int dlm_netlink_init(void) +{ + int rv; + + rv = genl_register_family(&family); + if (rv) + return rv; + + rv = genl_register_ops(&family, &dlm_nl_ops); + if (rv < 0) + goto err; + return 0; + err: + genl_unregister_family(&family); + return rv; +} + +void dlm_netlink_exit(void) +{ + genl_unregister_ops(&family, &dlm_nl_ops); + genl_unregister_family(&family); +} + +static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) +{ + struct dlm_rsb *r = lkb->lkb_resource; + struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; + + memset(data, 0, sizeof(struct dlm_lock_data)); + + data->version = DLM_LOCK_DATA_VERSION; + data->nodeid = lkb->lkb_nodeid; + data->ownpid = lkb->lkb_ownpid; + data->id = lkb->lkb_id; + data->remid = lkb->lkb_remid; + data->status = lkb->lkb_status; + data->grmode = lkb->lkb_grmode; + data->rqmode = lkb->lkb_rqmode; + data->timestamp = lkb->lkb_timestamp; + if (ua) + data->xid = ua->xid; + if (r) { + data->lockspace_id = r->res_ls->ls_global_id; + data->resource_namelen = r->res_length; + memcpy(data->resource_name, r->res_name, r->res_length); + } +} + +void dlm_timeout_warn(struct dlm_lkb *lkb) +{ + struct dlm_lock_data *data; + struct sk_buff *send_skb; + size_t size; + int rv; + + log_debug(lkb->lkb_resource->res_ls, "timeout_warn %x", lkb->lkb_id); + + size = nla_total_size(sizeof(struct dlm_lock_data)) + + nla_total_size(0); /* why this? */ + + rv = prepare_data(DLM_CMD_TIMEOUT, &send_skb, size); + if (rv < 0) + return; + + data = mk_data(send_skb); + if (!data) { + nlmsg_free(send_skb); + return; + } + + fill_data(data, lkb); + + send_data(send_skb); +} + diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 3cb636d60249..66575997861c 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -190,6 +190,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) dlm_clear_members_gone(ls); + dlm_adjust_timeouts(ls); + error = enable_locking(ls, rv->seq); if (error) { log_debug(ls, "enable_locking failed %d", error); diff --git a/fs/dlm/user.c b/fs/dlm/user.c index b0201ec325a7..c7612da5b617 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -348,7 +348,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params) return -EPERM; error = dlm_new_lockspace(params->name, strlen(params->name), - &lockspace, 0, DLM_USER_LVB_LEN); + &lockspace, params->flags, DLM_USER_LVB_LEN); if (error) return error; diff --git a/include/linux/Kbuild b/include/linux/Kbuild index f317c270d4bf..afae306b177c 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -49,6 +49,7 @@ header-y += consolemap.h header-y += const.h header-y += cycx_cfm.h header-y += dlm_device.h +header-y += dlm_netlink.h header-y += dm-ioctl.h header-y += dn.h header-y += dqblk_v1.h diff --git a/include/linux/dlm.h b/include/linux/dlm.h index 1b1dcb9a40bb..975f17d8aa53 100644 --- a/include/linux/dlm.h +++ b/include/linux/dlm.h @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -149,6 +149,7 @@ #define DLM_LKF_ALTPR 0x00008000 #define DLM_LKF_ALTCW 0x00010000 #define DLM_LKF_FORCEUNLOCK 0x00020000 +#define DLM_LKF_TIMEOUT 0x00040000 /* * Some return codes that are not in errno.h @@ -199,11 +200,11 @@ struct dlm_lksb { char * sb_lvbptr; }; +#define DLM_LSFL_NODIR 0x00000001 +#define DLM_LSFL_TIMEWARN 0x00000002 #ifdef __KERNEL__ -#define DLM_LSFL_NODIR 0x00000001 - /* * dlm_new_lockspace * diff --git a/include/linux/dlm_netlink.h b/include/linux/dlm_netlink.h new file mode 100644 index 000000000000..19276332707a --- /dev/null +++ b/include/linux/dlm_netlink.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + */ + +#ifndef _DLM_NETLINK_H +#define _DLM_NETLINK_H + +enum { + DLM_STATUS_WAITING = 1, + DLM_STATUS_GRANTED = 2, + DLM_STATUS_CONVERT = 3, +}; + +#define DLM_LOCK_DATA_VERSION 1 + +struct dlm_lock_data { + uint16_t version; + uint32_t lockspace_id; + int nodeid; + int ownpid; + uint32_t id; + uint32_t remid; + uint64_t xid; + int8_t status; + int8_t grmode; + int8_t rqmode; + unsigned long timestamp; + int resource_namelen; + char resource_name[DLM_RESNAME_MAXLEN]; +}; + +enum { + DLM_CMD_UNSPEC = 0, + DLM_CMD_HELLO, /* user->kernel */ + DLM_CMD_TIMEOUT, /* kernel->user */ + __DLM_CMD_MAX, +}; + +#define DLM_CMD_MAX (__DLM_CMD_MAX - 1) + +enum { + DLM_TYPE_UNSPEC = 0, + DLM_TYPE_LOCK, + __DLM_TYPE_MAX, +}; + +#define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1) + +#define DLM_GENL_VERSION 0x1 +#define DLM_GENL_NAME "DLM" + +#endif /* _DLM_NETLINK_H */ From d7db923ea4990edb5583bf54af868ba687a1bc84 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 09:00:32 -0500 Subject: [PATCH 143/551] [DLM] dlm_device interface changes [3/6] Change the user/kernel device interface used by libdlm: - Add ability for userspace to check the version of the interface. libdlm can now adapt to different versions of the kernel interface. - Increase the size of the flags passed in a lock request so all possible flags can be used from userspace. - Add an opaque "xid" value for each lock. This "transaction id" will be used later to associate locks with each other during deadlock detection. - Add a "timeout" value for each lock. This is used along with the DLM_LKF_TIMEOUT flag. Also, remove a fragment of unused code in device_read(). This patch requires updating libdlm which is backward compatible with older kernels. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/dlm_internal.h | 2 ++ fs/dlm/lock.c | 24 +++++++++-------- fs/dlm/lock.h | 6 +++-- fs/dlm/user.c | 53 +++++++++++++++++++++++++++++++------- include/linux/dlm_device.h | 21 ++++++++++----- 5 files changed, 77 insertions(+), 29 deletions(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 65a5fc076b8a..a8d6e993697c 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -151,6 +151,7 @@ struct dlm_args { void *bastaddr; int mode; struct dlm_lksb *lksb; + unsigned long timeout; }; @@ -528,6 +529,7 @@ struct dlm_user_args { void __user *castaddr; void __user *bastparam; void __user *bastaddr; + uint64_t xid; }; #define DLM_PROC_FLAGS_CLOSING 1 diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index ab986dfbe6d3..ad3797a37942 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1098,6 +1098,8 @@ void dlm_scan_timeout(struct dlm_ls *ls) } if (do_cancel) { + log_debug("timeout cancel %x node %d %s", lkb->lkb_id, + lkb->lkb_nodeid, r->res_name); lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; del_timeout(lkb); @@ -1864,7 +1866,7 @@ static void confirm_master(struct dlm_rsb *r, int error) } static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, - int namelen, uint32_t parent_lkid, void *ast, + int namelen, unsigned long timeout_cs, void *ast, void *astarg, void *bast, struct dlm_args *args) { int rv = -EINVAL; @@ -1907,10 +1909,6 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr) goto out; - /* parent/child locks not yet supported */ - if (parent_lkid) - goto out; - if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid) goto out; @@ -1922,6 +1920,7 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, args->astaddr = ast; args->astparam = (long) astarg; args->bastaddr = bast; + args->timeout = timeout_cs; args->mode = mode; args->lksb = lksb; rv = 0; @@ -1976,6 +1975,7 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, lkb->lkb_lksb = args->lksb; lkb->lkb_lvbptr = args->lksb->sb_lvbptr; lkb->lkb_ownpid = (int) current->pid; + lkb->lkb_timeout_cs = args->timeout; rv = 0; out: return rv; @@ -2423,7 +2423,7 @@ int dlm_lock(dlm_lockspace_t *lockspace, if (error) goto out; - error = set_lock_args(mode, lksb, flags, namelen, parent_lkid, ast, + error = set_lock_args(mode, lksb, flags, namelen, 0, ast, astarg, bast, &args); if (error) goto out_put; @@ -4175,7 +4175,7 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, uint32_t flags, void *name, unsigned int namelen, - uint32_t parent_lkid) + unsigned long timeout_cs) { struct dlm_lkb *lkb; struct dlm_args args; @@ -4203,7 +4203,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, When DLM_IFL_USER is set, the dlm knows that this is a userspace lock and that lkb_astparam is the dlm_user_args structure. */ - error = set_lock_args(mode, &ua->lksb, flags, namelen, parent_lkid, + error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); lkb->lkb_flags |= DLM_IFL_USER; ua->old_mode = DLM_LOCK_IV; @@ -4240,7 +4240,8 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, } int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, - int mode, uint32_t flags, uint32_t lkid, char *lvb_in) + int mode, uint32_t flags, uint32_t lkid, char *lvb_in, + unsigned long timeout_cs) { struct dlm_lkb *lkb; struct dlm_args args; @@ -4268,6 +4269,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, if (lvb_in && ua->lksb.sb_lvbptr) memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); + ua->xid = ua_tmp->xid; ua->castparam = ua_tmp->castparam; ua->castaddr = ua_tmp->castaddr; ua->bastparam = ua_tmp->bastparam; @@ -4275,8 +4277,8 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, ua->user_lksb = ua_tmp->user_lksb; ua->old_mode = lkb->lkb_grmode; - error = set_lock_args(mode, &ua->lksb, flags, 0, 0, DLM_FAKE_USER_AST, - ua, DLM_FAKE_USER_AST, &args); + error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, + DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); if (error) goto out_put; diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 6b5b71f0e9dd..99ab4635074e 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -38,9 +38,11 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc); int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc); int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, - uint32_t flags, void *name, unsigned int namelen, uint32_t parent_lkid); + uint32_t flags, void *name, unsigned int namelen, + unsigned long timeout_cs); int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, - int mode, uint32_t flags, uint32_t lkid, char *lvb_in); + int mode, uint32_t flags, uint32_t lkid, char *lvb_in, + unsigned long timeout_cs); int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid, char *lvb_in); int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, diff --git a/fs/dlm/user.c b/fs/dlm/user.c index c7612da5b617..37aad3fe8949 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -33,16 +33,17 @@ static const struct file_operations device_fops; struct dlm_lock_params32 { __u8 mode; __u8 namelen; - __u16 flags; + __u16 unused; + __u32 flags; __u32 lkid; __u32 parent; - + __u64 xid; + __u64 timeout; __u32 castparam; __u32 castaddr; __u32 bastparam; __u32 bastaddr; __u32 lksb; - char lvb[DLM_USER_LVB_LEN]; char name[0]; }; @@ -68,6 +69,7 @@ struct dlm_lksb32 { }; struct dlm_lock_result32 { + __u32 version[3]; __u32 length; __u32 user_astaddr; __u32 user_astparam; @@ -102,6 +104,8 @@ static void compat_input(struct dlm_write_request *kb, kb->i.lock.flags = kb32->i.lock.flags; kb->i.lock.lkid = kb32->i.lock.lkid; kb->i.lock.parent = kb32->i.lock.parent; + kb->i.lock.xid = kb32->i.lock.xid; + kb->i.lock.timeout = kb32->i.lock.timeout; kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam; kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr; kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam; @@ -115,6 +119,10 @@ static void compat_input(struct dlm_write_request *kb, static void compat_output(struct dlm_lock_result *res, struct dlm_lock_result32 *res32) { + res32->version[0] = res->version[0]; + res32->version[1] = res->version[1]; + res32->version[2] = res->version[2]; + res32->user_astaddr = (__u32)(long)res->user_astaddr; res32->user_astparam = (__u32)(long)res->user_astparam; res32->user_lksb = (__u32)(long)res->user_lksb; @@ -252,16 +260,18 @@ static int device_user_lock(struct dlm_user_proc *proc, ua->castaddr = params->castaddr; ua->bastparam = params->bastparam; ua->bastaddr = params->bastaddr; + ua->xid = params->xid; if (params->flags & DLM_LKF_CONVERT) error = dlm_user_convert(ls, ua, params->mode, params->flags, - params->lkid, params->lvb); + params->lkid, params->lvb, + (unsigned long) params->timeout); else { error = dlm_user_request(ls, ua, params->mode, params->flags, params->name, params->namelen, - params->parent); + (unsigned long) params->timeout); if (!error) error = ua->lksb.sb_lkid; } @@ -641,6 +651,9 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type, int struct_len; memset(&result, 0, sizeof(struct dlm_lock_result)); + result.version[0] = DLM_DEVICE_VERSION_MAJOR; + result.version[1] = DLM_DEVICE_VERSION_MINOR; + result.version[2] = DLM_DEVICE_VERSION_PATCH; memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb)); result.user_lksb = ua->user_lksb; @@ -699,6 +712,20 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type, return error; } +static int copy_version_to_user(char __user *buf, size_t count) +{ + struct dlm_device_version ver; + + memset(&ver, 0, sizeof(struct dlm_device_version)); + ver.version[0] = DLM_DEVICE_VERSION_MAJOR; + ver.version[1] = DLM_DEVICE_VERSION_MINOR; + ver.version[2] = DLM_DEVICE_VERSION_PATCH; + + if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version))) + return -EFAULT; + return sizeof(struct dlm_device_version); +} + /* a read returns a single ast described in a struct dlm_lock_result */ static ssize_t device_read(struct file *file, char __user *buf, size_t count, @@ -710,6 +737,16 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, DECLARE_WAITQUEUE(wait, current); int error, type=0, bmode=0, removed = 0; + if (count == sizeof(struct dlm_device_version)) { + error = copy_version_to_user(buf, count); + return error; + } + + if (!proc) { + log_print("non-version read from control device %zu", count); + return -EINVAL; + } + #ifdef CONFIG_COMPAT if (count < sizeof(struct dlm_lock_result32)) #else @@ -747,11 +784,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, } } - if (list_empty(&proc->asts)) { - spin_unlock(&proc->asts_spin); - return -EAGAIN; - } - /* there may be both completion and blocking asts to return for the lkb, don't remove lkb from asts list unless no asts remain */ @@ -823,6 +855,7 @@ static const struct file_operations device_fops = { static const struct file_operations ctl_device_fops = { .open = ctl_device_open, .release = ctl_device_close, + .read = device_read, .write = device_write, .owner = THIS_MODULE, }; diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h index c2735cab2ebf..f7b9b57348a8 100644 --- a/include/linux/dlm_device.h +++ b/include/linux/dlm_device.h @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -18,21 +18,24 @@ #define DLM_USER_LVB_LEN 32 /* Version of the device interface */ -#define DLM_DEVICE_VERSION_MAJOR 5 -#define DLM_DEVICE_VERSION_MINOR 1 +#define DLM_DEVICE_VERSION_MAJOR 6 +#define DLM_DEVICE_VERSION_MINOR 0 #define DLM_DEVICE_VERSION_PATCH 0 /* struct passed to the lock write */ struct dlm_lock_params { __u8 mode; __u8 namelen; - __u16 flags; + __u16 unused; + __u32 flags; __u32 lkid; __u32 parent; - void __user *castparam; + __u64 xid; + __u64 timeout; + void __user *castparam; void __user *castaddr; void __user *bastparam; - void __user *bastaddr; + void __user *bastaddr; struct dlm_lksb __user *lksb; char lvb[DLM_USER_LVB_LEN]; char name[0]; @@ -62,9 +65,15 @@ struct dlm_write_request { } i; }; +struct dlm_device_version { + __u32 version[3]; +}; + /* struct read from the "device" fd, consists mainly of userspace pointers for the library to use */ + struct dlm_lock_result { + __u32 version[3]; __u32 length; void __user * user_astaddr; void __user * user_astparam; From c85d65e91430db94ae9ce0cf38b56e496658b642 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 09:01:26 -0500 Subject: [PATCH 144/551] [DLM] cancel in conversion deadlock [4/6] When conversion deadlock is detected, cancel the conversion and return EDEADLK to the application. This is a new default behavior where before the dlm would allow the deadlock to exist indefinately. The DLM_LKF_NODLCKWT flag can now be used in a conversion to prevent the dlm from performing conversion deadlock detection/cancelation on it. The DLM_LKF_CONVDEADLK flag can continue to be used as before to tell the dlm to demote the granted mode of the lock being converted if it gets into a conversion deadlock. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lock.c | 195 ++++++++++++++++++++++++++++++-------------- include/linux/dlm.h | 6 +- 2 files changed, 138 insertions(+), 63 deletions(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index ad3797a37942..3c4d570477b4 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1408,10 +1408,8 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb) * queue for one resource. The granted mode of each lock blocks the requested * mode of the other lock." * - * Part 2: if the granted mode of lkb is preventing the first lkb in the - * convert queue from being granted, then demote lkb (set grmode to NL). - * This second form requires that we check for conv-deadlk even when - * now == 0 in _can_be_granted(). + * Part 2: if the granted mode of lkb is preventing an earlier lkb in the + * convert queue from being granted, then deadlk/demote lkb. * * Example: * Granted Queue: empty @@ -1420,41 +1418,52 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb) * * The first lock can't be granted because of the granted mode of the second * lock and the second lock can't be granted because it's not first in the - * list. We demote the granted mode of the second lock (the lkb passed to this - * function). + * list. We either cancel lkb's conversion (PR->EX) and return EDEADLK, or we + * demote the granted mode of lkb (from PR to NL) if it has the CONVDEADLK + * flag set and return DEMOTED in the lksb flags. * - * After the resolution, the "grant pending" function needs to go back and try - * to grant locks on the convert queue again since the first lock can now be - * granted. + * Originally, this function detected conv-deadlk in a more limited scope: + * - if !modes_compat(lkb1, lkb2) && !modes_compat(lkb2, lkb1), or + * - if lkb1 was the first entry in the queue (not just earlier), and was + * blocked by the granted mode of lkb2, and there was nothing on the + * granted queue preventing lkb1 from being granted immediately, i.e. + * lkb2 was the only thing preventing lkb1 from being granted. + * + * That second condition meant we'd only say there was conv-deadlk if + * resolving it (by demotion) would lead to the first lock on the convert + * queue being granted right away. It allowed conversion deadlocks to exist + * between locks on the convert queue while they couldn't be granted anyway. + * + * Now, we detect and take action on conversion deadlocks immediately when + * they're created, even if they may not be immediately consequential. If + * lkb1 exists anywhere in the convert queue and lkb2 comes in with a granted + * mode that would prevent lkb1's conversion from being granted, we do a + * deadlk/demote on lkb2 right away and don't let it onto the convert queue. + * I think this means that the lkb_is_ahead condition below should always + * be zero, i.e. there will never be conv-deadlk between two locks that are + * both already on the convert queue. */ -static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) +static int conversion_deadlock_detect(struct dlm_rsb *r, struct dlm_lkb *lkb2) { - struct dlm_lkb *this, *first = NULL, *self = NULL; + struct dlm_lkb *lkb1; + int lkb_is_ahead = 0; - list_for_each_entry(this, &rsb->res_convertqueue, lkb_statequeue) { - if (!first) - first = this; - if (this == lkb) { - self = lkb; + list_for_each_entry(lkb1, &r->res_convertqueue, lkb_statequeue) { + if (lkb1 == lkb2) { + lkb_is_ahead = 1; continue; } - if (!modes_compat(this, lkb) && !modes_compat(lkb, this)) - return 1; + if (!lkb_is_ahead) { + if (!modes_compat(lkb2, lkb1)) + return 1; + } else { + if (!modes_compat(lkb2, lkb1) && + !modes_compat(lkb1, lkb2)) + return 1; + } } - - /* if lkb is on the convert queue and is preventing the first - from being granted, then there's deadlock and we demote lkb. - multiple converting locks may need to do this before the first - converting lock can be granted. */ - - if (self && self != first) { - if (!modes_compat(lkb, first) && - !queue_conflict(&rsb->res_grantqueue, first)) - return 1; - } - return 0; } @@ -1583,42 +1592,57 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (!now && !conv && list_empty(&r->res_convertqueue) && first_in_list(lkb, &r->res_waitqueue)) return 1; - out: - /* - * The following, enabled by CONVDEADLK, departs from VMS. - */ - - if (conv && (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) && - conversion_deadlock_detect(r, lkb)) { - lkb->lkb_grmode = DLM_LOCK_NL; - lkb->lkb_sbflags |= DLM_SBF_DEMOTED; - } - return 0; } -/* - * The ALTPR and ALTCW flags aren't traditional lock manager flags, but are a - * simple way to provide a big optimization to applications that can use them. - */ - -static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) +static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now, + int *err) { - uint32_t flags = lkb->lkb_exflags; int rv; int8_t alt = 0, rqmode = lkb->lkb_rqmode; + int8_t is_convert = (lkb->lkb_grmode != DLM_LOCK_IV); + + if (err) + *err = 0; rv = _can_be_granted(r, lkb, now); if (rv) goto out; - if (lkb->lkb_sbflags & DLM_SBF_DEMOTED) - goto out; + /* + * The CONVDEADLK flag is non-standard and tells the dlm to resolve + * conversion deadlocks by demoting grmode to NL, otherwise the dlm + * cancels one of the locks. + */ - if (rqmode != DLM_LOCK_PR && flags & DLM_LKF_ALTPR) + if (is_convert && can_be_queued(lkb) && + conversion_deadlock_detect(r, lkb)) { + if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) { + lkb->lkb_grmode = DLM_LOCK_NL; + lkb->lkb_sbflags |= DLM_SBF_DEMOTED; + } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { + if (err) + *err = -EDEADLK; + else { + log_print("can_be_granted deadlock %x now %d", + lkb->lkb_id, now); + dlm_dump_rsb(r); + } + } + goto out; + } + + /* + * The ALTPR and ALTCW flags are non-standard and tell the dlm to try + * to grant a request in a mode other than the normal rqmode. It's a + * simple way to provide a big optimization to applications that can + * use them. + */ + + if (rqmode != DLM_LOCK_PR && (lkb->lkb_exflags & DLM_LKF_ALTPR)) alt = DLM_LOCK_PR; - else if (rqmode != DLM_LOCK_CW && flags & DLM_LKF_ALTCW) + else if (rqmode != DLM_LOCK_CW && (lkb->lkb_exflags & DLM_LKF_ALTCW)) alt = DLM_LOCK_CW; if (alt) { @@ -1633,10 +1657,20 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) return rv; } +/* FIXME: I don't think that can_be_granted() can/will demote or find deadlock + for locks pending on the convert list. Once verified (watch for these + log_prints), we should be able to just call _can_be_granted() and not + bother with the demote/deadlk cases here (and there's no easy way to deal + with a deadlk here, we'd have to generate something like grant_lock with + the deadlk error.) */ + +/* returns the highest requested mode of all blocked conversions */ + static int grant_pending_convert(struct dlm_rsb *r, int high) { struct dlm_lkb *lkb, *s; int hi, demoted, quit, grant_restart, demote_restart; + int deadlk; quit = 0; restart: @@ -1646,14 +1680,29 @@ static int grant_pending_convert(struct dlm_rsb *r, int high) list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) { demoted = is_demoted(lkb); - if (can_be_granted(r, lkb, 0)) { + deadlk = 0; + + if (can_be_granted(r, lkb, 0, &deadlk)) { grant_lock_pending(r, lkb); grant_restart = 1; - } else { - hi = max_t(int, lkb->lkb_rqmode, hi); - if (!demoted && is_demoted(lkb)) - demote_restart = 1; + continue; } + + if (!demoted && is_demoted(lkb)) { + log_print("WARN: pending demoted %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); + demote_restart = 1; + continue; + } + + if (deadlk) { + log_print("WARN: pending deadlock %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); + dlm_dump_rsb(r); + continue; + } + + hi = max_t(int, lkb->lkb_rqmode, hi); } if (grant_restart) @@ -1671,7 +1720,7 @@ static int grant_pending_wait(struct dlm_rsb *r, int high) struct dlm_lkb *lkb, *s; list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { - if (can_be_granted(r, lkb, 0)) + if (can_be_granted(r, lkb, 0, NULL)) grant_lock_pending(r, lkb); else high = max_t(int, lkb->lkb_rqmode, high); @@ -2121,7 +2170,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) { int error = 0; - if (can_be_granted(r, lkb, 1)) { + if (can_be_granted(r, lkb, 1, NULL)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); goto out; @@ -2147,16 +2196,32 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) { int error = 0; + int deadlk = 0; /* changing an existing lock may allow others to be granted */ - if (can_be_granted(r, lkb, 1)) { + if (can_be_granted(r, lkb, 1, &deadlk)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); grant_pending_locks(r); goto out; } + /* can_be_granted() detected that this lock would block in a conversion + deadlock, so we leave it on the granted queue and return EDEADLK in + the ast for the convert. */ + + if (deadlk) { + /* it's left on the granted queue */ + log_debug(r->res_ls, "deadlock %x node %d sts%d g%d r%d %s", + lkb->lkb_id, lkb->lkb_nodeid, lkb->lkb_status, + lkb->lkb_grmode, lkb->lkb_rqmode, r->res_name); + revert_lock(r, lkb); + queue_cast(r, lkb, -EDEADLK); + error = -EDEADLK; + goto out; + } + /* is_demoted() means the can_be_granted() above set the grmode to NL, and left us on the granted queue. This auto-demotion (due to CONVDEADLK) might mean other locks, and/or this lock, are @@ -2438,7 +2503,7 @@ int dlm_lock(dlm_lockspace_t *lockspace, out_put: if (convert || error) __put_lkb(ls, lkb); - if (error == -EAGAIN) + if (error == -EAGAIN || error == -EDEADLK) error = 0; out: dlm_unlock_recovery(ls); @@ -3312,6 +3377,12 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, queue_cast(r, lkb, -EAGAIN); break; + case -EDEADLK: + receive_flags_reply(lkb, ms); + revert_lock_pc(r, lkb); + queue_cast(r, lkb, -EDEADLK); + break; + case -EINPROGRESS: /* convert was queued on remote master */ receive_flags_reply(lkb, ms); @@ -4284,7 +4355,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, error = convert_lock(ls, lkb, &args); - if (error == -EINPROGRESS || error == -EAGAIN) + if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK) error = 0; out_put: dlm_put_lkb(lkb); diff --git a/include/linux/dlm.h b/include/linux/dlm.h index 975f17d8aa53..5227a9594f9d 100644 --- a/include/linux/dlm.h +++ b/include/linux/dlm.h @@ -85,7 +85,11 @@ * Only relevant to locks originating in userspace. A persistent lock will not * be removed if the process holding the lock exits. * - * DLM_LKF_NODLKWT + * DLM_LKF_NODLCKWT + * + * Do not cancel the lock if it gets into conversion deadlock. + * Exclude this lock from being monitored due to DLM_LSFL_TIMEWARN. + * * DLM_LKF_NODLCKBLK * * net yet implemented From 79d72b54483bf81b9f9de0dd555c710ac7267986 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 09:02:20 -0500 Subject: [PATCH 145/551] [DLM] fix new_lockspace error exit [5/6] Fix the error path when exiting new_lockspace(). It was kfree'ing the lockspace struct at the end, but that's only valid if it exits before kobject_register occured. After kobject_register we have to let the kobject do the freeing. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lockspace.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 339a204d7479..a3a50e67e4dd 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -400,6 +400,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, { struct dlm_ls *ls; int i, size, error = -ENOMEM; + int do_unreg = 0; if (namelen > DLM_LOCKSPACE_LEN) return -EINVAL; @@ -525,32 +526,34 @@ static int new_lockspace(char *name, int namelen, void **lockspace, error = dlm_recoverd_start(ls); if (error) { log_error(ls, "can't start dlm_recoverd %d", error); - goto out_rcomfree; + goto out_delist; } - dlm_create_debug_file(ls); - error = kobject_setup(ls); if (error) - goto out_del; + goto out_stop; error = kobject_register(&ls->ls_kobj); if (error) - goto out_del; + goto out_stop; + + /* let kobject handle freeing of ls if there's an error */ + do_unreg = 1; error = do_uevent(ls, 1); if (error) - goto out_unreg; + goto out_stop; + + dlm_create_debug_file(ls); + + log_debug(ls, "join complete"); *lockspace = ls; return 0; - out_unreg: - kobject_unregister(&ls->ls_kobj); - out_del: - dlm_delete_debug_file(ls); + out_stop: dlm_recoverd_stop(ls); - out_rcomfree: + out_delist: spin_lock(&lslist_lock); list_del(&ls->ls_list); spin_unlock(&lslist_lock); @@ -562,7 +565,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace, out_rsbfree: kfree(ls->ls_rsbtbl); out_lsfree: - kfree(ls); + if (do_unreg) + kobject_unregister(&ls->ls_kobj); + else + kfree(ls); out: module_put(THIS_MODULE); return error; @@ -708,7 +714,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) dlm_clear_members_gone(ls); kfree(ls->ls_node_array); kobject_unregister(&ls->ls_kobj); - /* The ls structure will be freed when the kobject is done with */ + /* The ls structure will be freed when the kobject is done with */ mutex_lock(&ls_lock); ls_count--; From 8b0e7b2cf35aa827ed5efb508c1879481b970496 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 09:03:35 -0500 Subject: [PATCH 146/551] [DLM] wait for config check during join [6/6] Joining the lockspace should wait for the initial round of inter-node config checks to complete before returning. This way, if there's a configuration mismatch between the joining node and the existing nodes, the join can fail and return an error to the application. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/dlm_internal.h | 2 ++ fs/dlm/lockspace.c | 30 ++++++++++++++++++++++++++++++ fs/dlm/member.c | 6 ++++++ fs/dlm/rcom.c | 4 ++-- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index a8d6e993697c..03ba6c4fd5c2 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -472,6 +472,8 @@ struct dlm_ls { wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ int ls_uevent_result; + struct completion ls_members_done; + int ls_members_result; struct miscdevice ls_device; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a3a50e67e4dd..c8f0c15ac166 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in) else kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); + log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving"); + + /* dlm_controld will see the uevent, do the necessary group management + and then write to sysfs to wake us */ + error = wait_event_interruptible(ls->ls_uevent_wait, test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); + + log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result); + if (error) goto out; error = ls->ls_uevent_result; out: + if (error) + log_error(ls, "group %s failed %d %d", in ? "join" : "leave", + error, ls->ls_uevent_result); return error; } @@ -490,6 +501,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, init_waitqueue_head(&ls->ls_uevent_wait); ls->ls_uevent_result = 0; + init_completion(&ls->ls_members_done); + ls->ls_members_result = -1; ls->ls_recoverd_task = NULL; mutex_init(&ls->ls_recoverd_active); @@ -540,10 +553,21 @@ static int new_lockspace(char *name, int namelen, void **lockspace, /* let kobject handle freeing of ls if there's an error */ do_unreg = 1; + /* This uevent triggers dlm_controld in userspace to add us to the + group of nodes that are members of this lockspace (managed by the + cluster infrastructure.) Once it's done that, it tells us who the + current lockspace members are (via configfs) and then tells the + lockspace to start running (via sysfs) in dlm_ls_start(). */ + error = do_uevent(ls, 1); if (error) goto out_stop; + wait_for_completion(&ls->ls_members_done); + error = ls->ls_members_result; + if (error) + goto out_members; + dlm_create_debug_file(ls); log_debug(ls, "join complete"); @@ -551,6 +575,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace, *lockspace = ls; return 0; + out_members: + do_uevent(ls, 0); + dlm_clear_members(ls); + kfree(ls->ls_node_array); out_stop: dlm_recoverd_stop(ls); out_delist: @@ -588,6 +616,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace, error = new_lockspace(name, namelen, lockspace, flags, lvblen); if (!error) ls_count++; + else if (!ls_count) + threads_stop(); out: mutex_unlock(&ls_lock); return error; diff --git a/fs/dlm/member.c b/fs/dlm/member.c index f08faec3d854..073599dced2a 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -233,6 +233,12 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) *neg_out = neg; error = ping_members(ls); + if (!error || error == -EPROTO) { + /* new_lockspace() may be waiting to know if the config + is good or bad */ + ls->ls_members_result = error; + complete(&ls->ls_members_done); + } if (error) goto out; diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 6bfbd6153809..f71c23542f0f 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -90,7 +90,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) log_error(ls, "version mismatch: %x nodeid %d: %x", DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid, rc->rc_header.h_version); - return -EINVAL; + return -EPROTO; } if (rf->rf_lvblen != ls->ls_lvblen || @@ -98,7 +98,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", ls->ls_lvblen, ls->ls_exflags, nodeid, rf->rf_lvblen, rf->rf_lsflags); - return -EINVAL; + return -EPROTO; } return 0; } From 639aca417d91ebba1077a6084e4423af1c1dd811 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 18 May 2007 16:02:57 -0500 Subject: [PATCH 147/551] [DLM] fix compile breakage In the rush to get the previous patch set sent, a compilation bug I fixed shortly before sending somehow got clobbered, probably by a missed quilt refresh or something. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 3c4d570477b4..b47e6fd0172c 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1098,8 +1098,8 @@ void dlm_scan_timeout(struct dlm_ls *ls) } if (do_cancel) { - log_debug("timeout cancel %x node %d %s", lkb->lkb_id, - lkb->lkb_nodeid, r->res_name); + log_debug(r->res_ls, "timeout cancel %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; del_timeout(lkb); From 518bbde33f7a6b4e252ea2591c77ef796065afa8 Mon Sep 17 00:00:00 2001 From: Fabio Massimo Di Nitto Date: Tue, 22 May 2007 09:00:24 +0200 Subject: [PATCH 148/551] [GFS2] latest gfs2-nmw headers break userland build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2e8701a15cd6f7c95e74d6660615a69b09e453ef commit breaks libgfs2 build: gcc -Wall -I/usr/src/ubuntu/mypkgs/rhcluster/cluster/config -DHELPER_PROGRAM -D_FILE_OFFSET_BITS=64 -DGFS2_RELEASE_NAME=\"2.0\" -ggdb -I/usr/include -I../include -I../libgfs2 -c -o gfs2hex.o gfs2hex.c In file included from hexedit.h:22, from gfs2hex.c:27: /usr/include/linux/gfs2_ondisk.h:505: error: expected specifier-qualifier-list before ‘u32’ make[2]: *** [gfs2hex.o] Error 1 make[2]: Leaving directory `/usr/src/ubuntu/mypkgs/rhcluster/cluster/gfs2/edit' make[1]: *** [all] Error 2 make[1]: Leaving directory `/usr/src/ubuntu/mypkgs/rhcluster/cluster/gfs2' make: *** [gfs2] Error 2 Signed-off-by: Fabio Massimo Di Nitto Signed-off-by: Steven Whitehouse --- include/linux/gfs2_ondisk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 028f9810ba07..9ecf92941b23 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -502,7 +502,7 @@ struct gfs2_quota_change_host { struct gfs2_quota_lvb { __be32 qb_magic; - u32 __pad; + __u32 __pad; __be64 qb_limit; /* Hard limit of # blocks to alloc */ __be64 qb_warn; /* Warn user when alloc is above this # */ __be64 qb_value; /* Current # blocks allocated */ From b3cab7b9a34a6e65c1ca8f80fb57b256d57e8555 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 29 May 2007 11:14:21 +0100 Subject: [PATCH 149/551] [DLM] Compile fix A one liner fix which got missed from the earlier patches. Signed-off-by: Steven Whitehouse Cc: Fabio Massimo Di Nitto Cc: David Teigland --- fs/dlm/lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index b47e6fd0172c..2f8a5a700cc0 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1098,7 +1098,7 @@ void dlm_scan_timeout(struct dlm_ls *ls) } if (do_cancel) { - log_debug(r->res_ls, "timeout cancel %x node %d %s", + log_debug(ls, "timeout cancel %x node %d %s", lkb->lkb_id, lkb->lkb_nodeid, r->res_name); lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; From 84d8cd69a8e7f1c9962f46bc79850c9f1f663806 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 29 May 2007 08:44:23 -0500 Subject: [PATCH 150/551] [DLM] timeout fixes Various fixes related to the new timeout feature: - add_timeout() missed setting TIMEWARN flag on lkb's when the TIMEOUT flag was already set - clear_proc_locks should remove a dead process's locks from the timeout list - the end-of-life calculation for user locks needs to consider that ETIMEDOUT is equivalent to -DLM_ECANCEL - make initial default timewarn_cs config value visible in configfs - change bit position of TIMEOUT_CANCEL flag so it's not copied to a remote master node - set timestamp on remote lkb's so a lock dump will display the time they've been waiting Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/config.c | 1 + fs/dlm/dlm_internal.h | 2 +- fs/dlm/lock.c | 13 ++++++------ fs/dlm/netlink.c | 2 -- fs/dlm/user.c | 49 ++++++++++++++++++++++++++----------------- 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 2909abf1bbc3..1b59fa56a599 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -433,6 +433,7 @@ static struct config_group *make_cluster(struct config_group *g, cl->cl_toss_secs = dlm_config.ci_toss_secs; cl->cl_scan_secs = dlm_config.ci_scan_secs; cl->cl_log_debug = dlm_config.ci_log_debug; + cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; space_list = &sps->ss_group; comm_list = &cms->cs_group; diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 03ba6c4fd5c2..a7435a8df35e 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -215,9 +215,9 @@ struct dlm_args { #define DLM_IFL_OVERLAP_CANCEL 0x00100000 #define DLM_IFL_ENDOFLIFE 0x00200000 #define DLM_IFL_WATCH_TIMEWARN 0x00400000 +#define DLM_IFL_TIMEOUT_CANCEL 0x00800000 #define DLM_IFL_USER 0x00000001 #define DLM_IFL_ORPHAN 0x00000002 -#define DLM_IFL_TIMEOUT_CANCEL 0x00000004 struct dlm_lkb { struct dlm_rsb *lkb_resource; /* the rsb */ diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 2f8a5a700cc0..df91578145d1 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1010,17 +1010,18 @@ static void add_timeout(struct dlm_lkb *lkb) { struct dlm_ls *ls = lkb->lkb_resource->res_ls; - if (is_master_copy(lkb)) + if (is_master_copy(lkb)) { + lkb->lkb_timestamp = jiffies; return; - - if (lkb->lkb_exflags & DLM_LKF_TIMEOUT) - goto add_it; + } if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) && !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN; goto add_it; } + if (lkb->lkb_exflags & DLM_LKF_TIMEOUT) + goto add_it; return; add_it: @@ -3510,8 +3511,7 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms) case -DLM_ECANCEL: receive_flags_reply(lkb, ms); revert_lock_pc(r, lkb); - if (ms->m_result) - queue_cast(r, lkb, -DLM_ECANCEL); + queue_cast(r, lkb, -DLM_ECANCEL); break; case 0: break; @@ -4534,6 +4534,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) lkb = del_proc_lock(ls, proc); if (!lkb) break; + del_timeout(lkb); if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) orphan_proc_lock(ls, lkb); else diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c index 804b32cd22c1..863b87d0dc71 100644 --- a/fs/dlm/netlink.c +++ b/fs/dlm/netlink.c @@ -133,8 +133,6 @@ void dlm_timeout_warn(struct dlm_lkb *lkb) size_t size; int rv; - log_debug(lkb->lkb_resource->res_ls, "timeout_warn %x", lkb->lkb_id); - size = nla_total_size(sizeof(struct dlm_lock_data)) + nla_total_size(0); /* why this? */ diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 37aad3fe8949..329da1b5285f 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -138,6 +138,35 @@ static void compat_output(struct dlm_lock_result *res, } #endif +/* Figure out if this lock is at the end of its life and no longer + available for the application to use. The lkb still exists until + the final ast is read. A lock becomes EOL in three situations: + 1. a noqueue request fails with EAGAIN + 2. an unlock completes with EUNLOCK + 3. a cancel of a waiting request completes with ECANCEL/EDEADLK + An EOL lock needs to be removed from the process's list of locks. + And we can't allow any new operation on an EOL lock. This is + not related to the lifetime of the lkb struct which is managed + entirely by refcount. */ + +static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) +{ + switch (sb_status) { + case -DLM_EUNLOCK: + return 1; + case -DLM_ECANCEL: + case -ETIMEDOUT: + if (lkb->lkb_grmode == DLM_LOCK_IV) + return 1; + break; + case -EAGAIN: + if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV) + return 1; + break; + } + return 0; +} + /* we could possibly check if the cancel of an orphan has resulted in the lkb being removed and then remove that lkb from the orphans list and free it */ @@ -184,25 +213,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) log_debug(ls, "ast overlap %x status %x %x", lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags); - /* Figure out if this lock is at the end of its life and no longer - available for the application to use. The lkb still exists until - the final ast is read. A lock becomes EOL in three situations: - 1. a noqueue request fails with EAGAIN - 2. an unlock completes with EUNLOCK - 3. a cancel of a waiting request completes with ECANCEL - An EOL lock needs to be removed from the process's list of locks. - And we can't allow any new operation on an EOL lock. This is - not related to the lifetime of the lkb struct which is managed - entirely by refcount. */ - - if (type == AST_COMP && - lkb->lkb_grmode == DLM_LOCK_IV && - ua->lksb.sb_status == -EAGAIN) - eol = 1; - else if (ua->lksb.sb_status == -DLM_EUNLOCK || - (ua->lksb.sb_status == -DLM_ECANCEL && - lkb->lkb_grmode == DLM_LOCK_IV)) - eol = 1; + eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type); if (eol) { lkb->lkb_ast_type &= ~AST_BAST; lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; From 8b4021fa436f7c76a2299e6d85d4d4a619724e9a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 29 May 2007 08:46:00 -0500 Subject: [PATCH 151/551] [DLM] canceling deadlocked lock Add a function that can be used through libdlm by a system daemon to cancel another process's deadlocked lock. A completion ast with EDEADLK is returned to the process waiting for the lock. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/dlm_internal.h | 1 + fs/dlm/lock.c | 53 ++++++++++++++++++++++++++++++++++++++ fs/dlm/lock.h | 1 + fs/dlm/user.c | 25 ++++++++++++++++++ include/linux/dlm_device.h | 1 + 5 files changed, 81 insertions(+) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index a7435a8df35e..a006fa59e7da 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -216,6 +216,7 @@ struct dlm_args { #define DLM_IFL_ENDOFLIFE 0x00200000 #define DLM_IFL_WATCH_TIMEWARN 0x00400000 #define DLM_IFL_TIMEOUT_CANCEL 0x00800000 +#define DLM_IFL_DEADLOCK_CANCEL 0x01000000 #define DLM_IFL_USER 0x00000001 #define DLM_IFL_ORPHAN 0x00000002 diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index df91578145d1..de943afacb37 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -300,6 +300,11 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) rv = -ETIMEDOUT; } + if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_DEADLOCK_CANCEL)) { + lkb->lkb_flags &= ~DLM_IFL_DEADLOCK_CANCEL; + rv = -EDEADLK; + } + lkb->lkb_lksb->sb_status = rv; lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; @@ -4450,6 +4455,54 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, return error; } +int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid) +{ + struct dlm_lkb *lkb; + struct dlm_args args; + struct dlm_user_args *ua; + struct dlm_rsb *r; + int error; + + dlm_lock_recovery(ls); + + error = find_lkb(ls, lkid, &lkb); + if (error) + goto out; + + ua = (struct dlm_user_args *)lkb->lkb_astparam; + + error = set_unlock_args(flags, ua, &args); + if (error) + goto out_put; + + /* same as cancel_lock(), but set DEADLOCK_CANCEL after lock_rsb */ + + r = lkb->lkb_resource; + hold_rsb(r); + lock_rsb(r); + + error = validate_unlock_args(lkb, &args); + if (error) + goto out_r; + lkb->lkb_flags |= DLM_IFL_DEADLOCK_CANCEL; + + error = _cancel_lock(r, lkb); + out_r: + unlock_rsb(r); + put_rsb(r); + + if (error == -DLM_ECANCEL) + error = 0; + /* from validate_unlock_args() */ + if (error == -EBUSY) + error = 0; + out_put: + dlm_put_lkb(lkb); + out: + dlm_unlock_recovery(ls); + return error; +} + /* lkb's that are removed from the waiters list by revert are just left on the orphans list with the granted orphan locks, to be freed by purge */ diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 99ab4635074e..1720313c22df 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -49,6 +49,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid); int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc, int nodeid, int pid); +int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid); void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc); static inline int is_master(struct dlm_rsb *r) diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 329da1b5285f..6438941ab1f8 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -156,6 +156,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) return 1; case -DLM_ECANCEL: case -ETIMEDOUT: + case -EDEADLK: if (lkb->lkb_grmode == DLM_LOCK_IV) return 1; break; @@ -320,6 +321,22 @@ static int device_user_unlock(struct dlm_user_proc *proc, return error; } +static int device_user_deadlock(struct dlm_user_proc *proc, + struct dlm_lock_params *params) +{ + struct dlm_ls *ls; + int error; + + ls = dlm_find_lockspace_local(proc->lockspace); + if (!ls) + return -ENOENT; + + error = dlm_user_deadlock(ls, params->flags, params->lkid); + + dlm_put_lockspace(ls); + return error; +} + static int create_misc_device(struct dlm_ls *ls, char *name) { int error, len; @@ -545,6 +562,14 @@ static ssize_t device_write(struct file *file, const char __user *buf, error = device_user_unlock(proc, &kbuf->i.lock); break; + case DLM_USER_DEADLOCK: + if (!proc) { + log_print("no locking on control device"); + goto out_sig; + } + error = device_user_deadlock(proc, &kbuf->i.lock); + break; + case DLM_USER_CREATE_LOCKSPACE: if (proc) { log_print("create/remove only on control device"); diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h index f7b9b57348a8..9642277a152a 100644 --- a/include/linux/dlm_device.h +++ b/include/linux/dlm_device.h @@ -92,6 +92,7 @@ struct dlm_lock_result { #define DLM_USER_CREATE_LOCKSPACE 4 #define DLM_USER_REMOVE_LOCKSPACE 5 #define DLM_USER_PURGE 6 +#define DLM_USER_DEADLOCK 7 /* Arbitrary length restriction */ #define MAX_LS_NAME_LEN 64 From 9dd592d70be0db6fa8e4e19d7642cfaa424b200e Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 29 May 2007 08:47:04 -0500 Subject: [PATCH 152/551] [DLM] dumping master locks Add a new debugfs file that dumps a compact list of mastered locks. This will be used by a userland daemon to collect state for deadlock detection. Also, for the existing function that prints all lock state, lock the rsb before going through the lock lists since they can be changing in the course of normal dlm activity. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/debug_fs.c | 164 +++++++++++++++++++++++++++++++++++++++++- fs/dlm/dlm_internal.h | 1 + 2 files changed, 163 insertions(+), 2 deletions(-) diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 9e27a1675794..184be9870c63 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -27,6 +27,8 @@ static struct dentry *dlm_root; struct rsb_iter { int entry; + int master; + int header; struct dlm_ls *ls; struct list_head *next; struct dlm_rsb *rsb; @@ -86,6 +88,8 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s) struct dlm_lkb *lkb; int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list; + lock_rsb(res); + seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length); for (i = 0; i < res->res_length; i++) { if (isprint(res->res_name[i])) @@ -152,6 +156,59 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s) seq_printf(s, "\n"); } out: + unlock_rsb(res); + return 0; +} + +static void print_master_lock(struct seq_file *s, struct dlm_lkb *lkb, + struct dlm_rsb *r) +{ + struct dlm_user_args *ua; + unsigned int waiting = 0; + uint64_t xid = 0; + + if (lkb->lkb_flags & DLM_IFL_USER) { + ua = (struct dlm_user_args *) lkb->lkb_astparam; + if (ua) + xid = ua->xid; + } + + if (lkb->lkb_timestamp) + waiting = jiffies_to_msecs(jiffies - lkb->lkb_timestamp); + + /* id nodeid remid pid xid flags sts grmode rqmode time_ms len name */ + + seq_printf(s, "%x %d %x %u %llu %x %d %d %d %u %d \"%s\"\n", + lkb->lkb_id, + lkb->lkb_nodeid, + lkb->lkb_remid, + lkb->lkb_ownpid, + (unsigned long long)xid, + lkb->lkb_exflags, + lkb->lkb_status, + lkb->lkb_grmode, + lkb->lkb_rqmode, + waiting, + r->res_length, + r->res_name); +} + +static int print_master_resource(struct dlm_rsb *r, struct seq_file *s) +{ + struct dlm_lkb *lkb; + + lock_rsb(r); + + list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + unlock_rsb(r); return 0; } @@ -209,7 +266,7 @@ static struct rsb_iter *rsb_iter_init(struct dlm_ls *ls) { struct rsb_iter *ri; - ri = kmalloc(sizeof *ri, GFP_KERNEL); + ri = kzalloc(sizeof *ri, GFP_KERNEL); if (!ri) return NULL; @@ -267,7 +324,17 @@ static int rsb_seq_show(struct seq_file *file, void *iter_ptr) { struct rsb_iter *ri = iter_ptr; - print_resource(ri->rsb, file); + if (ri->master) { + if (ri->header) { + seq_printf(file, "id nodeid remid pid xid flags sts " + "grmode rqmode time_ms len name\n"); + ri->header = 0; + } + if (is_master(ri->rsb)) + print_master_resource(ri->rsb, file); + } else { + print_resource(ri->rsb, file); + } return 0; } @@ -302,6 +369,83 @@ static const struct file_operations rsb_fops = { .release = seq_release }; +/* + * Dump master lock state + */ + +static struct rsb_iter *master_iter_init(struct dlm_ls *ls, loff_t *pos) +{ + struct rsb_iter *ri; + + ri = kzalloc(sizeof *ri, GFP_KERNEL); + if (!ri) + return NULL; + + ri->ls = ls; + ri->entry = 0; + ri->next = NULL; + ri->master = 1; + + if (*pos == 0) + ri->header = 1; + + if (rsb_iter_next(ri)) { + rsb_iter_free(ri); + return NULL; + } + + return ri; +} + +static void *master_seq_start(struct seq_file *file, loff_t *pos) +{ + struct rsb_iter *ri; + loff_t n = *pos; + + ri = master_iter_init(file->private, pos); + if (!ri) + return NULL; + + while (n--) { + if (rsb_iter_next(ri)) { + rsb_iter_free(ri); + return NULL; + } + } + + return ri; +} + +static struct seq_operations master_seq_ops = { + .start = master_seq_start, + .next = rsb_seq_next, + .stop = rsb_seq_stop, + .show = rsb_seq_show, +}; + +static int master_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + int ret; + + ret = seq_open(file, &master_seq_ops); + if (ret) + return ret; + + seq = file->private_data; + seq->private = inode->i_private; + + return 0; +} + +static const struct file_operations master_fops = { + .owner = THIS_MODULE, + .open = master_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + /* * dump lkb's on the ls_waiters list */ @@ -369,6 +513,20 @@ int dlm_create_debug_file(struct dlm_ls *ls) return -ENOMEM; } + memset(name, 0, sizeof(name)); + snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_master", ls->ls_name); + + ls->ls_debug_master_dentry = debugfs_create_file(name, + S_IFREG | S_IRUGO, + dlm_root, + ls, + &master_fops); + if (!ls->ls_debug_master_dentry) { + debugfs_remove(ls->ls_debug_waiters_dentry); + debugfs_remove(ls->ls_debug_rsb_dentry); + return -ENOMEM; + } + return 0; } @@ -378,6 +536,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls) debugfs_remove(ls->ls_debug_rsb_dentry); if (ls->ls_debug_waiters_dentry) debugfs_remove(ls->ls_debug_waiters_dentry); + if (ls->ls_debug_master_dentry) + debugfs_remove(ls->ls_debug_master_dentry); } int dlm_register_debugfs(void) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index a006fa59e7da..f2c85493c0c6 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -470,6 +470,7 @@ struct dlm_ls { struct dentry *ls_debug_rsb_dentry; /* debugfs */ struct dentry *ls_debug_waiters_dentry; /* debugfs */ + struct dentry *ls_debug_master_dentry; /* debugfs */ wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ int ls_uevent_result; From 0b7cac0fb0e541a7f54d0ba55b31d829ce3dd899 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 29 May 2007 08:47:51 -0500 Subject: [PATCH 153/551] [DLM] show default protocol Display the initial value of the "protocol" config value in configfs. The default value has always been 0 in the past anyway, so it's always appeared to be correct. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 1b59fa56a599..5069b2cb5a1f 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -433,6 +433,7 @@ static struct config_group *make_cluster(struct config_group *g, cl->cl_toss_secs = dlm_config.ci_toss_secs; cl->cl_scan_secs = dlm_config.ci_scan_secs; cl->cl_log_debug = dlm_config.ci_log_debug; + cl->cl_protocol = dlm_config.ci_protocol; cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; space_list = &sps->ss_group; From 1990e917651d58a3c5155d0491431c09e29e385b Mon Sep 17 00:00:00 2001 From: Abhijith Das Date: Thu, 31 May 2007 17:52:02 -0500 Subject: [PATCH 154/551] [GFS2] Quotas non-functional - fix another bug This patch fixes a bug where gfs2 was writing update quota usage information to the wrong location in the quota file. Signed-off-by: Abhijith Das Signed-off-by: Steven Whitehouse --- fs/gfs2/ondisk.c | 10 ++++++++++ fs/gfs2/quota.c | 11 +++++++---- include/linux/gfs2_ondisk.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c index cd4cf055c37d..a5b05ea3d4c7 100644 --- a/fs/gfs2/ondisk.c +++ b/fs/gfs2/ondisk.c @@ -121,6 +121,16 @@ void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) qu->qu_value = be64_to_cpu(str->qu_value); } +void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf) +{ + struct gfs2_quota *str = buf; + + str->qu_limit = cpu_to_be64(qu->qu_limit); + str->qu_warn = cpu_to_be64(qu->qu_warn); + str->qu_value = cpu_to_be64(qu->qu_value); + memset(&str->qu_reserved, 0, sizeof(str->qu_reserved)); +} + void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) { const struct gfs2_dinode_host *di = &ip->i_di; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index fcd3ee2c5b96..8a58815dea08 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -573,12 +573,13 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, struct inode *inode = &ip->i_inode; struct address_space *mapping = inode->i_mapping; unsigned long index = loc >> PAGE_CACHE_SHIFT; - unsigned offset = loc & (PAGE_CACHE_SHIFT - 1); + unsigned offset = loc & (PAGE_CACHE_SIZE - 1); unsigned blocksize, iblock, pos; struct buffer_head *bh; struct page *page; void *kaddr; - __be64 *ptr; + char *ptr; + struct gfs2_quota_host qp; s64 value; int err = -EIO; @@ -620,8 +621,10 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, kaddr = kmap_atomic(page, KM_USER0); ptr = kaddr + offset; - value = (s64)be64_to_cpu(*ptr) + change; - *ptr = cpu_to_be64(value); + gfs2_quota_in(&qp, ptr); + qp.qu_value += change; + value = qp.qu_value; + gfs2_quota_out(&qp, ptr); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); err = 0; diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 9ecf92941b23..01cc35946a9d 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -519,6 +519,7 @@ extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf); extern void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf); extern void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf); extern void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf); +extern void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf); struct gfs2_inode; extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, const void *buf); From 89918647a445fddfe223b097e29f775dcfa81eab Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 1 Jun 2007 15:19:33 +0100 Subject: [PATCH 155/551] [GFS2] Make the log reserved blocks depend on block size The number of blocks which we reserve in the log at the start of each transaction needs to depends upon the block size since the overhead is related to the number of "pointers" which can be fitted into a single block. This relates to Red Hat bz #240435 Signed-off-by: Steven Whitehouse --- fs/gfs2/log.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 291415ddfe51..586923d24e6e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -262,7 +262,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) * @sdp: The GFS2 superblock * @blks: The number of blocks to reserve * - * Note that we never give out the last 6 blocks of the journal. Thats + * Note that we never give out the last few blocks of the journal. Thats * due to the fact that there is are a small number of header blocks * associated with each log flush. The exact number can't be known until * flush time, so we ensure that we have just enough free blocks at all @@ -274,6 +274,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) { unsigned int try = 0; + unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); if (gfs2_assert_warn(sdp, blks) || gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) @@ -281,7 +282,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) mutex_lock(&sdp->sd_log_reserve_mutex); gfs2_log_lock(sdp); - while(sdp->sd_log_blks_free <= (blks + 6)) { + while(sdp->sd_log_blks_free <= (blks + reserved_blks)) { gfs2_log_unlock(sdp); gfs2_ail1_empty(sdp, 0); gfs2_log_flush(sdp, NULL); From afb853fb4eec380b492a3c369f837359359c28e8 Mon Sep 17 00:00:00 2001 From: Patrick Caulfield Date: Fri, 1 Jun 2007 10:07:26 -0500 Subject: [PATCH 156/551] [DLM] fix socket shutdown This patch clears the user_data of active sockets as part of cleanup. This prevents any late-arriving data from trying to add jobs to the work queue while we are tidying up. Signed-Off-By: Patrick Caulfield Signed-Off-By: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lowcomms.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 27970a58d29b..fc0bff74c61e 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -260,7 +260,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) static void lowcomms_data_ready(struct sock *sk, int count_unused) { struct connection *con = sock2con(sk); - if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) + if (con && !test_and_set_bit(CF_READ_PENDING, &con->flags)) queue_work(recv_workqueue, &con->rwork); } @@ -268,7 +268,7 @@ static void lowcomms_write_space(struct sock *sk) { struct connection *con = sock2con(sk); - if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) + if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) queue_work(send_workqueue, &con->swork); } @@ -1400,8 +1400,11 @@ void dlm_lowcomms_stop(void) down(&connections_lock); for (i = 0; i <= max_nodeid; i++) { con = __nodeid2con(i, 0); - if (con) + if (con) { con->flags |= 0xFF; + if (con->sock) + con->sock->sk->sk_user_data = NULL; + } } up(&connections_lock); From ddf4b426aababdae4cb96326d7aeb9d119f42c50 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 1 Jun 2007 14:21:38 -0500 Subject: [PATCH 157/551] [GFS2] fix jdata issues This is a patch for the first three issues of RHBZ #238162 The first issue is that when you allocate a new page for a file, it will not start off uptodate. This makes sense, since you haven't written anything to that part of the file yet. Unfortunately, gfs2_pin() checks to make sure that the buffers are uptodate. The solution to this is to mark the buffers uptodate in gfs2_commit_write(), after they have been zeroed out and have the data written into them. I'm pretty confident with this fix, although it's not completely obvious that there is no problem with marking the buffers uptodate here. The second issue is simply that you can try to pin a data buffer that is already on the incore log, and thus, already pinned. This patch checks to see if this buffer is already on the log, and exits databuf_lo_add() if it is, just like buf_lo_add() does. The third issue is that gfs2_log_flush() doesn't do it's block accounting correctly. Both metadata and journaled data are logged, but gfs2_log_flush() only compares the number of metadata blocks with the number of blocks to commit to the ondisk journal. This patch also counts the journaled data blocks. Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/log.c | 2 +- fs/gfs2/lops.c | 2 ++ fs/gfs2/ops_address.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 586923d24e6e..1fb846fc545e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -566,7 +566,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) INIT_LIST_HEAD(&ai->ai_ail1_list); INIT_LIST_HEAD(&ai->ai_ail2_list); - gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf == sdp->sd_log_commited_buf); + gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf + sdp->sd_log_num_jdata == sdp->sd_log_commited_buf); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index f82d84d05d23..3e971f25120d 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -475,6 +475,8 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) tr->tr_num_buf++; list_add(&bd->bd_list_tr, &tr->tr_list_buf); gfs2_log_unlock(sdp); + if (!list_empty(&le->le_list)) + return; gfs2_pin(sdp, bd->bd_bh); tr->tr_num_buf_new++; } else { diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index fb84478e1df6..ac5659521386 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -50,6 +50,8 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, end = start + bsize; if (end <= from || start >= to) continue; + if (gfs2_is_jdata(ip)) + set_buffer_uptodate(bh); gfs2_trans_add_bh(ip->i_gl, bh, 0); } } From bb8d8a6f54c1c84d7c74623491bab043b36a38c5 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 1 Jun 2007 14:11:58 +0100 Subject: [PATCH 158/551] [GFS2] Fix sign problem in quota/statfs and cleanup _host structures This patch fixes some sign issues which were accidentally introduced into the quota & statfs code during the endianess annotation process. Also included is a general clean up which moves all of the _host structures out of gfs2_ondisk.h (where they should not have been to start with) and into the places where they are actually used (often only one place). Also those _host structures which are not required any more are removed entirely (which is the eventual plan for all of them). The conversion routines from ondisk.c are also moved into the places where they are actually used, which for almost every one, was just one single place, so all those are now static functions. This also cleans up the end of gfs2_ondisk.h which no longer needs the #ifdef __KERNEL__. The net result is a reduction of about 100 lines of code, many functions now marked static plus the bug fixes as mentioned above. For good measure I ran the code through sparse after making these changes to check that there are no warnings generated. This fixes Red Hat bz #239686 Signed-off-by: Steven Whitehouse --- fs/gfs2/Makefile | 2 +- fs/gfs2/bmap.c | 4 +- fs/gfs2/dir.c | 2 +- fs/gfs2/eattr.c | 6 +- fs/gfs2/incore.h | 63 ++++++++- fs/gfs2/inode.c | 83 +++++++++++- fs/gfs2/inode.h | 10 ++ fs/gfs2/ondisk.c | 246 ------------------------------------ fs/gfs2/ops_export.c | 10 +- fs/gfs2/ops_export.h | 22 ---- fs/gfs2/ops_fstype.c | 13 +- fs/gfs2/ops_fstype.h | 1 + fs/gfs2/ops_inode.c | 4 +- fs/gfs2/ops_vm.c | 2 +- fs/gfs2/quota.c | 42 +++++- fs/gfs2/recovery.c | 22 +++- fs/gfs2/rgrp.c | 111 +++++++++++----- fs/gfs2/super.c | 77 ++++++++--- fs/gfs2/super.h | 2 +- fs/gfs2/util.c | 2 +- include/linux/gfs2_ondisk.h | 127 ------------------- 21 files changed, 372 insertions(+), 479 deletions(-) delete mode 100644 fs/gfs2/ondisk.c delete mode 100644 fs/gfs2/ops_export.h diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile index e3f1ada643ac..04ad0caebedb 100644 --- a/fs/gfs2/Makefile +++ b/fs/gfs2/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_GFS2_FS) += gfs2.o gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ - mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ + mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ recovery.o rgrp.o super.o sys.o trans.o util.o diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index e76a887a89b2..b784cf3c6482 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -718,7 +718,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); @@ -824,7 +824,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) goto out_gunlock_q; error = gfs2_trans_begin(sdp, - sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + + sdp->sd_max_height + al->al_rgd->rd_length + RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) goto out_ipres; diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 9cdd71cef59c..2f154049b59d 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1897,7 +1897,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 5b83ca6acab1..40e1d37112e6 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -254,7 +254,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, if (error) return error; - error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE + + error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE + RES_EATTR + RES_STATFS + RES_QUOTA, blks); if (error) goto out_gunlock; @@ -700,7 +700,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, goto out_gunlock_q; error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), - blks + al->al_rgd->rd_ri.ri_length + + blks + al->al_rgd->rd_length + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) goto out_ipres; @@ -1352,7 +1352,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index b2079fcd2513..e5069b912d5e 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -28,6 +28,14 @@ struct gfs2_sbd; typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); +struct gfs2_log_header_host { + u64 lh_sequence; /* Sequence number of this transaction */ + u32 lh_flags; /* GFS2_LOG_HEAD_... */ + u32 lh_tail; /* Block number of log tail */ + u32 lh_blkno; + u32 lh_hash; +}; + /* * Structure of operations that are associated with each * type of element in the log. @@ -60,12 +68,23 @@ struct gfs2_bitmap { u32 bi_len; }; +struct gfs2_rgrp_host { + u32 rg_flags; + u32 rg_free; + u32 rg_dinodes; + u64 rg_igeneration; +}; + struct gfs2_rgrpd { struct list_head rd_list; /* Link with superblock */ struct list_head rd_list_mru; struct list_head rd_recent; /* Recently used rgrps */ struct gfs2_glock *rd_gl; /* Glock for this rgrp */ - struct gfs2_rindex_host rd_ri; + u64 rd_addr; /* grp block disk address */ + u64 rd_data0; /* first data location */ + u32 rd_length; /* length of rgrp header in fs blocks */ + u32 rd_data; /* num of data blocks in rgrp */ + u32 rd_bitbytes; /* number of bytes in data bitmaps */ struct gfs2_rgrp_host rd_rg; u64 rd_rg_vn; struct gfs2_bitmap *rd_bits; @@ -211,6 +230,20 @@ enum { GIF_SW_PAGED = 3, }; +struct gfs2_dinode_host { + u64 di_size; /* number of bytes in file */ + u64 di_blocks; /* number of blocks in file */ + u64 di_goal_meta; /* rgrp to alloc from next */ + u64 di_goal_data; /* data block goal */ + u64 di_generation; /* generation number for NFS */ + u32 di_flags; /* GFS2_DIF_... */ + u16 di_height; /* height of metadata */ + /* These only apply to directories */ + u16 di_depth; /* Number of bits in the table */ + u32 di_entries; /* The number of entries in the directory */ + u64 di_eattr; /* extended attribute block number */ +}; + struct gfs2_inode { struct inode i_inode; u64 i_no_addr; @@ -346,6 +379,12 @@ struct gfs2_jdesc { unsigned int jd_blocks; }; +struct gfs2_statfs_change_host { + s64 sc_total; + s64 sc_free; + s64 sc_dinodes; +}; + #define GFS2_GLOCKD_DEFAULT 1 #define GFS2_GLOCKD_MAX 16 @@ -418,6 +457,28 @@ enum { #define GFS2_FSNAME_LEN 256 +struct gfs2_inum_host { + u64 no_formal_ino; + u64 no_addr; +}; + +struct gfs2_sb_host { + u32 sb_magic; + u32 sb_type; + u32 sb_format; + + u32 sb_fs_format; + u32 sb_multihost_format; + u32 sb_bsize; + u32 sb_bsize_shift; + + struct gfs2_inum_host sb_master_dir; + struct gfs2_inum_host sb_root_dir; + + char sb_lockproto[GFS2_LOCKNAME_LEN]; + char sb_locktable[GFS2_LOCKNAME_LEN]; +}; + struct gfs2_sbd { struct super_block *sd_vfs; struct super_block *sd_vfs_meta; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 58f5a67e1c35..a31a4b80ba3c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -38,6 +38,11 @@ #include "trans.h" #include "util.h" +struct gfs2_inum_range_host { + u64 ir_start; + u64 ir_length; +}; + static int iget_test(struct inode *inode, void *opaque) { struct gfs2_inode *ip = GFS2_I(inode); @@ -402,6 +407,22 @@ out: return inode ? inode : ERR_PTR(error); } +static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) +{ + const struct gfs2_inum_range *str = buf; + + ir->ir_start = be64_to_cpu(str->ir_start); + ir->ir_length = be64_to_cpu(str->ir_length); +} + +static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) +{ + struct gfs2_inum_range *str = buf; + + str->ir_start = cpu_to_be64(ir->ir_start); + str->ir_length = cpu_to_be64(ir->ir_length); +} + static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) { struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); @@ -741,7 +762,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, goto fail_quota_locks; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 2 * RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) @@ -1234,3 +1255,63 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) return error; } +void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) +{ + const struct gfs2_dinode_host *di = &ip->i_di; + struct gfs2_dinode *str = buf; + + str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); + str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); + str->di_header.__pad0 = 0; + str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); + str->di_header.__pad1 = 0; + str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); + str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); + str->di_mode = cpu_to_be32(ip->i_inode.i_mode); + str->di_uid = cpu_to_be32(ip->i_inode.i_uid); + str->di_gid = cpu_to_be32(ip->i_inode.i_gid); + str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); + str->di_size = cpu_to_be64(di->di_size); + str->di_blocks = cpu_to_be64(di->di_blocks); + str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); + str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); + str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); + + str->di_goal_meta = cpu_to_be64(di->di_goal_meta); + str->di_goal_data = cpu_to_be64(di->di_goal_data); + str->di_generation = cpu_to_be64(di->di_generation); + + str->di_flags = cpu_to_be32(di->di_flags); + str->di_height = cpu_to_be16(di->di_height); + str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && + !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? + GFS2_FORMAT_DE : 0); + str->di_depth = cpu_to_be16(di->di_depth); + str->di_entries = cpu_to_be32(di->di_entries); + + str->di_eattr = cpu_to_be64(di->di_eattr); +} + +void gfs2_dinode_print(const struct gfs2_inode *ip) +{ + const struct gfs2_dinode_host *di = &ip->i_di; + + printk(KERN_INFO " no_formal_ino = %llu\n", + (unsigned long long)ip->i_no_formal_ino); + printk(KERN_INFO " no_addr = %llu\n", + (unsigned long long)ip->i_no_addr); + printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); + printk(KERN_INFO " di_blocks = %llu\n", + (unsigned long long)di->di_blocks); + printk(KERN_INFO " di_goal_meta = %llu\n", + (unsigned long long)di->di_goal_meta); + printk(KERN_INFO " di_goal_data = %llu\n", + (unsigned long long)di->di_goal_data); + printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); + printk(KERN_INFO " di_height = %u\n", di->di_height); + printk(KERN_INFO " di_depth = %u\n", di->di_depth); + printk(KERN_INFO " di_entries = %u\n", di->di_entries); + printk(KERN_INFO " di_eattr = %llu\n", + (unsigned long long)di->di_eattr); +} + diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 05fc095d8540..35375fc43fa3 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -38,6 +38,14 @@ static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; } +static inline void gfs2_inum_out(const struct gfs2_inode *ip, + struct gfs2_dirent *dent) +{ + dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); + dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); +} + + void gfs2_inode_attr_in(struct gfs2_inode *ip); struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type); struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); @@ -59,6 +67,8 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); int gfs2_glock_nq_atime(struct gfs2_holder *gh); int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); +void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); +void gfs2_dinode_print(const struct gfs2_inode *ip); #endif /* __INODE_DOT_H__ */ diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c deleted file mode 100644 index a5b05ea3d4c7..000000000000 --- a/fs/gfs2/ondisk.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License version 2. - */ - -#include -#include -#include -#include - -#include "gfs2.h" -#include -#include -#include "incore.h" - -#define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ - struct->member); - -/* - * gfs2_xxx_in - read in an xxx struct - * first arg: the cpu-order structure - * buf: the disk-order buffer - * - * gfs2_xxx_out - write out an xxx struct - * first arg: the cpu-order structure - * buf: the disk-order buffer - * - * gfs2_xxx_print - print out an xxx struct - * first arg: the cpu-order structure - */ - -void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent) -{ - dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); - dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); -} - -static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) -{ - const struct gfs2_meta_header *str = buf; - - mh->mh_magic = be32_to_cpu(str->mh_magic); - mh->mh_type = be32_to_cpu(str->mh_type); - mh->mh_format = be32_to_cpu(str->mh_format); -} - -void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) -{ - const struct gfs2_sb *str = buf; - - gfs2_meta_header_in(&sb->sb_header, buf); - - sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); - sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); - sb->sb_bsize = be32_to_cpu(str->sb_bsize); - sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); - sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); - sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); - sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); - sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); - - memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); - memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); -} - -void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf) -{ - const struct gfs2_rindex *str = buf; - - ri->ri_addr = be64_to_cpu(str->ri_addr); - ri->ri_length = be32_to_cpu(str->ri_length); - ri->ri_data0 = be64_to_cpu(str->ri_data0); - ri->ri_data = be32_to_cpu(str->ri_data); - ri->ri_bitbytes = be32_to_cpu(str->ri_bitbytes); - -} - -void gfs2_rindex_print(const struct gfs2_rindex_host *ri) -{ - printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); - pv(ri, ri_length, "%u"); - - printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)ri->ri_data0); - pv(ri, ri_data, "%u"); - - pv(ri, ri_bitbytes, "%u"); -} - -void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) -{ - const struct gfs2_rgrp *str = buf; - - rg->rg_flags = be32_to_cpu(str->rg_flags); - rg->rg_free = be32_to_cpu(str->rg_free); - rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); - rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); -} - -void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) -{ - struct gfs2_rgrp *str = buf; - - str->rg_flags = cpu_to_be32(rg->rg_flags); - str->rg_free = cpu_to_be32(rg->rg_free); - str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); - str->__pad = cpu_to_be32(0); - str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); - memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); -} - -void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) -{ - const struct gfs2_quota *str = buf; - - qu->qu_limit = be64_to_cpu(str->qu_limit); - qu->qu_warn = be64_to_cpu(str->qu_warn); - qu->qu_value = be64_to_cpu(str->qu_value); -} - -void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf) -{ - struct gfs2_quota *str = buf; - - str->qu_limit = cpu_to_be64(qu->qu_limit); - str->qu_warn = cpu_to_be64(qu->qu_warn); - str->qu_value = cpu_to_be64(qu->qu_value); - memset(&str->qu_reserved, 0, sizeof(str->qu_reserved)); -} - -void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) -{ - const struct gfs2_dinode_host *di = &ip->i_di; - struct gfs2_dinode *str = buf; - - str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); - str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); - str->di_header.__pad0 = 0; - str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); - str->di_header.__pad1 = 0; - str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); - str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); - str->di_mode = cpu_to_be32(ip->i_inode.i_mode); - str->di_uid = cpu_to_be32(ip->i_inode.i_uid); - str->di_gid = cpu_to_be32(ip->i_inode.i_gid); - str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); - str->di_size = cpu_to_be64(di->di_size); - str->di_blocks = cpu_to_be64(di->di_blocks); - str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); - str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); - str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); - - str->di_goal_meta = cpu_to_be64(di->di_goal_meta); - str->di_goal_data = cpu_to_be64(di->di_goal_data); - str->di_generation = cpu_to_be64(di->di_generation); - - str->di_flags = cpu_to_be32(di->di_flags); - str->di_height = cpu_to_be16(di->di_height); - str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && - !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? - GFS2_FORMAT_DE : 0); - str->di_depth = cpu_to_be16(di->di_depth); - str->di_entries = cpu_to_be32(di->di_entries); - - str->di_eattr = cpu_to_be64(di->di_eattr); -} - -void gfs2_dinode_print(const struct gfs2_inode *ip) -{ - const struct gfs2_dinode_host *di = &ip->i_di; - - printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)ip->i_no_formal_ino); - printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)ip->i_no_addr); - - printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); - printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); - printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); - printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); - - pv(di, di_flags, "0x%.8X"); - pv(di, di_height, "%u"); - - pv(di, di_depth, "%u"); - pv(di, di_entries, "%u"); - - printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); -} - -void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) -{ - const struct gfs2_log_header *str = buf; - - gfs2_meta_header_in(&lh->lh_header, buf); - lh->lh_sequence = be64_to_cpu(str->lh_sequence); - lh->lh_flags = be32_to_cpu(str->lh_flags); - lh->lh_tail = be32_to_cpu(str->lh_tail); - lh->lh_blkno = be32_to_cpu(str->lh_blkno); - lh->lh_hash = be32_to_cpu(str->lh_hash); -} - -void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) -{ - const struct gfs2_inum_range *str = buf; - - ir->ir_start = be64_to_cpu(str->ir_start); - ir->ir_length = be64_to_cpu(str->ir_length); -} - -void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) -{ - struct gfs2_inum_range *str = buf; - - str->ir_start = cpu_to_be64(ir->ir_start); - str->ir_length = cpu_to_be64(ir->ir_length); -} - -void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) -{ - const struct gfs2_statfs_change *str = buf; - - sc->sc_total = be64_to_cpu(str->sc_total); - sc->sc_free = be64_to_cpu(str->sc_free); - sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); -} - -void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) -{ - struct gfs2_statfs_change *str = buf; - - str->sc_total = cpu_to_be64(sc->sc_total); - str->sc_free = cpu_to_be64(sc->sc_free); - str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); -} - -void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) -{ - const struct gfs2_quota_change *str = buf; - - qc->qc_change = be64_to_cpu(str->qc_change); - qc->qc_flags = be32_to_cpu(str->qc_flags); - qc->qc_id = be32_to_cpu(str->qc_id); -} - diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 51a8a14deb29..d07230ee5fc0 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c @@ -22,10 +22,18 @@ #include "glops.h" #include "inode.h" #include "ops_dentry.h" -#include "ops_export.h" +#include "ops_fstype.h" #include "rgrp.h" #include "util.h" +#define GFS2_SMALL_FH_SIZE 4 +#define GFS2_LARGE_FH_SIZE 10 + +struct gfs2_fh_obj { + struct gfs2_inum_host this; + u32 imode; +}; + static struct dentry *gfs2_decode_fh(struct super_block *sb, __u32 *p, int fh_len, diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h deleted file mode 100644 index f925a955b3b8..000000000000 --- a/fs/gfs2/ops_export.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License version 2. - */ - -#ifndef __OPS_EXPORT_DOT_H__ -#define __OPS_EXPORT_DOT_H__ - -#define GFS2_SMALL_FH_SIZE 4 -#define GFS2_LARGE_FH_SIZE 10 - -extern struct export_operations gfs2_export_ops; -struct gfs2_fh_obj { - struct gfs2_inum_host this; - __u32 imode; -}; - -#endif /* __OPS_EXPORT_DOT_H__ */ diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c682371717ff..0443e255173d 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -27,7 +27,6 @@ #include "inode.h" #include "lm.h" #include "mount.h" -#include "ops_export.h" #include "ops_fstype.h" #include "ops_super.h" #include "recovery.h" @@ -116,7 +115,6 @@ static void init_vfs(struct super_block *sb, unsigned noatime) static int init_names(struct gfs2_sbd *sdp, int silent) { - struct page *page; char *proto, *table; int error = 0; @@ -126,14 +124,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent) /* Try to autodetect */ if (!proto[0] || !table[0]) { - struct gfs2_sb *sb; - page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - if (!page) - return -ENOBUFS; - sb = kmap(page); - gfs2_sb_in(&sdp->sd_sb, sb); - kunmap(page); - __free_page(page); + error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + if (error) + return error; error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); if (error) diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h index 7cc2c296271b..407029b3b2b3 100644 --- a/fs/gfs2/ops_fstype.h +++ b/fs/gfs2/ops_fstype.h @@ -14,5 +14,6 @@ extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; +extern struct export_operations gfs2_export_ops; #endif /* __OPS_FSTYPE_DOT_H__ */ diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index f8ecfec4064b..919a661e4f79 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -206,7 +206,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, goto out_gunlock_q; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 2 * RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) @@ -711,7 +711,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, goto out_gunlock_q; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 4 * RES_DINODE + 4 * RES_LEAF + RES_STATFS + RES_QUOTA + 4, 0); if (error) diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index aa0dbd2aac1b..404b7cc9f8c4 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c @@ -66,7 +66,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) if (error) goto out_gunlock_q; - error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + + error = gfs2_trans_begin(sdp, al->al_rgd->rd_length + ind_blocks + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 8a58815dea08..6e546ee8f3d4 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -66,6 +66,18 @@ #define QUOTA_USER 1 #define QUOTA_GROUP 0 +struct gfs2_quota_host { + u64 qu_limit; + u64 qu_warn; + s64 qu_value; +}; + +struct gfs2_quota_change_host { + u64 qc_change; + u32 qc_flags; /* GFS2_QCF_... */ + u32 qc_id; +}; + static u64 qd2offset(struct gfs2_quota_data *qd) { u64 offset; @@ -561,6 +573,25 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) mutex_unlock(&sdp->sd_quota_mutex); } +static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) +{ + const struct gfs2_quota *str = buf; + + qu->qu_limit = be64_to_cpu(str->qu_limit); + qu->qu_warn = be64_to_cpu(str->qu_warn); + qu->qu_value = be64_to_cpu(str->qu_value); +} + +static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf) +{ + struct gfs2_quota *str = buf; + + str->qu_limit = cpu_to_be64(qu->qu_limit); + str->qu_warn = cpu_to_be64(qu->qu_warn); + str->qu_value = cpu_to_be64(qu->qu_value); + memset(&str->qu_reserved, 0, sizeof(str->qu_reserved)); +} + /** * gfs2_adjust_quota * @@ -694,7 +725,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) goto out_alloc; error = gfs2_trans_begin(sdp, - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + num_qd * data_blocks + nalloc * ind_blocks + RES_DINODE + num_qd + @@ -1055,6 +1086,15 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) return error; } +static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) +{ + const struct gfs2_quota_change *str = buf; + + qc->qc_change = be64_to_cpu(str->qc_change); + qc->qc_flags = be32_to_cpu(str->qc_flags); + qc->qc_id = be32_to_cpu(str->qc_id); +} + int gfs2_quota_init(struct gfs2_sbd *sdp) { struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 8bc182c7e2ef..5ada38c99a2c 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -116,6 +116,22 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp) } } +static int gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) +{ + const struct gfs2_log_header *str = buf; + + if (str->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || + str->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH)) + return 1; + + lh->lh_sequence = be64_to_cpu(str->lh_sequence); + lh->lh_flags = be32_to_cpu(str->lh_flags); + lh->lh_tail = be32_to_cpu(str->lh_tail); + lh->lh_blkno = be32_to_cpu(str->lh_blkno); + lh->lh_hash = be32_to_cpu(str->lh_hash); + return 0; +} + /** * get_log_header - read the log header for a given segment * @jd: the journal @@ -147,12 +163,10 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, sizeof(u32)); hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); hash ^= (u32)~0; - gfs2_log_header_in(&lh, bh->b_data); + error = gfs2_log_header_in(&lh, bh->b_data); brelse(bh); - if (lh.lh_header.mh_magic != GFS2_MAGIC || - lh.lh_header.mh_type != GFS2_METATYPE_LH || - lh.lh_blkno != blk || lh.lh_hash != hash) + if (error || lh.lh_blkno != blk || lh.lh_hash != hash) return 1; *head = lh; diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 30eb428065c5..027f6ec5b0d9 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -204,7 +204,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_bitmap *bi = NULL; - u32 length = rgd->rd_ri.ri_length; + u32 length = rgd->rd_length; u32 count[4], tmp; int buf, x; @@ -227,7 +227,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) return; } - tmp = rgd->rd_ri.ri_data - + tmp = rgd->rd_data - rgd->rd_rg.rg_free - rgd->rd_rg.rg_dinodes; if (count[1] + count[2] != tmp) { @@ -253,10 +253,10 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) } -static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) +static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) { - u64 first = ri->ri_data0; - u64 last = first + ri->ri_data; + u64 first = rgd->rd_data0; + u64 last = first + rgd->rd_data; return first <= block && block < last; } @@ -275,7 +275,7 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) spin_lock(&sdp->sd_rindex_spin); list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { - if (rgrp_contains_block(&rgd->rd_ri, blk)) { + if (rgrp_contains_block(rgd, blk)) { list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); spin_unlock(&sdp->sd_rindex_spin); return rgd; @@ -354,6 +354,15 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) mutex_unlock(&sdp->sd_rindex_mutex); } +static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) +{ + printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); + printk(KERN_INFO " ri_length = %u\n", rgd->rd_length); + printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0); + printk(KERN_INFO " ri_data = %u\n", rgd->rd_data); + printk(KERN_INFO " ri_bitbytes = %u\n", rgd->rd_bitbytes); +} + /** * gfs2_compute_bitstructs - Compute the bitmap sizes * @rgd: The resource group descriptor @@ -367,7 +376,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_bitmap *bi; - u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ + u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */ u32 bytes_left, bytes; int x; @@ -378,7 +387,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) if (!rgd->rd_bits) return -ENOMEM; - bytes_left = rgd->rd_ri.ri_bitbytes; + bytes_left = rgd->rd_bitbytes; for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; @@ -399,14 +408,14 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) } else if (x + 1 == length) { bytes = bytes_left; bi->bi_offset = sizeof(struct gfs2_meta_header); - bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bi->bi_start = rgd->rd_bitbytes - bytes_left; bi->bi_len = bytes; /* other blocks */ } else { bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); bi->bi_offset = sizeof(struct gfs2_meta_header); - bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bi->bi_start = rgd->rd_bitbytes - bytes_left; bi->bi_len = bytes; } @@ -418,9 +427,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) return -EIO; } bi = rgd->rd_bits + (length - 1); - if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) { + if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_data) { if (gfs2_consist_rgrpd(rgd)) { - gfs2_rindex_print(&rgd->rd_ri); + gfs2_rindex_print(rgd); fs_err(sdp, "start=%u len=%u offset=%u\n", bi->bi_start, bi->bi_len, bi->bi_offset); } @@ -431,6 +440,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) } /** + * gfs2_ri_total - Total up the file system space, according to the rindex. * */ @@ -439,7 +449,6 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) u64 total_data = 0; struct inode *inode = sdp->sd_rindex; struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_rindex_host ri; char buf[sizeof(struct gfs2_rindex)]; struct file_ra_state ra_state; int error, rgrps; @@ -455,13 +464,23 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) sizeof(struct gfs2_rindex)); if (error != sizeof(struct gfs2_rindex)) break; - gfs2_rindex_in(&ri, buf); - total_data += ri.ri_data; + total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data); } mutex_unlock(&sdp->sd_rindex_mutex); return total_data; } +static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf) +{ + const struct gfs2_rindex *str = buf; + + rgd->rd_addr = be64_to_cpu(str->ri_addr); + rgd->rd_length = be32_to_cpu(str->ri_length); + rgd->rd_data0 = be64_to_cpu(str->ri_data0); + rgd->rd_data = be32_to_cpu(str->ri_data); + rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); +} + /** * read_rindex_entry - Pull in a new resource index entry from the disk * @gl: The glock covering the rindex inode @@ -500,12 +519,12 @@ static int read_rindex_entry(struct gfs2_inode *ip, list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); - gfs2_rindex_in(&rgd->rd_ri, buf); + gfs2_rindex_in(rgd, buf); error = compute_bitstructs(rgd); if (error) return error; - error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, + error = gfs2_glock_get(sdp, rgd->rd_addr, &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); if (error) return error; @@ -626,6 +645,28 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) return error; } +static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) +{ + const struct gfs2_rgrp *str = buf; + + rg->rg_flags = be32_to_cpu(str->rg_flags); + rg->rg_free = be32_to_cpu(str->rg_free); + rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); + rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); +} + +static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) +{ + struct gfs2_rgrp *str = buf; + + str->rg_flags = cpu_to_be32(rg->rg_flags); + str->rg_free = cpu_to_be32(rg->rg_free); + str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); + str->__pad = cpu_to_be32(0); + str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); + memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); +} + /** * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps * @rgd: the struct gfs2_rgrpd describing the RG to read in @@ -640,7 +681,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_glock *gl = rgd->rd_gl; - unsigned int length = rgd->rd_ri.ri_length; + unsigned int length = rgd->rd_length; struct gfs2_bitmap *bi; unsigned int x, y; int error; @@ -658,7 +699,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; - error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh); + error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); if (error) goto fail; } @@ -720,7 +761,7 @@ void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd) void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; - int x, length = rgd->rd_ri.ri_length; + int x, length = rgd->rd_length; spin_lock(&sdp->sd_rindex_spin); gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); @@ -743,7 +784,7 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; - unsigned int length = rgd->rd_ri.ri_length; + unsigned int length = rgd->rd_length; unsigned int x; for (x = 0; x < length; x++) { @@ -826,7 +867,7 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, goto first; list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { - if (rgd->rd_ri.ri_addr == rglast) + if (rgd->rd_addr == rglast) goto out; } @@ -1037,7 +1078,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) } out: - ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; + ip->i_last_rg_alloc = rgd->rd_addr; if (begin) { recent_rgrp_add(rgd); @@ -1128,8 +1169,8 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) unsigned int buf; unsigned char type; - length = rgd->rd_ri.ri_length; - rgrp_block = block - rgd->rd_ri.ri_data0; + length = rgd->rd_length; + rgrp_block = block - rgd->rd_data0; for (buf = 0; buf < length; buf++) { bi = rgd->rd_bits + buf; @@ -1171,7 +1212,7 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char old_state, unsigned char new_state) { struct gfs2_bitmap *bi = NULL; - u32 length = rgd->rd_ri.ri_length; + u32 length = rgd->rd_length; u32 blk = 0; unsigned int buf, x; @@ -1247,9 +1288,9 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, return NULL; } - length = rgd->rd_ri.ri_length; + length = rgd->rd_length; - rgrp_blk = bstart - rgd->rd_ri.ri_data0; + rgrp_blk = bstart - rgd->rd_data0; while (blen--) { for (buf = 0; buf < length; buf++) { @@ -1293,15 +1334,15 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) u32 goal, blk; u64 block; - if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data)) - goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0; + if (rgrp_contains_block(rgd, ip->i_di.di_goal_data)) + goal = ip->i_di.di_goal_data - rgd->rd_data0; else goal = rgd->rd_last_alloc_data; blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_data = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; ip->i_di.di_goal_data = block; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); @@ -1337,15 +1378,15 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) u32 goal, blk; u64 block; - if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta)) - goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0; + if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta)) + goal = ip->i_di.di_goal_meta - rgd->rd_data0; else goal = rgd->rd_last_alloc_meta; blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_meta = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; ip->i_di.di_goal_meta = block; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); @@ -1387,7 +1428,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) rgd->rd_last_alloc_meta = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); rgd->rd_rg.rg_free--; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index faccffd19907..f916b9740c75 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -95,8 +95,8 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) { unsigned int x; - if (sb->sb_header.mh_magic != GFS2_MAGIC || - sb->sb_header.mh_type != GFS2_METATYPE_SB) { + if (sb->sb_magic != GFS2_MAGIC || + sb->sb_type != GFS2_METATYPE_SB) { if (!silent) printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); return -EINVAL; @@ -174,10 +174,31 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) return 0; } +static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) +{ + const struct gfs2_sb *str = buf; + + sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); + sb->sb_type = be32_to_cpu(str->sb_header.mh_type); + sb->sb_format = be32_to_cpu(str->sb_header.mh_format); + sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); + sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); + sb->sb_bsize = be32_to_cpu(str->sb_bsize); + sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); + sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); + sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); + sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); + sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); + + memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); + memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); +} + /** * gfs2_read_super - Read the gfs2 super block from disk - * @sb: The VFS super block + * @sdp: The GFS2 super block * @sector: The location of the super block + * @error: The error code to return * * This uses the bio functions to read the super block from disk * because we want to be 100% sure that we never read cached data. @@ -189,17 +210,19 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) * the master directory (contains pointers to journals etc) and the * root directory. * - * Returns: A page containing the sb or NULL + * Returns: 0 on success or error */ -struct page *gfs2_read_super(struct super_block *sb, sector_t sector) +int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) { + struct super_block *sb = sdp->sd_vfs; + struct gfs2_sb *p; struct page *page; struct bio *bio; page = alloc_page(GFP_KERNEL); if (unlikely(!page)) - return NULL; + return -ENOBUFS; ClearPageUptodate(page); ClearPageDirty(page); @@ -208,7 +231,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) bio = bio_alloc(GFP_KERNEL, 1); if (unlikely(!bio)) { __free_page(page); - return NULL; + return -ENOBUFS; } bio->bi_sector = sector * (sb->s_blocksize >> 9); @@ -222,9 +245,13 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) bio_put(bio); if (!PageUptodate(page)) { __free_page(page); - return NULL; + return -EIO; } - return page; + p = kmap(page); + gfs2_sb_in(&sdp->sd_sb, p); + kunmap(page); + __free_page(page); + return 0; } /** @@ -241,19 +268,13 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) u32 tmp_blocks; unsigned int x; int error; - struct page *page; - char *sb; - page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - if (!page) { + error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + if (error) { if (!silent) fs_err(sdp, "can't read superblock\n"); - return -EIO; + return error; } - sb = kmap(page); - gfs2_sb_in(&sdp->sd_sb, sb); - kunmap(page); - __free_page(page); error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); if (error) @@ -593,6 +614,24 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) return error; } +static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) +{ + const struct gfs2_statfs_change *str = buf; + + sc->sc_total = be64_to_cpu(str->sc_total); + sc->sc_free = be64_to_cpu(str->sc_free); + sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); +} + +static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) +{ + struct gfs2_statfs_change *str = buf; + + str->sc_total = cpu_to_be64(sc->sc_total); + str->sc_free = cpu_to_be64(sc->sc_free); + str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); +} + int gfs2_statfs_init(struct gfs2_sbd *sdp) { struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); @@ -772,7 +811,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, struct gfs2_statfs_change_host *sc) { gfs2_rgrp_verify(rgd); - sc->sc_total += rgd->rd_ri.ri_data; + sc->sc_total += rgd->rd_data; sc->sc_free += rgd->rd_rg.rg_free; sc->sc_dinodes += rgd->rd_rg.rg_dinodes; return 0; diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index e590b2df11dc..60a870e430be 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h @@ -16,7 +16,7 @@ void gfs2_tune_init(struct gfs2_tune *gt); int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); -struct page *gfs2_read_super(struct super_block *sb, sector_t sector); +int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector); static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) { diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 3f5edc54e80a..424a0774eda8 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -137,7 +137,7 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide, "GFS2: fsid=%s: RG = %llu\n" "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", sdp->sd_fsname, - sdp->sd_fsname, (unsigned long long)rgd->rd_ri.ri_addr, + sdp->sd_fsname, (unsigned long long)rgd->rd_addr, sdp->sd_fsname, function, file, line); return rv; } diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 01cc35946a9d..2c4e24fb0765 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -54,11 +54,6 @@ struct gfs2_inum { __be64 no_addr; }; -struct gfs2_inum_host { - __u64 no_formal_ino; - __u64 no_addr; -}; - /* * Generic metadata head structure * Every inplace buffer logged in the journal must start with this. @@ -87,12 +82,6 @@ struct gfs2_meta_header { __be32 __pad1; /* Was incarnation number in gfs1 */ }; -struct gfs2_meta_header_host { - __u32 mh_magic; - __u32 mh_type; - __u32 mh_format; -}; - /* * super-block structure * @@ -132,23 +121,6 @@ struct gfs2_sb { /* In gfs1, quota and license dinodes followed */ }; -struct gfs2_sb_host { - struct gfs2_meta_header_host sb_header; - - __u32 sb_fs_format; - __u32 sb_multihost_format; - - __u32 sb_bsize; - __u32 sb_bsize_shift; - - struct gfs2_inum_host sb_master_dir; /* Was jindex dinode in gfs1 */ - struct gfs2_inum_host sb_root_dir; - - char sb_lockproto[GFS2_LOCKNAME_LEN]; - char sb_locktable[GFS2_LOCKNAME_LEN]; - /* In gfs1, quota and license dinodes followed */ -}; - /* * resource index structure */ @@ -166,14 +138,6 @@ struct gfs2_rindex { __u8 ri_reserved[64]; }; -struct gfs2_rindex_host { - __u64 ri_addr; /* grp block disk address */ - __u64 ri_data0; /* first data location */ - __u32 ri_length; /* length of rgrp header in fs blocks */ - __u32 ri_data; /* num of data blocks in rgrp */ - __u32 ri_bitbytes; /* number of bytes in data bitmaps */ -}; - /* * resource group header structure */ @@ -205,13 +169,6 @@ struct gfs2_rgrp { __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */ }; -struct gfs2_rgrp_host { - __u32 rg_flags; - __u32 rg_free; - __u32 rg_dinodes; - __u64 rg_igeneration; -}; - /* * quota structure */ @@ -223,12 +180,6 @@ struct gfs2_quota { __u8 qu_reserved[64]; }; -struct gfs2_quota_host { - __u64 qu_limit; - __u64 qu_warn; - __u64 qu_value; -}; - /* * dinode structure */ @@ -312,27 +263,6 @@ struct gfs2_dinode { __u8 di_reserved[56]; }; -struct gfs2_dinode_host { - __u64 di_size; /* number of bytes in file */ - __u64 di_blocks; /* number of blocks in file */ - - /* This section varies from gfs1. Padding added to align with - * remainder of dinode - */ - __u64 di_goal_meta; /* rgrp to alloc from next */ - __u64 di_goal_data; /* data block goal */ - __u64 di_generation; /* generation number for NFS */ - - __u32 di_flags; /* GFS2_DIF_... */ - __u16 di_height; /* height of metadata */ - - /* These only apply to directories */ - __u16 di_depth; /* Number of bits in the table */ - __u32 di_entries; /* The number of entries in the directory */ - - __u64 di_eattr; /* extended attribute block number */ -}; - /* * directory structure - many of these per directory file */ @@ -407,16 +337,6 @@ struct gfs2_log_header { __be32 lh_hash; }; -struct gfs2_log_header_host { - struct gfs2_meta_header_host lh_header; - - __u64 lh_sequence; /* Sequence number of this transaction */ - __u32 lh_flags; /* GFS2_LOG_HEAD_... */ - __u32 lh_tail; /* Block number of log tail */ - __u32 lh_blkno; - __u32 lh_hash; -}; - /* * Log type descriptor */ @@ -457,11 +377,6 @@ struct gfs2_inum_range { __be64 ir_length; }; -struct gfs2_inum_range_host { - __u64 ir_start; - __u64 ir_length; -}; - /* * Statfs change * Describes an change to the pool of free and allocated @@ -474,12 +389,6 @@ struct gfs2_statfs_change { __be64 sc_dinodes; }; -struct gfs2_statfs_change_host { - __u64 sc_total; - __u64 sc_free; - __u64 sc_dinodes; -}; - /* * Quota change * Describes an allocation change for a particular @@ -494,12 +403,6 @@ struct gfs2_quota_change { __be32 qc_id; }; -struct gfs2_quota_change_host { - __u64 qc_change; - __u32 qc_flags; /* GFS2_QCF_... */ - __u32 qc_id; -}; - struct gfs2_quota_lvb { __be32 qb_magic; __u32 __pad; @@ -508,34 +411,4 @@ struct gfs2_quota_lvb { __be64 qb_value; /* Current # blocks allocated */ }; -#ifdef __KERNEL__ -/* Translation functions */ -struct gfs2_inode; - -extern void gfs2_inum_out(const struct gfs2_inode *ip, struct gfs2_dirent *dent); -extern void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf); -extern void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf); -extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf); -extern void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf); -extern void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf); -extern void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf); -extern void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf); -struct gfs2_inode; -extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); -extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, const void *buf); -extern void gfs2_ea_header_out(const struct gfs2_ea_header *ea, void *buf); -extern void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf); -extern void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf); -extern void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf); -extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf); -extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf); -extern void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf); - -/* Printing functions */ - -extern void gfs2_rindex_print(const struct gfs2_rindex_host *ri); -extern void gfs2_dinode_print(const struct gfs2_inode *ip); - -#endif /* __KERNEL__ */ - #endif /* __GFS2_ONDISK_DOT_H__ */ From 4bd91ba18198eee42c39d4c334c825d1a0a4b445 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 5 Jun 2007 09:39:18 +0100 Subject: [PATCH 159/551] [GFS2] Add nanosecond timestamp feature This adds a nanosecond timestamp feature to the GFS2 filesystem. Due to the way that the on-disk format works, older filesystems will just appear to have this field set to zero. When mounted by an older version of GFS2, the filesystem will simply ignore the extra fields so that it will again appear to have whole second resolution, so that its trivially backward compatible. Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 10 +++++----- fs/gfs2/dir.c | 10 +++++----- fs/gfs2/eattr.c | 8 ++++---- fs/gfs2/inode.c | 30 +++++++++++++++++++----------- fs/gfs2/ops_fstype.c | 1 + fs/gfs2/ops_inode.c | 2 +- include/linux/gfs2_ondisk.h | 5 ++++- 7 files changed, 39 insertions(+), 27 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index b784cf3c6482..d16044cb023a 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -772,7 +772,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, gfs2_free_data(ip, bstart, blen); } - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, dibh->b_data); @@ -847,7 +847,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) } ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; error = gfs2_meta_inode_buffer(ip, &dibh); if (error) @@ -958,7 +958,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) if (gfs2_is_stuffed(ip)) { ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); @@ -970,7 +970,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) if (!error) { ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -1043,7 +1043,7 @@ static int trunc_end(struct gfs2_inode *ip) ip->i_no_addr; gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); } - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; gfs2_trans_add_bh(ip->i_gl, dibh, 1); diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 2f154049b59d..f793e31a050e 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); if (ip->i_di.di_size < offset + size) ip->i_di.di_size = offset + size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -228,7 +228,7 @@ out: if (ip->i_di.di_size < offset + copied) ip->i_di.di_size = offset + copied; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -1622,7 +1622,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, break; gfs2_trans_add_bh(ip->i_gl, bh, 1); ip->i_di.di_entries++; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, bh->b_data); brelse(bh); error = 0; @@ -1708,7 +1708,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) gfs2_consist_inode(dip); gfs2_trans_add_bh(dip->i_gl, bh, 1); dip->i_di.di_entries--; - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(dip, bh->b_data); brelse(bh); mark_inode_dirty(&dip->i_inode); @@ -1756,7 +1756,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, gfs2_trans_add_bh(dip->i_gl, bh, 1); } - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(dip, bh->b_data); brelse(bh); return 0; diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 40e1d37112e6..2a7435b5c4dc 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -300,7 +300,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -717,7 +717,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, (er->er_mode & S_IFMT)); ip->i_inode.i_mode = er->er_mode; } - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -852,7 +852,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh, (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); ip->i_inode.i_mode = er->er_mode; } - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -1133,7 +1133,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el) error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index a31a4b80ba3c..3ef0f051d076 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -178,11 +178,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) di->di_blocks = be64_to_cpu(str->di_blocks); gfs2_set_inode_blocks(&ip->i_inode); ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); - ip->i_inode.i_atime.tv_nsec = 0; + ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); - ip->i_inode.i_mtime.tv_nsec = 0; + ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); - ip->i_inode.i_ctime.tv_nsec = 0; + ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); di->di_goal_meta = be64_to_cpu(str->di_goal_meta); di->di_goal_data = be64_to_cpu(str->di_goal_data); @@ -317,7 +317,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) else drop_nlink(&ip->i_inode); - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -648,6 +648,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_dinode *di; struct buffer_head *dibh; + struct timespec tv = CURRENT_TIME; dibh = gfs2_meta_new(gl, inum->no_addr); gfs2_trans_add_bh(gl, dibh, 1); @@ -663,7 +664,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, di->di_nlink = 0; di->di_size = 0; di->di_blocks = cpu_to_be64(1); - di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); + di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); di->di_major = cpu_to_be32(MAJOR(dev)); di->di_minor = cpu_to_be32(MINOR(dev)); di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); @@ -693,6 +694,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, di->di_entries = 0; memset(&di->__pad4, 0, sizeof(di->__pad4)); di->di_eattr = 0; + di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); + di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); + di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); memset(&di->di_reserved, 0, sizeof(di->di_reserved)); brelse(dibh); @@ -1135,10 +1139,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) struct gfs2_glock *gl = gh->gh_gl; struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_inode *ip = gl->gl_object; - s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum); + s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); unsigned int state; int flags; int error; + struct timespec tv = CURRENT_TIME; if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || @@ -1156,8 +1161,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) (sdp->sd_vfs->s_flags & MS_RDONLY)) return 0; - curtime = get_seconds(); - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { gfs2_glock_dq(gh); gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, gh); @@ -1168,8 +1172,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) /* Verify that atime hasn't been updated while we were trying to get exclusive lock. */ - curtime = get_seconds(); - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { + tv = CURRENT_TIME; + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { struct buffer_head *dibh; struct gfs2_dinode *di; @@ -1183,11 +1187,12 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) if (error) goto fail_end_trans; - ip->i_inode.i_atime.tv_sec = curtime; + ip->i_inode.i_atime = tv; gfs2_trans_add_bh(ip->i_gl, dibh, 1); di = (struct gfs2_dinode *)dibh->b_data; di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); + di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); brelse(dibh); gfs2_trans_end(sdp); @@ -1290,6 +1295,9 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) str->di_entries = cpu_to_be32(di->di_entries); str->di_eattr = cpu_to_be64(di->di_eattr); + str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); + str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); + str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); } void gfs2_dinode_print(const struct gfs2_inode *ip) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 0443e255173d..b46727275e58 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -104,6 +104,7 @@ static void init_vfs(struct super_block *sb, unsigned noatime) sb->s_magic = GFS2_MAGIC; sb->s_op = &gfs2_super_ops; sb->s_export_op = &gfs2_export_ops; + sb->s_time_gran = 1; sb->s_maxbytes = MAX_LFS_FILESIZE; if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 919a661e4f79..9cc07f442ef5 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -757,7 +757,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, error = gfs2_meta_inode_buffer(ip, &dibh); if (error) goto out_end_trans; - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index 2c4e24fb0765..a44a6a078f0a 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -259,8 +259,11 @@ struct gfs2_dinode { struct gfs2_inum __pad4; /* Unused even in current gfs1 */ __be64 di_eattr; /* extended attribute block number */ + __be32 di_atime_nsec; /* nsec portion of atime */ + __be32 di_mtime_nsec; /* nsec portion of mtime */ + __be32 di_ctime_nsec; /* nsec portion of ctime */ - __u8 di_reserved[56]; + __u8 di_reserved[44]; }; /* From 292e539e9386823df8aab556f3da09667f78da8c Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 5 Jun 2007 17:36:38 -0400 Subject: [PATCH 160/551] [DLM] fix reference counting This is a fix for the patch 021d2ff3a08019260a1dc002793c92d6bf18afb6 I left off a dlm_hold_rsb which causes the box to panic if you try to use debugfs. This patch fixes the problem. Sorry about that, Signed-off-by: Josef Bacik Signed-off-by: Steven Whitehouse --- fs/dlm/debug_fs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 184be9870c63..9f5de37706a9 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -250,6 +250,7 @@ static int rsb_iter_next(struct rsb_iter *ri) goto top; } ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain); + dlm_hold_rsb(ri->rsb); read_unlock(&ls->ls_rsbtbl[i].lock); dlm_put_rsb(old); } From 44f487a5536a3afd96a9f571de24c36559e9ae82 Mon Sep 17 00:00:00 2001 From: Patrick Caulfield Date: Wed, 6 Jun 2007 09:21:22 -0500 Subject: [PATCH 161/551] [DLM] variable allocation Add a new flag, DLM_LSFL_FS, to be used when a file system creates a lockspace. This flag causes the dlm to use GFP_NOFS for allocations instead of GFP_KERNEL. (This updated version of the patch uses gfp_t for ls_allocation.) Signed-Off-By: Patrick Caulfield Signed-Off-By: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/dlm_internal.h | 1 + fs/dlm/lock.c | 2 +- fs/dlm/lockspace.c | 5 +++++ fs/dlm/rcom.c | 9 +++++---- fs/gfs2/locking/dlm/mount.c | 2 +- include/linux/dlm.h | 1 + 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index f2c85493c0c6..8ac081882c78 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -463,6 +463,7 @@ struct dlm_ls { int ls_low_nodeid; int ls_total_weight; int *ls_node_array; + gfp_t ls_allocation; struct dlm_rsb ls_stub_rsb; /* for returning errors */ struct dlm_lkb ls_stub_lkb; /* for returning errors */ diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index de943afacb37..b455919c1998 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -2594,7 +2594,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len, pass into lowcomms_commit and a message buffer (mb) that we write our data into */ - mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) return -ENOBUFS; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index c8f0c15ac166..6802653473d1 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -444,6 +444,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace, set_bit(LSFL_TIMEWARN, &ls->ls_flags); ls->ls_exflags = (flags & ~DLM_LSFL_TIMEWARN); + if (flags & DLM_LSFL_FS) + ls->ls_allocation = GFP_NOFS; + else + ls->ls_allocation = GFP_KERNEL; + size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index f71c23542f0f..e3a1527cbdbe 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -38,7 +38,7 @@ static int create_rcom(struct dlm_ls *ls, int to_nodeid, int type, int len, char *mb; int mb_len = sizeof(struct dlm_rcom) + len; - mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) { log_print("create_rcom to %d type %d len %d ENOBUFS", to_nodeid, type, len); @@ -386,7 +386,8 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) dlm_recover_process_copy(ls, rc_in); } -static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) +static int send_ls_not_ready(struct dlm_ls *ls, int nodeid, + struct dlm_rcom *rc_in) { struct dlm_rcom *rc; struct rcom_config *rf; @@ -394,7 +395,7 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) char *mb; int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); - mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) return -ENOBUFS; memset(mb, 0, mb_len); @@ -464,7 +465,7 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid) log_print("lockspace %x from %d type %x not found", hd->h_lockspace, nodeid, rc->rc_type); if (rc->rc_type == DLM_RCOM_STATUS) - send_ls_not_ready(nodeid, rc); + send_ls_not_ready(ls, nodeid, rc); return; } diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 1d8faa3da8af..41c5b04caaba 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c @@ -147,7 +147,7 @@ static int gdlm_mount(char *table_name, char *host_data, error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), &ls->dlm_lockspace, - nodir ? DLM_LSFL_NODIR : 0, + DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), GDLM_LVB_SIZE); if (error) { log_error("dlm_new_lockspace error %d", error); diff --git a/include/linux/dlm.h b/include/linux/dlm.h index 5227a9594f9d..be9d278761e0 100644 --- a/include/linux/dlm.h +++ b/include/linux/dlm.h @@ -206,6 +206,7 @@ struct dlm_lksb { #define DLM_LSFL_NODIR 0x00000001 #define DLM_LSFL_TIMEWARN 0x00000002 +#define DLM_LSFL_FS 0x00000004 #ifdef __KERNEL__ From ffed8ab342e39b8b5f4d5c94c37a708e225ffcd8 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 7 Jun 2007 11:29:35 +0100 Subject: [PATCH 162/551] [GFS2] Fix typo in rename of directories A typo caused us to pass a NULL pointer when renaming directories. It was accidentally introduced in: [GFS2] Clean up inode number handling Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 9cc07f442ef5..84051b997a43 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -749,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, if (error) goto out_end_trans; - error = gfs2_dir_mvino(ip, &name, nip, DT_DIR); + error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); if (error) goto out_end_trans; } else { From e1cc86037b689a82cdb2df50c32fa8cf9d6b6c3a Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 7 Jun 2007 11:47:52 +0100 Subject: [PATCH 163/551] [GFS2] Fix bug in error path of inode This fixes a bug in the ordering of operations in the error path of createi. Its not valid to do an iput() when holding the inode's glock since the iput() will (in this case) result in delete_inode() being called which needs to grab the lock itself. This was causing the recursive lock checking code to trigger. Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 3ef0f051d076..87505f7eb745 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -857,7 +857,7 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, unsigned int mode, dev_t dev) { - struct inode *inode; + struct inode *inode = NULL; struct gfs2_inode *dip = ghs->gh_gl->gl_object; struct inode *dir = &dip->i_inode; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); @@ -900,28 +900,28 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, error = gfs2_inode_refresh(GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = gfs2_acl_create(dip, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = gfs2_security_init(dip, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = link_dinode(dip, name, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; if (!inode) return ERR_PTR(-ENOMEM); return inode; -fail_iput: - iput(inode); fail_gunlock2: gfs2_glock_dq_uninit(ghs + 1); + if (inode) + iput(inode); fail_gunlock: gfs2_glock_dq(ghs); fail: From b35997d4482ed24b43a5951c5b021d224b24293c Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Thu, 7 Jun 2007 09:10:01 -0500 Subject: [PATCH 164/551] [GFS2] Can't mount GFS2 file system on AoE device This patch fixes bug 243131: Can't mount GFS2 file system on AoE device. When using AoE devices with lock_nolock, there is no locking table, so gfs2 (and gfs1) uses the superblock s_id. This turns out to be the device name in some cases. In the case of AoE, the device contains a slash, (e.g. "etherd/e1.1p2") which is an invalid character when we try to register the table in sysfs. This patch replaces the "/" with underscore. Rather than add a new variable to the stack, I'm just reusing a (char *) variable that's no longer used: table. This code has been tested on the failing system using a RHEL5 patch. The upstream code was tested by using gfs2_tool sb to interject a "/" into the table name of a clustered gfs2 file system. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_fstype.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index b46727275e58..dae1d7142fe5 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -145,6 +145,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent) snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); + while ((table = strchr(sdp->sd_table_name, '/'))) + *table = '_'; + out: return error; } From c8cdf479377462315d6b4f56379f8ac989b0ef29 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 8 Jun 2007 10:05:33 +0100 Subject: [PATCH 165/551] [GFS2] Recovery for lost unlinked inodes Under certain circumstances its possible (though rather unlikely) that inodes which were unlinked by one node while still open on another might get "lost" in the sense that they don't get deallocated if the node which held the inode open crashed before it was unlinked. This patch adds the recovery code which allows automatic deallocation of the inode if its found during block allocation (the sensible time to look for such inodes since we are scanning the rgrp's bitmaps anyway at this time, so it adds no overhead to do this). Since the inode will have had its i_nlink set to zero, all we need to trigger recovery is a lookup and an iput(), and the normal deallocation code takes care of the rest. Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 2 ++ fs/gfs2/inode.c | 50 +++++++++++++++++++--------- fs/gfs2/rgrp.c | 87 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 107 insertions(+), 32 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index e5069b912d5e..c7c6ec0f17c7 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -95,6 +95,8 @@ struct gfs2_rgrpd { u32 rd_last_alloc_data; u32 rd_last_alloc_meta; struct gfs2_sbd *rd_sbd; + unsigned long rd_flags; +#define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */ }; enum gfs2_state_bits { diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 87505f7eb745..cacdb0dfe577 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -98,22 +98,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in if (inode->i_state & I_NEW) { struct gfs2_sbd *sdp = GFS2_SB(inode); - umode_t mode = DT2IF(type); + umode_t mode; inode->i_private = ip; - inode->i_mode = mode; - - if (S_ISREG(mode)) { - inode->i_op = &gfs2_file_iops; - inode->i_fop = &gfs2_file_fops; - inode->i_mapping->a_ops = &gfs2_file_aops; - } else if (S_ISDIR(mode)) { - inode->i_op = &gfs2_dir_iops; - inode->i_fop = &gfs2_dir_fops; - } else if (S_ISLNK(mode)) { - inode->i_op = &gfs2_symlink_iops; - } else { - inode->i_op = &gfs2_dev_iops; - } error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); if (unlikely(error)) @@ -130,10 +116,44 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in goto fail_iopen; gfs2_glock_put(io_gl); + + /* + * We must read the inode in order to work out its type in + * this case. Note that this doesn't happen often as we normally + * know the type beforehand. This code path only occurs during + * unlinked inode recovery (where it is safe to do this glock, + * which is not true in the general case). + */ + inode->i_mode = mode = DT2IF(type); + if (type == DT_UNKNOWN) { + struct gfs2_holder gh; + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (unlikely(error)) + goto fail_glock; + /* Inode is now uptodate */ + mode = inode->i_mode; + gfs2_glock_dq_uninit(&gh); + } + + if (S_ISREG(mode)) { + inode->i_op = &gfs2_file_iops; + inode->i_fop = &gfs2_file_fops; + inode->i_mapping->a_ops = &gfs2_file_aops; + } else if (S_ISDIR(mode)) { + inode->i_op = &gfs2_dir_iops; + inode->i_fop = &gfs2_dir_fops; + } else if (S_ISLNK(mode)) { + inode->i_op = &gfs2_symlink_iops; + } else { + inode->i_op = &gfs2_dev_iops; + } + unlock_new_inode(inode); } return inode; +fail_glock: + gfs2_glock_dq(&ip->i_iopen_gh); fail_iopen: gfs2_glock_put(io_gl); fail_put: diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 027f6ec5b0d9..fd3fd9074779 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -28,6 +28,7 @@ #include "ops_file.h" #include "util.h" #include "log.h" +#include "inode.h" #define BFITNOENT ((u32)~0) @@ -50,6 +51,9 @@ static const char valid_change[16] = { 1, 0, 0, 0 }; +static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, + unsigned char old_state, unsigned char new_state); + /** * gfs2_setbit - Set a bit in the bitmaps * @buffer: the buffer that holds the bitmaps @@ -531,6 +535,7 @@ static int read_rindex_entry(struct gfs2_inode *ip, rgd->rd_gl->gl_object = rgd; rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + rgd->rd_flags |= GFS2_RDF_CHECK; return error; } @@ -845,6 +850,37 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) return ret; } +/** + * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes + * @rgd: The rgrp + * + * Returns: The inode, if one has been found + */ + +static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) +{ + struct inode *inode; + u32 goal = 0; + u64 ino; + + for(;;) { + goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, + GFS2_BLKST_UNLINKED); + if (goal == 0) + return 0; + ino = goal + rgd->rd_data0; + if (ino <= *last_unlinked) + continue; + *last_unlinked = ino; + inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN); + if (!IS_ERR(inode)) + return inode; + } + + rgd->rd_flags &= ~GFS2_RDF_CHECK; + return NULL; +} + /** * recent_rgrp_first - get first RG from "recent" list * @sdp: The GFS2 superblock @@ -1006,8 +1042,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) * Returns: errno */ -static int get_local_rgrp(struct gfs2_inode *ip) +static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) { + struct inode *inode = NULL; struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; struct gfs2_alloc *al = &ip->i_alloc; @@ -1027,7 +1064,11 @@ static int get_local_rgrp(struct gfs2_inode *ip) case 0: if (try_rgrp_fit(rgd, al)) goto out; + if (rgd->rd_flags & GFS2_RDF_CHECK) + inode = try_rgrp_unlink(rgd, last_unlinked); gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (inode) + return inode; rgd = recent_rgrp_next(rgd, 1); break; @@ -1036,7 +1077,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) break; default: - return error; + return ERR_PTR(error); } } @@ -1051,7 +1092,11 @@ static int get_local_rgrp(struct gfs2_inode *ip) case 0: if (try_rgrp_fit(rgd, al)) goto out; + if (rgd->rd_flags & GFS2_RDF_CHECK) + inode = try_rgrp_unlink(rgd, last_unlinked); gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (inode) + return inode; break; case GLR_TRYFAILED: @@ -1059,7 +1104,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) break; default: - return error; + return ERR_PTR(error); } rgd = gfs2_rgrpd_get_next(rgd); @@ -1068,7 +1113,7 @@ static int get_local_rgrp(struct gfs2_inode *ip) if (rgd == begin) { if (++loops >= 3) - return -ENOSPC; + return ERR_PTR(-ENOSPC); if (!skipped) loops++; flags = 0; @@ -1088,7 +1133,7 @@ out: forward_rgrp_set(sdp, rgd); } - return 0; + return NULL; } /** @@ -1102,11 +1147,14 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = &ip->i_alloc; + struct inode *inode; int error = 0; + u64 last_unlinked = 0; if (gfs2_assert_warn(sdp, al->al_requested)) return -EINVAL; +try_again: /* We need to hold the rindex unless the inode we're using is the rindex itself, in which case it's already held. */ if (ip != GFS2_I(sdp->sd_rindex)) @@ -1117,11 +1165,15 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) if (error) return error; - error = get_local_rgrp(ip); - if (error) { + inode = get_local_rgrp(ip, &last_unlinked); + if (inode) { if (ip != GFS2_I(sdp->sd_rindex)) gfs2_glock_dq_uninit(&al->al_ri_gh); - return error; + if (IS_ERR(inode)) + return PTR_ERR(inode); + iput(inode); + gfs2_log_flush(sdp, NULL); + goto try_again; } al->al_file = file; @@ -1209,7 +1261,7 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) */ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, - unsigned char old_state, unsigned char new_state) + unsigned char old_state, unsigned char new_state) { struct gfs2_bitmap *bi = NULL; u32 length = rgd->rd_length; @@ -1250,17 +1302,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, goal = 0; } - if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) - blk = 0; + if (old_state != new_state) { + gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT); - gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); - gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, - bi->bi_len, blk, new_state); - if (bi->bi_clone) - gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, + gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); + gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, bi->bi_len, blk, new_state); + if (bi->bi_clone) + gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, + bi->bi_len, blk, new_state); + } - return bi->bi_start * GFS2_NBBY + blk; + return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk; } /** From 037bcbb7564e35aef937c54799550cd27735aac6 Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Fri, 8 Jun 2007 16:42:14 -0700 Subject: [PATCH 166/551] [GFS2] gfs2_lookupi() uninitialised var fix fs/gfs2/inode.c: In function 'gfs2_lookupi': fs/gfs2/inode.c:392: warning: 'error' may be used uninitialized in this function Looks like a real bug to me. Cc: Steven Whitehouse Signed-off-by: Andrew Morton Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index cacdb0dfe577..366235d6a5b5 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -389,7 +389,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, struct super_block *sb = dir->i_sb; struct gfs2_inode *dip = GFS2_I(dir); struct gfs2_holder d_gh; - int error; + int error = 0; struct inode *inode = NULL; int unlock = 0; From d88101d4d82ea09433692af30618c3b7afb7da02 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 8 Jun 2007 16:00:22 -0500 Subject: [PATCH 167/551] [GFS2] set plock owner in GETLK info Set the owner field in the plock info sent to userspace for GETLK. Without this, gfs_controld won't correctly see when the GETLK from a process matches one of the process's existing locks. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/plock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index f82495e18c2d..1dc76805dd45 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c @@ -242,7 +242,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); From a7a2ff8a951ab373732116e7c31e2e1fe025d5e0 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 8 Jun 2007 17:01:40 -0500 Subject: [PATCH 168/551] [GFS2] return conflicts for GETLK We weren't returning the correct result when GETLK found a conflict, which is indicated by userspace passing back a 1. Signed-off-by: Abhijith Das Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/plock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index 1dc76805dd45..fba1f1d87e4f 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c @@ -254,16 +254,20 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, } spin_unlock(&ops_lock); + /* info.rv from userspace is 1 for conflict, 0 for no-conflict, + -ENOENT if there are no locks on the file */ + rv = op->info.rv; fl->fl_type = F_UNLCK; if (rv == -ENOENT) rv = 0; - else if (rv == 0 && op->info.pid != fl->fl_pid) { + else if (rv > 0) { fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; fl->fl_pid = op->info.pid; fl->fl_start = op->info.start; fl->fl_end = op->info.end; + rv = 0; } kfree(op); From d93cfa9884354dac2d8ccd894594a43e0b962b6f Mon Sep 17 00:00:00 2001 From: Abhijith Das Date: Mon, 11 Jun 2007 08:22:32 +0100 Subject: [PATCH 169/551] [GFS2] Fix deallocation issues There were two issues during deallocation of unlinked inodes. The first was relating to the use of a "try" lock which in the case of the inode lock wasn't trying hard enough to deallocate in all circumstances (now changed to a normal glock) and in the case of the iopen lock didn't wait for the demotion of the shared lock before attempting to get the exclusive lock, and thereby sometimes (timing dependent) not completing the deallocation when it should have done. The second issue related to the lack of a way to invalidate dcache entries on remote nodes (now fixed by this patch) which meant that unlinks were taking a long time to return disk space to the fs. By adding some code to invalidate the dcache entries across the cluster for unlinked inodes, that is now fixed. This patch was written jointly by Abhijith Das and Steven Whitehouse. Signed-off-by: Abhijith Das Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 52 +++++++++++++++++++++++++++++++++++---------- fs/gfs2/glock.h | 1 + fs/gfs2/inode.c | 1 + fs/gfs2/ops_super.c | 8 ++++--- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index b3ed58551e74..384cae623ed3 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -422,11 +422,11 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) static void gfs2_holder_wake(struct gfs2_holder *gh) { clear_bit(HIF_WAIT, &gh->gh_iflags); - smp_mb(); + smp_mb__after_clear_bit(); wake_up_bit(&gh->gh_iflags, HIF_WAIT); } -static int holder_wait(void *word) +static int just_schedule(void *word) { schedule(); return 0; @@ -435,7 +435,20 @@ static int holder_wait(void *word) static void wait_on_holder(struct gfs2_holder *gh) { might_sleep(); - wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE); + wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); +} + +static void gfs2_demote_wake(struct gfs2_glock *gl) +{ + clear_bit(GLF_DEMOTE, &gl->gl_flags); + smp_mb__after_clear_bit(); + wake_up_bit(&gl->gl_flags, GLF_DEMOTE); +} + +static void wait_on_demote(struct gfs2_glock *gl) +{ + might_sleep(); + wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); } /** @@ -528,7 +541,7 @@ static int rq_demote(struct gfs2_glock *gl) if (gl->gl_state == gl->gl_demote_state || gl->gl_state == LM_ST_UNLOCKED) { - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); return 0; } set_bit(GLF_LOCK, &gl->gl_flags); @@ -666,12 +679,22 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl) * practise: LM_ST_SHARED and LM_ST_UNLOCKED */ -static void handle_callback(struct gfs2_glock *gl, unsigned int state) +static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote) { spin_lock(&gl->gl_spin); if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { gl->gl_demote_state = state; gl->gl_demote_time = jiffies; + if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && + gl->gl_object) { + struct inode *inode = igrab(gl->gl_object); + spin_unlock(&gl->gl_spin); + if (inode) { + d_prune_aliases(inode); + iput(inode); + } + return; + } } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { gl->gl_demote_state = state; } @@ -740,7 +763,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) if (ret & LM_OUT_CANCELED) op_done = 0; else - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); } else { spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); @@ -848,7 +871,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) gfs2_assert_warn(sdp, !ret); state_change(gl, LM_ST_UNLOCKED); - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); if (glops->go_inval) glops->go_inval(gl, DIO_METADATA); @@ -1174,7 +1197,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) const struct gfs2_glock_operations *glops = gl->gl_ops; if (gh->gh_flags & GL_NOCACHE) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_lock(gl); @@ -1196,6 +1219,13 @@ void gfs2_glock_dq(struct gfs2_holder *gh) spin_unlock(&gl->gl_spin); } +void gfs2_glock_dq_wait(struct gfs2_holder *gh) +{ + struct gfs2_glock *gl = gh->gh_gl; + gfs2_glock_dq(gh); + wait_on_demote(gl); +} + /** * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it * @gh: the holder structure @@ -1456,7 +1486,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, if (!gl) return; - handle_callback(gl, state); + handle_callback(gl, state, 1); spin_lock(&gl->gl_spin); run_queue(gl); @@ -1596,7 +1626,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp) if (gfs2_glmutex_trylock(gl)) { if (list_empty(&gl->gl_holders) && gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_unlock(gl); } @@ -1709,7 +1739,7 @@ static void clear_glock(struct gfs2_glock *gl) if (gfs2_glmutex_trylock(gl)) { if (list_empty(&gl->gl_holders) && gl->gl_state != LM_ST_UNLOCKED) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_unlock(gl); } } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index b3e152db70c8..7721ca3fff9e 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -87,6 +87,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh); int gfs2_glock_poll(struct gfs2_holder *gh); int gfs2_glock_wait(struct gfs2_holder *gh); void gfs2_glock_dq(struct gfs2_holder *gh); +void gfs2_glock_dq_wait(struct gfs2_holder *gh); void gfs2_glock_dq_uninit(struct gfs2_holder *gh); int gfs2_glock_nq_num(struct gfs2_sbd *sdp, diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 366235d6a5b5..792d64f69cc2 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -114,6 +114,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); if (unlikely(error)) goto fail_iopen; + ip->i_iopen_gh.gh_gl->gl_object = ip; gfs2_glock_put(io_gl); diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 485ce3d49923..603d940f1159 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c @@ -326,8 +326,10 @@ static void gfs2_clear_inode(struct inode *inode) gfs2_glock_schedule_for_reclaim(ip->i_gl); gfs2_glock_put(ip->i_gl); ip->i_gl = NULL; - if (ip->i_iopen_gh.gh_gl) + if (ip->i_iopen_gh.gh_gl) { + ip->i_iopen_gh.gh_gl->gl_object = NULL; gfs2_glock_dq_uninit(&ip->i_iopen_gh); + } } } @@ -422,13 +424,13 @@ static void gfs2_delete_inode(struct inode *inode) if (!inode->i_private) goto out; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); if (unlikely(error)) { gfs2_glock_dq_uninit(&ip->i_iopen_gh); goto out; } - gfs2_glock_dq(&ip->i_iopen_gh); + gfs2_glock_dq_wait(&ip->i_iopen_gh); gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); error = gfs2_glock_nq(&ip->i_iopen_gh); if (error) From fad59c1390045b5adb7c7249ec4e77e0f868aca5 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 11 Jun 2007 10:47:18 -0500 Subject: [PATCH 170/551] [DLM] don't require FS flag on all nodes Mask off the recently added DLM_LSFL_FS flag when setting the exflags. This way all the nodes in the lockspace aren't required to have the FS flag set, since we later check that exflags matches among all nodes. Signed-off-by: Patrick Caulfield Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/lockspace.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 6802653473d1..1dc72105ab12 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -438,17 +438,18 @@ static int new_lockspace(char *name, int namelen, void **lockspace, ls->ls_count = 0; ls->ls_flags = 0; - /* ls_exflags are forced to match among nodes, and we don't - need to require all nodes to have TIMEWARN active */ if (flags & DLM_LSFL_TIMEWARN) set_bit(LSFL_TIMEWARN, &ls->ls_flags); - ls->ls_exflags = (flags & ~DLM_LSFL_TIMEWARN); if (flags & DLM_LSFL_FS) ls->ls_allocation = GFP_NOFS; else ls->ls_allocation = GFP_KERNEL; + /* ls_exflags are forced to match among nodes, and we don't + need to require all nodes to have TIMEWARN or FS set */ + ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS)); + size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; From 8fb68595d508fd30ec90939572484b263600376c Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Tue, 12 Jun 2007 11:24:36 -0500 Subject: [PATCH 171/551] [GFS2] Journaled file write/unstuff bug This patch is for bugzilla bug 283162, which uncovered a number of bugs pertaining to writing to files that have the journaled bit on. These bugs happen most often when writing to the meta_fs because the files are always journaled. So operations like gfs2_grow were particularly vulnerable, although many of the problems could be recreated with normal files after setting the journaled bit on. The problems fixed are: -GFS2 wasn't ever writing unstuffed journaled data blocks to their in-place location on disk. Now it does. -If you unmounted too quickly after doing IO to a journaled file, GFS2 was crashing because you would discard a buffer whose bufdata was still on the active items list. GFS2 now deals with this gracefully. -GFS2 was losing track of the bufdata for journaled data blocks, and it wasn't getting freed, causing an error when you tried to unmount the module. GFS2 now frees all the bufdata structures. -There was a memory corruption occurring because GFS2 wrote twice as many log entries for journaled buffers. -It was occasionally trying to write journal headers in buffers that weren't currently mapped. Signed-off-by: Bob Peterson Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/log.c | 15 ++++++++++++++- fs/gfs2/lops.c | 4 +++- fs/gfs2/ops_address.c | 26 +++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 1fb846fc545e..fbdc0dc9923e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -83,6 +83,11 @@ static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) gfs2_assert(sdp, bd->bd_ail == ai); + if (!bh){ + list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); + continue; + } + if (!buffer_busy(bh)) { if (!buffer_uptodate(bh)) { gfs2_log_unlock(sdp); @@ -125,6 +130,11 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl bd_ail_st_list) { bh = bd->bd_bh; + if (!bh){ + list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); + continue; + } + gfs2_assert(sdp, bd->bd_ail == ai); if (buffer_busy(bh)) { @@ -227,7 +237,10 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) list_del(&bd->bd_ail_st_list); list_del(&bd->bd_ail_gl_list); atomic_dec(&bd->bd_gl->gl_ail_count); - brelse(bd->bd_bh); + if (bd->bd_bh) + brelse(bd->bd_bh); + else + kmem_cache_free(gfs2_bufdata_cachep, bd); } } diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 3e971f25120d..df6bceea379a 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -607,7 +607,8 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) if (unlikely(magic != 0)) set_buffer_escaped(bh1); gfs2_log_lock(sdp); - if (n++ > num) + n += 2; + if (n >= num) break; } else if (!bh1) { total_dbuf--; @@ -624,6 +625,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) } gfs2_log_unlock(sdp); if (bh) { + set_buffer_mapped(bh); set_buffer_dirty(bh); ll_rw_block(WRITE, 1, &bh); bh = NULL; diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index ac5659521386..9ab35a9ee75a 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -137,7 +137,9 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc) return 0; /* don't care */ } - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) { + if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) && + PageChecked(page)) { + ClearPageChecked(page); error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); if (error) goto out_ignore; @@ -573,6 +575,23 @@ fail_nounlock: return error; } +/** + * gfs2_set_page_dirty - Page dirtying function + * @page: The page to dirty + * + * Returns: 1 if it dirtyed the page, or 0 otherwise + */ + +static int gfs2_set_page_dirty(struct page *page) +{ + struct gfs2_inode *ip = GFS2_I(page->mapping->host); + struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); + + if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + SetPageChecked(page); + return __set_page_dirty_buffers(page); +} + /** * gfs2_bmap - Block map function * @mapping: Address space info @@ -609,6 +628,8 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh) if (bd) { bd->bd_bh = NULL; bh->b_private = NULL; + if (!bd->bd_ail && list_empty(&bd->bd_le.le_list)) + kmem_cache_free(gfs2_bufdata_cachep, bd); } gfs2_log_unlock(sdp); @@ -629,6 +650,8 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset) unsigned int curr_off = 0; BUG_ON(!PageLocked(page)); + if (offset == 0) + ClearPageChecked(page); if (!page_has_buffers(page)) return; @@ -841,6 +864,7 @@ const struct address_space_operations gfs2_file_aops = { .sync_page = block_sync_page, .prepare_write = gfs2_prepare_write, .commit_write = gfs2_commit_write, + .set_page_dirty = gfs2_set_page_dirty, .bmap = gfs2_bmap, .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage, From c4201214cbf10636e2c1ab9131573f735b42c8d4 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 14 Jun 2007 16:39:13 +0100 Subject: [PATCH 172/551] [GFS2] Remove bogus '\0' in rgrp.c Not sure how it slipped in, but we don't want it anyway. Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index fd3fd9074779..36c523d487a7 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -444,7 +444,6 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) } /** - * gfs2_ri_total - Total up the file system space, according to the rindex. * */ From 2840501ac822c5bf712f67b4b02640e16e145a29 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 18 Jun 2007 16:31:42 +0100 Subject: [PATCH 173/551] [GFS2] Use zero_user_page() in stuffed_readpage() As suggested by Robert P. J. Day Signed-off-by: Steven Whitehouse Cc: Robert P. J. Day --- fs/gfs2/ops_address.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 9ab35a9ee75a..26c888890c24 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c @@ -208,11 +208,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) * so we need to supply one here. It doesn't happen often. */ if (unlikely(page->index)) { - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr, 0, PAGE_CACHE_SIZE); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page); - SetPageUptodate(page); + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); return 0; } From 2332c4435bb733b5cd4f612ee57532bd8fde4c1c Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Mon, 18 Jun 2007 14:50:20 -0500 Subject: [PATCH 174/551] [GFS2] assertion failure after writing to journaled file, umount This patch passes all my nasty tests that were causing the code to fail under one circumstance or another. Here is a complete summary of all changes from today's git tree, in order of appearance: 1. There are now separate variables for metadata buffer accounting. 2. Variable sd_log_num_hdrs is no longer needed, since the header accounting is taken care of by the reserve/refund sequence. 3. Fixed a tiny grammatical problem in a comment. 4. Added a new function "calc_reserved" to calculate the reserved log space. This isn't entirely necessary, but it has two benefits: First, it simplifies the gfs2_log_refund function greatly. Second, it allows for easier debugging because I could sprinkle the code with calls to this function to make sure the accounting is proper (by adding asserts and printks) at strategic point of the code. 5. In log_pull_tail there apparently was a kludge to fix up the accounting based on a "pull" parameter. The buffer accounting is now done properly, so the kludge was removed. 6. File sync operations were making a call to gfs2_log_flush that writes another journal header. Since that header was unplanned for (reserved) by the reserve/refund sequence, the free space had to be decremented so that when log_pull_tail gets called, the free space is be adjusted properly. (Did I hear you call that a kludge? well, maybe, but a lot more justifiable than the one I removed). 7. In the gfs2_log_shutdown code, it optionally syncs the log by specifying the PULL parameter to log_write_header. I'm not sure this is necessary anymore. It just seems to me there could be cases where shutdown is called while there are outstanding log buffers. 8. In the (data)buf_lo_before_commit functions, I changed some offset values from being calculated on the fly to being constants. That simplified some code and we might as well let the compiler do the calculation once rather than redoing those cycles at run time. 9. This version has my rewritten databuf_lo_add function. This version is much more like its predecessor, buf_lo_add, which makes it easier to understand. Again, this might not be necessary, but it seems as if this one works as well as the previous one, maybe even better, so I decided to leave it in. 10. In databuf_lo_before_commit, a previous data corruption problem was caused by going off the end of the buffer. The proper solution is to have the proper limit in place, rather than stopping earlier. (Thus my previous attempt to fix it is wrong). If you don't wrap the buffer, you're stopping too early and that causes more log buffer accounting problems. 11. In lops.h there are two new (previously mentioned) constants for figuring out the data offset for the journal buffers. 12. There are also two new functions, buf_limit and databuf_limit to calculate how many entries will fit in the buffer. 13. In function gfs2_meta_wipe, it needs to distinguish between pinned metadata buffers and journaled data buffers for proper journal buffer accounting. It can't use the JDATA gfs2_inode flag because it's sometimes passed the "real" inode and sometimes the "metadata inode" and the inode flags will be random bits in a metadata gfs2_inode. It needs to base its decision on which was passed in. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 4 +- fs/gfs2/log.c | 100 +++++++++++++++++++++++++++++++++++----------- fs/gfs2/lops.c | 55 +++++++++++-------------- fs/gfs2/lops.h | 23 +++++++++++ fs/gfs2/meta_io.c | 8 +++- 5 files changed, 133 insertions(+), 57 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c7c6ec0f17c7..170ba93829c0 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -354,7 +354,9 @@ struct gfs2_trans { unsigned int tr_num_buf; unsigned int tr_num_buf_new; + unsigned int tr_num_databuf_new; unsigned int tr_num_buf_rm; + unsigned int tr_num_databuf_rm; struct list_head tr_list_buf; unsigned int tr_num_revoke; @@ -599,6 +601,7 @@ struct gfs2_sbd { unsigned int sd_log_blks_reserved; unsigned int sd_log_commited_buf; + unsigned int sd_log_commited_databuf; unsigned int sd_log_commited_revoke; unsigned int sd_log_num_gl; @@ -607,7 +610,6 @@ struct gfs2_sbd { unsigned int sd_log_num_rg; unsigned int sd_log_num_databuf; unsigned int sd_log_num_jdata; - unsigned int sd_log_num_hdrs; struct list_head sd_log_le_gl; struct list_head sd_log_le_buf; diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index fbdc0dc9923e..8fcfb784f906 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -276,7 +276,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) * @blks: The number of blocks to reserve * * Note that we never give out the last few blocks of the journal. Thats - * due to the fact that there is are a small number of header blocks + * due to the fact that there is a small number of header blocks * associated with each log flush. The exact number can't be known until * flush time, so we ensure that we have just enough free blocks at all * times to avoid running out during a log flush. @@ -371,6 +371,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer return dist; } +/** + * calc_reserved - Calculate the number of blocks to reserve when + * refunding a transaction's unused buffers. + * @sdp: The GFS2 superblock + * + * This is complex. We need to reserve room for all our currently used + * metadata buffers (e.g. normal file I/O rewriting file time stamps) and + * all our journaled data buffers for journaled files (e.g. files in the + * meta_fs like rindex, or files for which chattr +j was done.) + * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush + * will count it as free space (sd_log_blks_free) and corruption will follow. + * + * We can have metadata bufs and jdata bufs in the same journal. So each + * type gets its own log header, for which we need to reserve a block. + * In fact, each type has the potential for needing more than one header + * in cases where we have more buffers than will fit on a journal page. + * Metadata journal entries take up half the space of journaled buffer entries. + * Thus, metadata entries have buf_limit (502) and journaled buffers have + * databuf_limit (251) before they cause a wrap around. + * + * Also, we need to reserve blocks for revoke journal entries and one for an + * overall header for the lot. + * + * Returns: the number of blocks reserved + */ +static unsigned int calc_reserved(struct gfs2_sbd *sdp) +{ + unsigned int reserved = 0; + unsigned int mbuf_limit, metabufhdrs_needed; + unsigned int dbuf_limit, databufhdrs_needed; + unsigned int revokes = 0; + + mbuf_limit = buf_limit(sdp); + metabufhdrs_needed = (sdp->sd_log_commited_buf + + (mbuf_limit - 1)) / mbuf_limit; + dbuf_limit = databuf_limit(sdp); + databufhdrs_needed = (sdp->sd_log_commited_databuf + + (dbuf_limit - 1)) / dbuf_limit; + + if (sdp->sd_log_commited_revoke) + revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, + sizeof(u64)); + + reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + + sdp->sd_log_commited_databuf + databufhdrs_needed + + revokes; + /* One for the overall header */ + if (reserved) + reserved++; + return reserved; +} + static unsigned int current_tail(struct gfs2_sbd *sdp) { struct gfs2_ail *ai; @@ -461,14 +513,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, return bh; } -static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) +static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) { unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); ail2_empty(sdp, new_tail); gfs2_log_lock(sdp); - sdp->sd_log_blks_free += dist - (pull ? 1 : 0); + sdp->sd_log_blks_free += dist; gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); gfs2_log_unlock(sdp); @@ -518,7 +570,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) brelse(bh); if (sdp->sd_log_tail != tail) - log_pull_tail(sdp, tail, pull); + log_pull_tail(sdp, tail); else gfs2_assert_withdraw(sdp, !pull); @@ -579,7 +631,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) INIT_LIST_HEAD(&ai->ai_ail1_list); INIT_LIST_HEAD(&ai->ai_ail2_list); - gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf + sdp->sd_log_num_jdata == sdp->sd_log_commited_buf); + gfs2_assert_withdraw(sdp, + sdp->sd_log_num_buf + sdp->sd_log_num_jdata == + sdp->sd_log_commited_buf + + sdp->sd_log_commited_databuf); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); @@ -590,16 +645,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) lops_before_commit(sdp); if (!list_empty(&sdp->sd_log_flush_list)) log_flush_commit(sdp); - else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) + else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ + gfs2_log_lock(sdp); + sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ + gfs2_log_unlock(sdp); log_write_header(sdp, 0, PULL); + } lops_after_commit(sdp, ai); gfs2_log_lock(sdp); sdp->sd_log_head = sdp->sd_log_flush_head; - sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs; sdp->sd_log_blks_reserved = 0; sdp->sd_log_commited_buf = 0; - sdp->sd_log_num_hdrs = 0; + sdp->sd_log_commited_databuf = 0; sdp->sd_log_commited_revoke = 0; if (!list_empty(&ai->ai_ail1_list)) { @@ -616,32 +674,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { - unsigned int reserved = 0; + unsigned int reserved; unsigned int old; gfs2_log_lock(sdp); sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; - gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); + sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - + tr->tr_num_databuf_rm; + gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || + (((int)sdp->sd_log_commited_databuf) >= 0)); sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); - - if (sdp->sd_log_commited_buf) - reserved += sdp->sd_log_commited_buf; - if (sdp->sd_log_commited_revoke) - reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, - sizeof(u64)); - if (reserved) - reserved++; - + reserved = calc_reserved(sdp); old = sdp->sd_log_blks_free; sdp->sd_log_blks_free += tr->tr_reserved - (reserved - sdp->sd_log_blks_reserved); gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); - gfs2_assert_withdraw(sdp, - sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + - sdp->sd_log_num_hdrs); + gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= + sdp->sd_jdesc->jd_blocks); sdp->sd_log_blks_reserved = reserved; @@ -687,13 +739,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); - gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs); gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); sdp->sd_log_flush_head = sdp->sd_log_head; sdp->sd_log_flush_wrapped = 0; - log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); + log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, + (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index df6bceea379a..dd810ad68cf0 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -17,6 +17,7 @@ #include "gfs2.h" #include "incore.h" +#include "inode.h" #include "glock.h" #include "log.h" #include "lops.h" @@ -117,15 +118,13 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) struct gfs2_log_descriptor *ld; struct gfs2_bufdata *bd1 = NULL, *bd2; unsigned int total = sdp->sd_log_num_buf; - unsigned int offset = sizeof(struct gfs2_log_descriptor); + unsigned int offset = BUF_OFFSET; unsigned int limit; unsigned int num; unsigned n; __be64 *ptr; - offset += sizeof(__be64) - 1; - offset &= ~(sizeof(__be64) - 1); - limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); + limit = buf_limit(sdp); /* for 4k blocks, limit = 503 */ bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); @@ -134,7 +133,6 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) if (total > limit) num = limit; bh = gfs2_log_get_buf(sdp); - sdp->sd_log_num_hdrs++; ld = (struct gfs2_log_descriptor *)bh->b_data; ptr = (__be64 *)(bh->b_data + offset); ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); @@ -469,27 +467,26 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) struct gfs2_inode *ip = GFS2_I(mapping->host); gfs2_log_lock(sdp); + if (!list_empty(&bd->bd_list_tr)) { + gfs2_log_unlock(sdp); + return; + } tr->tr_touched = 1; - if (list_empty(&bd->bd_list_tr) && - (ip->i_di.di_flags & GFS2_DIF_JDATA)) { - tr->tr_num_buf++; - list_add(&bd->bd_list_tr, &tr->tr_list_buf); - gfs2_log_unlock(sdp); - if (!list_empty(&le->le_list)) - return; - gfs2_pin(sdp, bd->bd_bh); - tr->tr_num_buf_new++; - } else { - gfs2_log_unlock(sdp); - } + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + gfs2_log_unlock(sdp); + if (!list_empty(&le->le_list)) + return; + gfs2_trans_add_gl(bd->bd_gl); - gfs2_log_lock(sdp); - if (list_empty(&le->le_list)) { - if (ip->i_di.di_flags & GFS2_DIF_JDATA) - sdp->sd_log_num_jdata++; - sdp->sd_log_num_databuf++; - list_add(&le->le_list, &sdp->sd_log_le_databuf); + if (gfs2_is_jdata(ip)) { + sdp->sd_log_num_jdata++; + gfs2_pin(sdp, bd->bd_bh); + tr->tr_num_databuf_new++; } + sdp->sd_log_num_databuf++; + gfs2_log_lock(sdp); + list_add(&le->le_list, &sdp->sd_log_le_databuf); gfs2_log_unlock(sdp); } @@ -522,7 +519,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) LIST_HEAD(started); struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; struct buffer_head *bh = NULL,*bh1 = NULL; - unsigned int offset = sizeof(struct gfs2_log_descriptor); struct gfs2_log_descriptor *ld; unsigned int limit; unsigned int total_dbuf = sdp->sd_log_num_databuf; @@ -530,9 +526,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) unsigned int num, n; __be64 *ptr = NULL; - offset += 2*sizeof(__be64) - 1; - offset &= ~(2*sizeof(__be64) - 1); - limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); + limit = databuf_limit(sdp); /* * Start writing ordered buffers, write journaled buffers @@ -583,10 +577,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) gfs2_log_unlock(sdp); if (!bh) { bh = gfs2_log_get_buf(sdp); - sdp->sd_log_num_hdrs++; ld = (struct gfs2_log_descriptor *) bh->b_data; - ptr = (__be64 *)(bh->b_data + offset); + ptr = (__be64 *)(bh->b_data + + DATABUF_OFFSET); ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); ld->ld_header.mh_type = @@ -607,8 +601,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) if (unlikely(magic != 0)) set_buffer_escaped(bh1); gfs2_log_lock(sdp); - n += 2; - if (n >= num) + if (++n >= num) break; } else if (!bh1) { total_dbuf--; diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 965bc65c7c64..41a00df75587 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h @@ -13,6 +13,13 @@ #include #include "incore.h" +#define BUF_OFFSET \ + ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \ + ~(sizeof(__be64) - 1)) +#define DATABUF_OFFSET \ + ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \ + ~(2 * sizeof(__be64) - 1)) + extern const struct gfs2_log_operations gfs2_glock_lops; extern const struct gfs2_log_operations gfs2_buf_lops; extern const struct gfs2_log_operations gfs2_revoke_lops; @@ -21,6 +28,22 @@ extern const struct gfs2_log_operations gfs2_databuf_lops; extern const struct gfs2_log_operations *gfs2_log_ops[]; +static inline unsigned int buf_limit(struct gfs2_sbd *sdp) +{ + unsigned int limit; + + limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64); + return limit; +} + +static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) +{ + unsigned int limit; + + limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64)); + return limit; +} + static inline void lops_init_le(struct gfs2_log_element *le, const struct gfs2_log_operations *lops) { diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index e62d4f620c58..8da343b34ae7 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -387,12 +387,18 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) if (test_clear_buffer_pinned(bh)) { struct gfs2_trans *tr = current->journal_info; + struct gfs2_inode *bh_ip = + GFS2_I(bh->b_page->mapping->host); + gfs2_log_lock(sdp); list_del_init(&bd->bd_le.le_list); gfs2_assert_warn(sdp, sdp->sd_log_num_buf); sdp->sd_log_num_buf--; gfs2_log_unlock(sdp); - tr->tr_num_buf_rm++; + if (bh_ip->i_inode.i_private != NULL) + tr->tr_num_databuf_rm++; + else + tr->tr_num_buf_rm++; brelse(bh); } if (bd) { From eaf5bd3cac92126e5825c6ebc10bee0fba35d555 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 19 Jun 2007 15:38:17 +0100 Subject: [PATCH 175/551] [GFS2] Simplify multiple glock aquisition There is a bug in the code which acquires multiple glocks where if the initial out-of-order attempt fails part way though we can land up trying to acquire the wrong number of glocks. This is part of the fix for red hat bz #239737. The other part of the bz doesn't apply to upstream kernels since it was fixed by: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d3717bdf8f08a0e1039158c8bab2c24d20f492b6 Since the out-of-order code doesn't appear to add anything to the performance of GFS2, this patch just removed it rather than trying to fix it. It should be much easier to see whats going on here now. In addition, we don't allocate any memory unless we are using a lot of glocks (which is a relatively uncommon case). Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 64 ++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 384cae623ed3..3f0974e1afef 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1327,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, * @num_gh: the number of structures * @ghs: an array of struct gfs2_holder structures * - * Figure out how big an impact this function has. Either: - * 1) Replace this code with code that calls gfs2_glock_prefetch() - * 2) Forget async stuff and just call nq_m_sync() - * 3) Leave it like it is * * Returns: 0 on success (all glocks acquired), * errno on failure (no glocks acquired) @@ -1338,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs, int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) { - int *e; - unsigned int x; - int borked = 0, serious = 0; + struct gfs2_holder *tmp[4]; + struct gfs2_holder **pph = tmp; int error = 0; - if (!num_gh) + switch(num_gh) { + case 0: return 0; - - if (num_gh == 1) { + case 1: ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); return gfs2_glock_nq(ghs); - } - - e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); - if (!e) - return -ENOMEM; - - for (x = 0; x < num_gh; x++) { - ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; - error = gfs2_glock_nq(&ghs[x]); - if (error) { - borked = 1; - serious = error; - num_gh = x; + default: + if (num_gh <= 4) break; - } + pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS); + if (!pph) + return -ENOMEM; } - for (x = 0; x < num_gh; x++) { - error = e[x] = glock_wait_internal(&ghs[x]); - if (error) { - borked = 1; - if (error != GLR_TRYFAILED && error != GLR_CANCELED) - serious = error; - } - } + error = nq_m_sync(num_gh, ghs, pph); - if (!borked) { - kfree(e); - return 0; - } - - for (x = 0; x < num_gh; x++) - if (!e[x]) - gfs2_glock_dq(&ghs[x]); - - if (serious) - error = serious; - else { - for (x = 0; x < num_gh; x++) - gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, - &ghs[x]); - error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e); - } - - kfree(e); + if (pph != tmp) + kfree(pph); return error; } From 773ed1a044adc868036dee1722b8bca6ce5923e2 Mon Sep 17 00:00:00 2001 From: Robert Peterson Date: Wed, 20 Jun 2007 08:34:06 -0500 Subject: [PATCH 176/551] [GFS2] Addendum to the journaled file/unmount patch This patch is an addendum to the previous journaled file/unmount patch. It fixes a problem discovered during testing. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/lops.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index dd810ad68cf0..aff70f0698fd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -472,8 +472,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) return; } tr->tr_touched = 1; - tr->tr_num_buf++; - list_add(&bd->bd_list_tr, &tr->tr_list_buf); + if (gfs2_is_jdata(ip)) { + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + } gfs2_log_unlock(sdp); if (!list_empty(&le->le_list)) return; From 1875f2f31b3955dff8c3712a56ae61836c8b90fe Mon Sep 17 00:00:00 2001 From: "S. Wendy Cheng" Date: Mon, 25 Jun 2007 21:14:31 -0400 Subject: [PATCH 177/551] [GFS2] Fix gfs2_block_truncate_page err return Code segment inside gfs2_block_truncate_page() doesn't set the return code correctly. This causes NFSD erroneously returns EIO back to client with setattr procedure call (truncate error). Signed-off-by: S. Wendy Cheng Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index d16044cb023a..cd805a66880d 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -927,6 +927,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping) /* Uhhuh. Read error. Complain and punt. */ if (!buffer_uptodate(bh)) goto unlock; + err = 0; } if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) From 97d848365e603def43c69e160937f073bf9cf02e Mon Sep 17 00:00:00 2001 From: Patrick Caulfield Date: Wed, 27 Jun 2007 11:36:23 +0100 Subject: [PATCH 178/551] [DLM] Telnet to port 21064 can stop all lockspaces This patch fixes Red Hat bz#245892 Opening a tcp connection from a cluster member to another cluster member targeting the dlm port it is enough to stop every dlm operation in the cluster. This means that GFS and rgmanager will hang. Signed-Off-By: Patrick Caulfield Signed-off-by: Steven Whitehouse --- fs/dlm/lowcomms.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index fc0bff74c61e..73d44f57e24a 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -720,11 +720,17 @@ static int tcp_accept_from_sock(struct connection *con) INIT_WORK(&othercon->rwork, process_recv_sockets); set_bit(CF_IS_OTHERCON, &othercon->flags); newcon->othercon = othercon; + othercon->sock = newsock; + newsock->sk->sk_user_data = othercon; + add_sock(newsock, othercon); + addcon = othercon; + } + else { + printk("Extra connection from node %d attempted\n", nodeid); + result = -EAGAIN; + up_write(&newcon->sock_sem); + goto accept_err; } - othercon->sock = newsock; - newsock->sk->sk_user_data = othercon; - add_sock(newsock, othercon); - addcon = othercon; } else { newsock->sk->sk_user_data = newcon; From 090ffaa55dacea774af9ee378d09e47fb7cea9ff Mon Sep 17 00:00:00 2001 From: Wendy Cheng Date: Wed, 27 Jun 2007 11:00:03 -0400 Subject: [PATCH 179/551] [GFS2] inode size inconsistency This should have been part of the NFS patch #1 but somehow I missed it when packaging the patches. It is not a critical issue as the others (I hope). RHEL 5.1 31.el5 kernel runs fine without this change. Our truncate code is chopped into two parts, one for vfs inode changes (in vmtruncate()) and one of gfs inode (in gfs2_truncatei()). These two operatons are, unfortunately, not atomic. So it could happens that vmtruncate() succeeds (inode->i_size is changed) but gfs2_truncatei fails (say kernel temporarily out of memory). This would leave gfs inode i_di.di_size out of sync with vfs inode i_size. It will later confuse gfs2_commit_write() if a write is issued. Last time I checked, it will cause file corruption. Signed-off-by: S. Wendy Cheng Signed-off-by: Steven Whitehouse --- fs/gfs2/ops_inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 84051b997a43..911c115b5c6c 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -903,8 +903,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr) } error = gfs2_truncatei(ip, attr->ia_size); - if (error) - return error; + if (error && (inode->i_size != ip->i_di.di_size)) + i_size_write(inode, ip->i_di.di_size); return error; } From 569a7b6c2e8965ff4908003b925757703a3d649c Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 27 Jun 2007 10:15:56 -0500 Subject: [PATCH 180/551] [GFS2] remounting w/o acl option leaves acls enabled This patch is for bugzilla bug #245663. This crosswrites a fix from gfs1 (bz #210369) so that the mount options are reset properly upon remount. This was tested on system trin-10. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/mount.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c index 4864659555d4..6f006a804db3 100644 --- a/fs/gfs2/mount.c +++ b/fs/gfs2/mount.c @@ -82,20 +82,19 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) char *options, *o, *v; int error = 0; - if (!remount) { - /* If someone preloaded options, use those instead */ - spin_lock(&gfs2_sys_margs_lock); - if (gfs2_sys_margs) { - data = gfs2_sys_margs; - gfs2_sys_margs = NULL; - } - spin_unlock(&gfs2_sys_margs_lock); - - /* Set some defaults */ - args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; - args->ar_quota = GFS2_QUOTA_DEFAULT; - args->ar_data = GFS2_DATA_DEFAULT; + /* If someone preloaded options, use those instead */ + spin_lock(&gfs2_sys_margs_lock); + if (!remount && gfs2_sys_margs) { + data = gfs2_sys_margs; + gfs2_sys_margs = NULL; } + spin_unlock(&gfs2_sys_margs_lock); + + /* Set some defaults */ + memset(args, 0, sizeof(struct gfs2_args)); + args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; + args->ar_quota = GFS2_QUOTA_DEFAULT; + args->ar_data = GFS2_DATA_DEFAULT; /* Split the options into tokens with the "," character and process them */ From b3657629249eba0b3b61ff964d6e1539b469d117 Mon Sep 17 00:00:00 2001 From: Abhijith Das Date: Wed, 27 Jun 2007 11:06:19 -0500 Subject: [PATCH 181/551] [GFS2] System won't suspend with GFS2 file system mounted The kernel threads in gfs2, namely gfs2_scand, gfs2_logd, gfs2_quotad, gfs2_glockd, gfs2_recoverd weren't doing anything when the suspend mechanism was trying to freeze them. I put in calls to refrigerator() in the loops for all the daemons and suspend works as expected. Signed-off-by: Abhijith Das Signed-off-by: Steven Whitehouse --- fs/gfs2/daemon.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index 683cb5bda870..3548d9f31e0d 100644 --- a/fs/gfs2/daemon.c +++ b/fs/gfs2/daemon.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -49,6 +50,8 @@ int gfs2_scand(void *data) while (!kthread_should_stop()) { gfs2_scand_internal(sdp); t = gfs2_tune_get(sdp, gt_scand_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -74,6 +77,8 @@ int gfs2_glockd(void *data) wait_event_interruptible(sdp->sd_reclaim_wq, (atomic_read(&sdp->sd_reclaim_count) || kthread_should_stop())); + if (freezing(current)) + refrigerator(); } return 0; @@ -93,6 +98,8 @@ int gfs2_recoverd(void *data) while (!kthread_should_stop()) { gfs2_check_journals(sdp); t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -141,6 +148,8 @@ int gfs2_logd(void *data) } t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -191,6 +200,8 @@ int gfs2_quotad(void *data) gfs2_quota_scan(sdp); t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } From f4fadb23ca49abd2f1387a0b7e78b385ebc760ce Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Wed, 27 Jun 2007 14:43:37 -0700 Subject: [PATCH 182/551] [GFS2] git-gfs2-nmw-build-fix Cc: Steven Whitehouse Signed-off-by: Andrew Morton Signed-off-by: Steven Whitehouse --- fs/dlm/lowcomms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 73d44f57e24a..0553a6158dcb 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -728,7 +728,7 @@ static int tcp_accept_from_sock(struct connection *con) else { printk("Extra connection from node %d attempted\n", nodeid); result = -EAGAIN; - up_write(&newcon->sock_sem); + mutex_unlock(&newcon->sock_mutex); goto accept_err; } } From bb9bcf061660661c57ddcf31337529f82414b937 Mon Sep 17 00:00:00 2001 From: Wendy Cheng Date: Wed, 27 Jun 2007 17:07:08 -0400 Subject: [PATCH 183/551] [GFS2] Obtaining no_formal_ino from directory entry GFS2 lookup code doesn't ask for inode shared glock. This implies during in-memory inode creation for existing file, GFS2 will not disk-read in the inode contents. This leaves no_formal_ino un-initialized during lookup time. The un-initialized no_formal_ino is subsequently encoded into file handle. Clients will get ESTALE error whenever it tries to access these files. Signed-off-by: S. Wendy Cheng Signed-off-by: Steven Whitehouse --- fs/gfs2/dir.c | 7 ++++--- fs/gfs2/inode.c | 10 ++++++++-- fs/gfs2/inode.h | 3 ++- fs/gfs2/ops_export.c | 4 +++- fs/gfs2/ops_fstype.c | 2 +- fs/gfs2/rgrp.c | 11 ++++++----- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index f793e31a050e..2beb2f401aa2 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1498,9 +1498,10 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) if (dent) { if (IS_ERR(dent)) return ERR_PTR(PTR_ERR(dent)); - inode = gfs2_inode_lookup(dir->i_sb, - be64_to_cpu(dent->de_inum.no_addr), - be16_to_cpu(dent->de_type)); + inode = gfs2_inode_lookup(dir->i_sb, + be16_to_cpu(dent->de_type), + be64_to_cpu(dent->de_inum.no_addr), + be64_to_cpu(dent->de_inum.no_formal_ino)); brelse(bh); return inode; } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 792d64f69cc2..26aaf54959d9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) * Returns: A VFS inode, or an error */ -struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type) +struct inode *gfs2_inode_lookup(struct super_block *sb, + unsigned int type, + u64 no_addr, + u64 no_formal_ino) { struct inode *inode = gfs2_iget(sb, no_addr); struct gfs2_inode *ip = GFS2_I(inode); @@ -100,6 +103,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in struct gfs2_sbd *sdp = GFS2_SB(inode); umode_t mode; inode->i_private = ip; + ip->i_no_formal_ino = no_formal_ino; error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); if (unlikely(error)) @@ -915,7 +919,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, if (error) goto fail_gunlock2; - inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode)); + inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), + inum.no_addr, + inum.no_formal_ino); if (IS_ERR(inode)) goto fail_gunlock2; diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 35375fc43fa3..3268a2fed672 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, void gfs2_inode_attr_in(struct gfs2_inode *ip); -struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type); +struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, + u64 no_addr, u64 no_formal_ino); struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); int gfs2_inode_refresh(struct gfs2_inode *ip); diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index d07230ee5fc0..0fe14478a54d 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c @@ -245,7 +245,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) gfs2_glock_dq_uninit(&rgd_gh); gfs2_glock_dq_uninit(&ri_gh); - inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode); + inode = gfs2_inode_lookup(sb, fh_obj->imode, + inum->no_addr, + inum->no_formal_ino); if (!inode) goto fail; if (IS_ERR(inode)) { diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index dae1d7142fe5..cf5aa5050548 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -236,7 +236,7 @@ fail: static inline struct inode *gfs2_lookup_root(struct super_block *sb, u64 no_addr) { - return gfs2_inode_lookup(sb, no_addr, DT_DIR); + return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); } static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 36c523d487a7..7fb74484af63 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -860,18 +860,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) { struct inode *inode; u32 goal = 0; - u64 ino; + u64 no_addr; for(;;) { goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, GFS2_BLKST_UNLINKED); if (goal == 0) return 0; - ino = goal + rgd->rd_data0; - if (ino <= *last_unlinked) + no_addr = goal + rgd->rd_data0; + if (no_addr <= *last_unlinked) continue; - *last_unlinked = ino; - inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN); + *last_unlinked = no_addr; + inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, + no_addr, 0); if (!IS_ERR(inode)) return inode; } From 35dcc52e3a916184b145fd840250244b81004200 Mon Sep 17 00:00:00 2001 From: Wendy Cheng Date: Wed, 27 Jun 2007 17:07:53 -0400 Subject: [PATCH 184/551] [GFS2] Remove i_mode passing from NFS File Handle GFS2 has been passing i_mode within NFS File Handle. Other than the wrong assumption that there is always room for this extra 16 bit value, the current gfs2_get_dentry doesn't really need the i_mode to work correctly. Note that GFS2 NFS code does go thru the same lookup code path as direct file access route (where the mode is obtained from name lookup) but gfs2_get_dentry() is coded for different purpose. It is not used during lookup time. It is part of the file access procedure call. When the call is invoked, if on-disk inode is not in-memory, it has to be read-in. This makes i_mode passing a useless overhead. Signed-off-by: S. Wendy Cheng Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 54 ++++++++++++++++++++++++++++++-------------- fs/gfs2/inode.h | 1 + fs/gfs2/ops_export.c | 38 ++++++++++++------------------- fs/gfs2/rgrp.c | 2 +- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 26aaf54959d9..34f7bcdea1e9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -77,6 +77,36 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); } +/** + * GFS2 lookup code fills in vfs inode contents based on info obtained + * from directory entry inside gfs2_inode_lookup(). This has caused issues + * with NFS code path since its get_dentry routine doesn't have the relevant + * directory entry when gfs2_inode_lookup() is invoked. Part of the code + * segment inside gfs2_inode_lookup code needs to get moved around. + * + * Clean up I_LOCK and I_NEW as well. + **/ + +void gfs2_set_iop(struct inode *inode) +{ + umode_t mode = inode->i_mode; + + if (S_ISREG(mode)) { + inode->i_op = &gfs2_file_iops; + inode->i_fop = &gfs2_file_fops; + inode->i_mapping->a_ops = &gfs2_file_aops; + } else if (S_ISDIR(mode)) { + inode->i_op = &gfs2_dir_iops; + inode->i_fop = &gfs2_dir_fops; + } else if (S_ISLNK(mode)) { + inode->i_op = &gfs2_symlink_iops; + } else { + inode->i_op = &gfs2_dev_iops; + } + + unlock_new_inode(inode); +} + /** * gfs2_inode_lookup - Lookup an inode * @sb: The super block @@ -101,7 +131,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, if (inode->i_state & I_NEW) { struct gfs2_sbd *sdp = GFS2_SB(inode); - umode_t mode; inode->i_private = ip; ip->i_no_formal_ino = no_formal_ino; @@ -122,6 +151,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, gfs2_glock_put(io_gl); + if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) + goto gfs2_nfsbypass; + + inode->i_mode = DT2IF(type); + /* * We must read the inode in order to work out its type in * this case. Note that this doesn't happen often as we normally @@ -129,33 +163,19 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, * unlinked inode recovery (where it is safe to do this glock, * which is not true in the general case). */ - inode->i_mode = mode = DT2IF(type); if (type == DT_UNKNOWN) { struct gfs2_holder gh; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); if (unlikely(error)) goto fail_glock; /* Inode is now uptodate */ - mode = inode->i_mode; gfs2_glock_dq_uninit(&gh); } - if (S_ISREG(mode)) { - inode->i_op = &gfs2_file_iops; - inode->i_fop = &gfs2_file_fops; - inode->i_mapping->a_ops = &gfs2_file_aops; - } else if (S_ISDIR(mode)) { - inode->i_op = &gfs2_dir_iops; - inode->i_fop = &gfs2_dir_fops; - } else if (S_ISLNK(mode)) { - inode->i_op = &gfs2_symlink_iops; - } else { - inode->i_op = &gfs2_dev_iops; - } - - unlock_new_inode(inode); + gfs2_set_iop(inode); } +gfs2_nfsbypass: return inode; fail_glock: gfs2_glock_dq(&ip->i_iopen_gh); diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 3268a2fed672..4517ac82c01c 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -47,6 +47,7 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, void gfs2_inode_attr_in(struct gfs2_inode *ip); +void gfs2_set_iop(struct inode *inode); struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, u64 no_addr, u64 no_formal_ino); struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 0fe14478a54d..e317db2a5548 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c @@ -27,12 +27,7 @@ #include "util.h" #define GFS2_SMALL_FH_SIZE 4 -#define GFS2_LARGE_FH_SIZE 10 - -struct gfs2_fh_obj { - struct gfs2_inum_host this; - u32 imode; -}; +#define GFS2_LARGE_FH_SIZE 8 static struct dentry *gfs2_decode_fh(struct super_block *sb, __u32 *p, @@ -43,11 +38,8 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, void *context) { __be32 *fh = (__force __be32 *)p; - struct gfs2_fh_obj fh_obj; - struct gfs2_inum_host *this, parent; + struct gfs2_inum_host inum, parent; - this = &fh_obj.this; - fh_obj.imode = DT_UNKNOWN; memset(&parent, 0, sizeof(struct gfs2_inum)); switch (fh_len) { @@ -56,18 +48,17 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, parent.no_formal_ino |= be32_to_cpu(fh[5]); parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; parent.no_addr |= be32_to_cpu(fh[7]); - fh_obj.imode = be32_to_cpu(fh[8]); case GFS2_SMALL_FH_SIZE: - this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; - this->no_formal_ino |= be32_to_cpu(fh[1]); - this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; - this->no_addr |= be32_to_cpu(fh[3]); + inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; + inum.no_formal_ino |= be32_to_cpu(fh[1]); + inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; + inum.no_addr |= be32_to_cpu(fh[3]); break; default: return NULL; } - return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, + return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent, acceptable, context); } @@ -102,9 +93,6 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); fh[6] = cpu_to_be32(ip->i_no_addr >> 32); fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); - - fh[8] = cpu_to_be32(inode->i_mode); - fh[9] = 0; /* pad to double word */ *len = GFS2_LARGE_FH_SIZE; iput(inode); @@ -201,8 +189,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child) static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) { struct gfs2_sbd *sdp = sb->s_fs_info; - struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; - struct gfs2_inum_host *inum = &fh_obj->this; + struct gfs2_inum_host *inum = inum_obj; struct gfs2_holder i_gh, ri_gh, rgd_gh; struct gfs2_rgrpd *rgd; struct inode *inode; @@ -245,9 +232,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) gfs2_glock_dq_uninit(&rgd_gh); gfs2_glock_dq_uninit(&ri_gh); - inode = gfs2_inode_lookup(sb, fh_obj->imode, + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, - inum->no_formal_ino); + 0); if (!inode) goto fail; if (IS_ERR(inode)) { @@ -260,6 +247,11 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) iput(inode); goto fail; } + + /* Pick up the works we bypass in gfs2_inode_lookup */ + if (inode->i_state & I_NEW) + gfs2_set_iop(inode); + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { iput(inode); goto fail; diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7fb74484af63..e4e040625153 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -872,7 +872,7 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) continue; *last_unlinked = no_addr; inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, - no_addr, 0); + no_addr, -1); if (!IS_ERR(inode)) return inode; } From ac90a2552500996c529d5f0ddc16a9bf60bf670d Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 6 Jul 2007 09:47:08 -0500 Subject: [PATCH 185/551] [DLM] dump more lock values Add two more output fields (lkb_flags and rsb nodeid) to the new debugfs file that dumps one lock per line. Also, dump all locks instead of just mastered locks. Accordingly, use a suffix of _locks instead of _master. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/debug_fs.c | 80 ++++++++++++++++++++++--------------------- fs/dlm/dlm_internal.h | 2 +- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 9f5de37706a9..12c3bfd5e660 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -27,7 +27,7 @@ static struct dentry *dlm_root; struct rsb_iter { int entry; - int master; + int locks; int header; struct dlm_ls *ls; struct list_head *next; @@ -60,8 +60,8 @@ static char *print_lockmode(int mode) } } -static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, - struct dlm_rsb *res) +static void print_resource_lock(struct seq_file *s, struct dlm_lkb *lkb, + struct dlm_rsb *res) { seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode)); @@ -134,15 +134,15 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s) /* Print the locks attached to this resource */ seq_printf(s, "Granted Queue\n"); list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) - print_lock(s, lkb, res); + print_resource_lock(s, lkb, res); seq_printf(s, "Conversion Queue\n"); list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) - print_lock(s, lkb, res); + print_resource_lock(s, lkb, res); seq_printf(s, "Waiting Queue\n"); list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) - print_lock(s, lkb, res); + print_resource_lock(s, lkb, res); if (list_empty(&res->res_lookup)) goto out; @@ -160,8 +160,7 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s) return 0; } -static void print_master_lock(struct seq_file *s, struct dlm_lkb *lkb, - struct dlm_rsb *r) +static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r) { struct dlm_user_args *ua; unsigned int waiting = 0; @@ -176,37 +175,40 @@ static void print_master_lock(struct seq_file *s, struct dlm_lkb *lkb, if (lkb->lkb_timestamp) waiting = jiffies_to_msecs(jiffies - lkb->lkb_timestamp); - /* id nodeid remid pid xid flags sts grmode rqmode time_ms len name */ + /* id nodeid remid pid xid exflags flags sts grmode rqmode time_ms + r_nodeid r_len r_name */ - seq_printf(s, "%x %d %x %u %llu %x %d %d %d %u %d \"%s\"\n", + seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %u %u %d \"%s\"\n", lkb->lkb_id, lkb->lkb_nodeid, lkb->lkb_remid, lkb->lkb_ownpid, (unsigned long long)xid, lkb->lkb_exflags, + lkb->lkb_flags, lkb->lkb_status, lkb->lkb_grmode, lkb->lkb_rqmode, waiting, + r->res_nodeid, r->res_length, r->res_name); } -static int print_master_resource(struct dlm_rsb *r, struct seq_file *s) +static int print_locks(struct dlm_rsb *r, struct seq_file *s) { struct dlm_lkb *lkb; lock_rsb(r); list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) - print_master_lock(s, lkb, r); + print_lock(s, lkb, r); list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) - print_master_lock(s, lkb, r); + print_lock(s, lkb, r); list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) - print_master_lock(s, lkb, r); + print_lock(s, lkb, r); unlock_rsb(r); return 0; @@ -325,14 +327,14 @@ static int rsb_seq_show(struct seq_file *file, void *iter_ptr) { struct rsb_iter *ri = iter_ptr; - if (ri->master) { + if (ri->locks) { if (ri->header) { - seq_printf(file, "id nodeid remid pid xid flags sts " - "grmode rqmode time_ms len name\n"); + seq_printf(file, "id nodeid remid pid xid exflags flags " + "sts grmode rqmode time_ms r_nodeid " + "r_len r_name\n"); ri->header = 0; } - if (is_master(ri->rsb)) - print_master_resource(ri->rsb, file); + print_locks(ri->rsb, file); } else { print_resource(ri->rsb, file); } @@ -371,10 +373,10 @@ static const struct file_operations rsb_fops = { }; /* - * Dump master lock state + * Dump state in compact per-lock listing */ -static struct rsb_iter *master_iter_init(struct dlm_ls *ls, loff_t *pos) +static struct rsb_iter *locks_iter_init(struct dlm_ls *ls, loff_t *pos) { struct rsb_iter *ri; @@ -385,7 +387,7 @@ static struct rsb_iter *master_iter_init(struct dlm_ls *ls, loff_t *pos) ri->ls = ls; ri->entry = 0; ri->next = NULL; - ri->master = 1; + ri->locks = 1; if (*pos == 0) ri->header = 1; @@ -398,12 +400,12 @@ static struct rsb_iter *master_iter_init(struct dlm_ls *ls, loff_t *pos) return ri; } -static void *master_seq_start(struct seq_file *file, loff_t *pos) +static void *locks_seq_start(struct seq_file *file, loff_t *pos) { struct rsb_iter *ri; loff_t n = *pos; - ri = master_iter_init(file->private, pos); + ri = locks_iter_init(file->private, pos); if (!ri) return NULL; @@ -417,19 +419,19 @@ static void *master_seq_start(struct seq_file *file, loff_t *pos) return ri; } -static struct seq_operations master_seq_ops = { - .start = master_seq_start, +static struct seq_operations locks_seq_ops = { + .start = locks_seq_start, .next = rsb_seq_next, .stop = rsb_seq_stop, .show = rsb_seq_show, }; -static int master_open(struct inode *inode, struct file *file) +static int locks_open(struct inode *inode, struct file *file) { struct seq_file *seq; int ret; - ret = seq_open(file, &master_seq_ops); + ret = seq_open(file, &locks_seq_ops); if (ret) return ret; @@ -439,9 +441,9 @@ static int master_open(struct inode *inode, struct file *file) return 0; } -static const struct file_operations master_fops = { +static const struct file_operations locks_fops = { .owner = THIS_MODULE, - .open = master_open, + .open = locks_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release @@ -515,14 +517,14 @@ int dlm_create_debug_file(struct dlm_ls *ls) } memset(name, 0, sizeof(name)); - snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_master", ls->ls_name); + snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name); - ls->ls_debug_master_dentry = debugfs_create_file(name, - S_IFREG | S_IRUGO, - dlm_root, - ls, - &master_fops); - if (!ls->ls_debug_master_dentry) { + ls->ls_debug_locks_dentry = debugfs_create_file(name, + S_IFREG | S_IRUGO, + dlm_root, + ls, + &locks_fops); + if (!ls->ls_debug_locks_dentry) { debugfs_remove(ls->ls_debug_waiters_dentry); debugfs_remove(ls->ls_debug_rsb_dentry); return -ENOMEM; @@ -537,8 +539,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls) debugfs_remove(ls->ls_debug_rsb_dentry); if (ls->ls_debug_waiters_dentry) debugfs_remove(ls->ls_debug_waiters_dentry); - if (ls->ls_debug_master_dentry) - debugfs_remove(ls->ls_debug_master_dentry); + if (ls->ls_debug_locks_dentry) + debugfs_remove(ls->ls_debug_locks_dentry); } int dlm_register_debugfs(void) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 8ac081882c78..74901e981e10 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -471,7 +471,7 @@ struct dlm_ls { struct dentry *ls_debug_rsb_dentry; /* debugfs */ struct dentry *ls_debug_waiters_dentry; /* debugfs */ - struct dentry *ls_debug_master_dentry; /* debugfs */ + struct dentry *ls_debug_locks_dentry; /* debugfs */ wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ int ls_uevent_result; From 58037eb961f859607b161c50d9d4ecb374de1e8f Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 30 May 2007 15:07:13 +0200 Subject: [PATCH 186/551] HID: make debugging output runtime-configurable There have been many reports recently about broken HID devices, the diagnosis of which required users to recompile their kernels in order to be able to provide debugging output needed for coding a quirk for a particular device. This patch makes CONFIG_HID_DEBUG default y if !EMBEDDED and makes it possible to control debugging output produced by HID code by supplying 'debug=1' module parameter. Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-core.c | 93 +++++++++++++++++---------------- drivers/hid/hid-debug.c | 15 ++++++ drivers/hid/hid-input.c | 26 ++++----- drivers/hid/usbhid/hid-core.c | 38 +++++++------- drivers/hid/usbhid/hid-lgff.c | 10 ++-- drivers/hid/usbhid/hid-quirks.c | 8 +-- drivers/hid/usbhid/hid-tmff.c | 2 +- drivers/hid/usbhid/hid-zpff.c | 8 +-- drivers/hid/usbhid/hiddev.c | 2 +- drivers/hid/usbhid/usbkbd.c | 6 +-- include/linux/hid.h | 20 +++++-- 12 files changed, 122 insertions(+), 107 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8fbe9fdac128..5b004b2b1a4e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -24,6 +24,7 @@ config HID config HID_DEBUG bool "HID debugging support" + default y if !EMBEDDED depends on HID ---help--- This option lets the HID layer output diagnostics about its internal diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6ec04e79f685..317cf8a7b63c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -40,6 +40,13 @@ #define DRIVER_DESC "HID core driver" #define DRIVER_LICENSE "GPL" +#ifdef CONFIG_HID_DEBUG +int hid_debug = 0; +module_param_named(debug, hid_debug, bool, 0600); +MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off"); +EXPORT_SYMBOL_GPL(hid_debug); +#endif + /* * Register a new report for a device. */ @@ -78,7 +85,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned struct hid_field *field; if (report->maxfield == HID_MAX_FIELDS) { - dbg("too many fields in report"); + dbg_hid("too many fields in report\n"); return NULL; } @@ -106,7 +113,7 @@ static int open_collection(struct hid_parser *parser, unsigned type) usage = parser->local.usage[0]; if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { - dbg("collection stack overflow"); + dbg_hid("collection stack overflow\n"); return -1; } @@ -114,7 +121,7 @@ static int open_collection(struct hid_parser *parser, unsigned type) collection = kmalloc(sizeof(struct hid_collection) * parser->device->collection_size * 2, GFP_KERNEL); if (collection == NULL) { - dbg("failed to reallocate collection array"); + dbg_hid("failed to reallocate collection array\n"); return -1; } memcpy(collection, parser->device->collection, @@ -150,7 +157,7 @@ static int open_collection(struct hid_parser *parser, unsigned type) static int close_collection(struct hid_parser *parser) { if (!parser->collection_stack_ptr) { - dbg("collection stack underflow"); + dbg_hid("collection stack underflow\n"); return -1; } parser->collection_stack_ptr--; @@ -178,7 +185,7 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) static int hid_add_usage(struct hid_parser *parser, unsigned usage) { if (parser->local.usage_index >= HID_MAX_USAGES) { - dbg("usage index exceeded"); + dbg_hid("usage index exceeded\n"); return -1; } parser->local.usage[parser->local.usage_index] = usage; @@ -202,12 +209,12 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign int i; if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { - dbg("hid_register_report failed"); + dbg_hid("hid_register_report failed\n"); return -1; } if (parser->global.logical_maximum < parser->global.logical_minimum) { - dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); + dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum); return -1; } @@ -287,7 +294,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_PUSH: if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg("global enviroment stack overflow"); + dbg_hid("global enviroment stack overflow\n"); return -1; } @@ -298,7 +305,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_POP: if (!parser->global_stack_ptr) { - dbg("global enviroment stack underflow"); + dbg_hid("global enviroment stack underflow\n"); return -1; } @@ -342,27 +349,27 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: if ((parser->global.report_size = item_udata(item)) > 32) { - dbg("invalid report_size %d", parser->global.report_size); + dbg_hid("invalid report_size %d\n", parser->global.report_size); return -1; } return 0; case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { - dbg("invalid report_count %d", parser->global.report_count); + dbg_hid("invalid report_count %d\n", parser->global.report_count); return -1; } return 0; case HID_GLOBAL_ITEM_TAG_REPORT_ID: if ((parser->global.report_id = item_udata(item)) == 0) { - dbg("report_id 0 is invalid"); + dbg_hid("report_id 0 is invalid\n"); return -1; } return 0; default: - dbg("unknown global tag 0x%x", item->tag); + dbg_hid("unknown global tag 0x%x\n", item->tag); return -1; } } @@ -377,7 +384,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) unsigned n; if (item->size == 0) { - dbg("item data expected for local item"); + dbg_hid("item data expected for local item\n"); return -1; } @@ -395,14 +402,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) * items and the first delimiter set. */ if (parser->local.delimiter_depth != 0) { - dbg("nested delimiters"); + dbg_hid("nested delimiters\n"); return -1; } parser->local.delimiter_depth++; parser->local.delimiter_branch++; } else { if (parser->local.delimiter_depth < 1) { - dbg("bogus close delimiter"); + dbg_hid("bogus close delimiter\n"); return -1; } parser->local.delimiter_depth--; @@ -412,7 +419,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) case HID_LOCAL_ITEM_TAG_USAGE: if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); + dbg_hid("alternative usage ignored\n"); return 0; } @@ -424,7 +431,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); + dbg_hid("alternative usage ignored\n"); return 0; } @@ -437,7 +444,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: if (parser->local.delimiter_branch > 1) { - dbg("alternative usage ignored"); + dbg_hid("alternative usage ignored\n"); return 0; } @@ -446,14 +453,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) for (n = parser->local.usage_minimum; n <= data; n++) if (hid_add_usage(parser, n)) { - dbg("hid_add_usage failed\n"); + dbg_hid("hid_add_usage failed\n"); return -1; } return 0; default: - dbg("unknown local item tag 0x%x", item->tag); + dbg_hid("unknown local item tag 0x%x\n", item->tag); return 0; } return 0; @@ -487,7 +494,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) ret = hid_add_field(parser, HID_FEATURE_REPORT, data); break; default: - dbg("unknown main item tag 0x%x", item->tag); + dbg_hid("unknown main item tag 0x%x\n", item->tag); ret = 0; } @@ -502,7 +509,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) { - dbg("reserved item type, tag 0x%x", item->tag); + dbg_hid("reserved item type, tag 0x%x\n", item->tag); return 0; } @@ -667,14 +674,14 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) while ((start = fetch_item(start, end, &item)) != NULL) { if (item.format != HID_ITEM_FORMAT_SHORT) { - dbg("unexpected long global item"); + dbg_hid("unexpected long global item\n"); hid_free_device(device); vfree(parser); return NULL; } if (dispatch_type[item.type](parser, &item)) { - dbg("item %u %u %u %u parsing failed\n", + dbg_hid("item %u %u %u %u parsing failed\n", item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); hid_free_device(device); vfree(parser); @@ -683,13 +690,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (start == end) { if (parser->collection_stack_ptr) { - dbg("unbalanced collection at end of report description"); + dbg_hid("unbalanced collection at end of report description\n"); hid_free_device(device); vfree(parser); return NULL; } if (parser->local.delimiter_depth) { - dbg("unbalanced delimiter at end of report description"); + dbg_hid("unbalanced delimiter at end of report description\n"); hid_free_device(device); vfree(parser); return NULL; @@ -699,7 +706,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) } } - dbg("item fetching failed at offset %d\n", (int)(end - start)); + dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); hid_free_device(device); vfree(parser); return NULL; @@ -915,13 +922,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) hid_dump_input(field->usage + offset, value); if (offset >= field->report_count) { - dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); + dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); hid_dump_field(field, 8); return -1; } if (field->logical_minimum < 0) { if (value != snto32(s32ton(value, size), size)) { - dbg("value %d is out of range", value); + dbg_hid("value %d is out of range\n", value); return -1; } } @@ -934,19 +941,17 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i { struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; - int n, rsize; + int n, rsize, i; if (!hid) return -ENODEV; if (!size) { - dbg("empty report"); + dbg_hid("empty report\n"); return -1; } -#ifdef CONFIG_HID_DEBUG - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); -#endif + dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); n = 0; /* Normally report number is 0 */ if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ @@ -954,25 +959,21 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i size--; } -#ifdef CONFIG_HID_DEBUG - { - int i; - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size); - for (i = 0; i < size; i++) - printk(" %02x", data[i]); - printk("\n"); - } -#endif + /* dump the report descriptor */ + dbg_hid("report %d (size %u) = ", n, size); + for (i = 0; i < size; i++) + dbg_hid_line(" %02x", data[i]); + dbg_hid_line("\n"); if (!(report = report_enum->report_id_hash[n])) { - dbg("undefined report_id %d received", n); + dbg_hid("undefined report_id %d received\n", n); return -1; } rsize = ((report->size - 1) >> 3) + 1; if (size < rsize) { - dbg("report %d is too short, (%d < %d)", report->id, size, rsize); + dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize); memset(data + size, 0, rsize - size); } diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 83c4126b37c3..a13757b78980 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -347,6 +347,9 @@ static void resolv_usage_page(unsigned page) { void hid_resolv_usage(unsigned usage) { const struct hid_usage_entry *p; + if (!hid_debug) + return; + resolv_usage_page(usage >> 16); printk("."); for (p = hid_usage_table; p->description; p++) @@ -369,6 +372,9 @@ __inline__ static void tab(int n) { void hid_dump_field(struct hid_field *field, int n) { int j; + if (!hid_debug) + return; + if (field->physical) { tab(n); printk("Physical("); @@ -466,6 +472,9 @@ void hid_dump_device(struct hid_device *device) { unsigned i,k; static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; + if (!hid_debug) + return; + for (i = 0; i < HID_REPORT_TYPES; i++) { report_enum = device->report_enum + i; list = report_enum->report_list.next; @@ -489,6 +498,9 @@ void hid_dump_device(struct hid_device *device) { EXPORT_SYMBOL_GPL(hid_dump_device); void hid_dump_input(struct hid_usage *usage, __s32 value) { + if (!hid_debug) + return; + printk("hid-debug: input "); hid_resolv_usage(usage->hid); printk(" = %d\n", value); @@ -758,6 +770,9 @@ static char **names[EV_MAX + 1] = { void hid_resolv_event(__u8 type, __u16 code) { + if (!hid_debug) + return; + printk("%s.%s", events[type] ? events[type] : "?", names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); } diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 7f817897b178..38595d3935ce 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -308,9 +308,7 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode, clear_bit(old_keycode, dev->keybit); set_bit(usage->code, dev->keybit); -#ifdef CONFIG_HID_DEBUG - printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); -#endif + dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); /* Set the keybit for the old keycode if the old keycode is used * by another key */ if (hidinput_find_key (hid, 0, old_keycode)) @@ -333,11 +331,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel field->hidinput = hidinput; -#ifdef CONFIG_HID_DEBUG - printk(KERN_DEBUG "Mapping: "); + dbg_hid("Mapping: "); hid_resolv_usage(usage->hid); - printk(" ---> "); -#endif + dbg_hid_line(" ---> "); if (field->flags & HID_MAIN_ITEM_CONSTANT) goto ignore; @@ -819,15 +815,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } hid_resolv_event(usage->type, usage->code); -#ifdef CONFIG_HID_DEBUG - printk("\n"); -#endif + + dbg_hid_line("\n"); + return; ignore: -#ifdef CONFIG_HID_DEBUG - printk("IGNORED\n"); -#endif + dbg_hid_line("IGNORED\n"); return; } @@ -896,12 +890,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct } if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ - dbg("Maximum Effects - %d",value); + dbg_hid("Maximum Effects - %d\n",value); return; } if (usage->hid == (HID_UP_PID | 0x7fUL)) { - dbg("PID Pool Report\n"); + dbg_hid("PID Pool Report\n"); return; } @@ -994,7 +988,7 @@ int hidinput_connect(struct hid_device *hid) if (!hidinput || !input_dev) { kfree(hidinput); input_free_device(input_dev); - err("Out of memory during hid input probe"); + err_hid("Out of memory during hid input probe"); return -1; } diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index d91b9dac6dff..1eb2c64bc44a 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -127,7 +127,7 @@ static void hid_reset(struct work_struct *work) hid_io_error(hid); break; default: - err("can't reset device, %s-%s/input%d, status %d", + err_hid("can't reset device, %s-%s/input%d, status %d", hid_to_usb_dev(hid)->bus->bus_name, hid_to_usb_dev(hid)->devpath, usbhid->ifnum, rc); @@ -220,7 +220,7 @@ static void hid_irq_in(struct urb *urb) if (status) { clear_bit(HID_IN_RUNNING, &usbhid->iofl); if (status != -EPERM) { - err("can't resubmit intr, %s-%s/input%d, status %d", + err_hid("can't resubmit intr, %s-%s/input%d, status %d", hid_to_usb_dev(hid)->bus->bus_name, hid_to_usb_dev(hid)->devpath, usbhid->ifnum, status); @@ -240,10 +240,10 @@ static int hid_submit_out(struct hid_device *hid) usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); usbhid->urbout->dev = hid_to_usb_dev(hid); - dbg("submitting out urb"); + dbg_hid("submitting out urb\n"); if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { - err("usb_submit_urb(out) failed"); + err_hid("usb_submit_urb(out) failed"); return -1; } @@ -287,12 +287,12 @@ static int hid_submit_ctrl(struct hid_device *hid) usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); usbhid->cr->wLength = cpu_to_le16(len); - dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", + dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n", usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { - err("usb_submit_urb(ctrl) failed"); + err_hid("usb_submit_urb(ctrl) failed"); return -1; } @@ -474,7 +474,7 @@ int usbhid_wait_io(struct hid_device *hid) if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), 10*HZ)) { - dbg("timeout waiting for ctrl or out queue to clear"); + dbg_hid("timeout waiting for ctrl or out queue to clear\n"); return -1; } @@ -667,7 +667,7 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) USB_CTRL_GET_TIMEOUT); if (result < 0) - err("%s failed: %d\n", __func__, result); + err_hid("%s failed: %d\n", __func__, result); kfree(buf); } @@ -746,7 +746,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && (!interface->desc.bNumEndpoints || usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { - dbg("class descriptor not present\n"); + dbg_hid("class descriptor not present\n"); return NULL; } @@ -755,19 +755,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { - dbg("weird size of report descriptor (%u)", rsize); + dbg_hid("weird size of report descriptor (%u)\n", rsize); return NULL; } if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { - dbg("couldn't allocate rdesc memory"); + dbg_hid("couldn't allocate rdesc memory\n"); return NULL; } hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { - dbg("reading report descriptor failed"); + dbg_hid("reading report descriptor failed\n"); kfree(rdesc); return NULL; } @@ -781,15 +781,13 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (quirks & HID_QUIRK_SWAPPED_MIN_MAX) hid_fixup_cypress_descriptor(rdesc, rsize); -#ifdef CONFIG_HID_DEBUG - printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); + dbg_hid("report descriptor (size %u, read %d) = ", rsize, n); for (n = 0; n < rsize; n++) - printk(" %02x", (unsigned char) rdesc[n]); - printk("\n"); -#endif + dbg_hid_line(" %02x", (unsigned char) rdesc[n]); + dbg_hid_line("\n"); if (!(hid = hid_parse_report(rdesc, n))) { - dbg("parsing report descriptor failed"); + dbg_hid("parsing report descriptor failed\n"); kfree(rdesc); return NULL; } @@ -861,7 +859,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) } if (!usbhid->urbin) { - err("couldn't find an input interrupt endpoint"); + err_hid("couldn't find an input interrupt endpoint"); goto fail; } @@ -978,7 +976,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) int i; char *c; - dbg("HID probe called for ifnum %d", + dbg_hid("HID probe called for ifnum %d\n", intf->altsetting->desc.bInterfaceNumber); if (!(hid = usb_hid_configure(intf))) diff --git a/drivers/hid/usbhid/hid-lgff.c b/drivers/hid/usbhid/hid-lgff.c index c5cd4107d6af..4b7ab6a46d93 100644 --- a/drivers/hid/usbhid/hid-lgff.c +++ b/drivers/hid/usbhid/hid-lgff.c @@ -78,7 +78,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef report->field[0]->value[1] = 0x08; report->field[0]->value[2] = x; report->field[0]->value[3] = y; - dbg("(x, y)=(%04x, %04x)", x, y); + dbg_hid("(x, y)=(%04x, %04x)\n", x, y); usbhid_submit_report(hid, report, USB_DIR_OUT); break; @@ -93,7 +93,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef report->field[0]->value[1] = 0x00; report->field[0]->value[2] = left; report->field[0]->value[3] = right; - dbg("(left, right)=(%04x, %04x)", left, right); + dbg_hid("(left, right)=(%04x, %04x)\n", left, right); usbhid_submit_report(hid, report, USB_DIR_OUT); break; } @@ -113,20 +113,20 @@ int hid_lgff_init(struct hid_device* hid) /* Find the report to use */ if (list_empty(report_list)) { - err("No output report found"); + err_hid("No output report found"); return -1; } /* Check that the report looks ok */ report = list_entry(report_list->next, struct hid_report, list); if (!report) { - err("NULL output report"); + err_hid("NULL output report"); return -1; } field = report->field[0]; if (!field) { - err("NULL field"); + err_hid("NULL field"); return -1; } diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index f6c4145dc202..a418ebfe39b8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -493,7 +493,7 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor, } if (bl_entry != NULL) - dbg("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", + dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", bl_entry->quirks, bl_entry->idVendor, bl_entry->idProduct); @@ -521,13 +521,13 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, int list_edited = 0; if (!idVendor) { - dbg("Cannot add a quirk with idVendor = 0"); + dbg_hid("Cannot add a quirk with idVendor = 0\n"); return -EINVAL; } q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); if (!q_new) { - dbg("Could not allocate quirks_list_struct"); + dbg_hid("Could not allocate quirks_list_struct\n"); return -ENOMEM; } @@ -643,7 +643,7 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor, bl_entry = &hid_blacklist[n]; if (bl_entry != NULL) - dbg("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", + dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", bl_entry->quirks, bl_entry->idVendor, bl_entry->idProduct); return bl_entry; diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c index ab5ba6ef891c..555bb48b4295 100644 --- a/drivers/hid/usbhid/hid-tmff.c +++ b/drivers/hid/usbhid/hid-tmff.c @@ -70,7 +70,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef tmff->rumble->value[0] = left; tmff->rumble->value[1] = right; - dbg("(left,right)=(%08x, %08x)", left, right); + dbg_hid("(left,right)=(%08x, %08x)\n", left, right); usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); return 0; diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c index a7fbffcdaf36..5a688274f6a3 100644 --- a/drivers/hid/usbhid/hid-zpff.c +++ b/drivers/hid/usbhid/hid-zpff.c @@ -21,10 +21,6 @@ */ -/* #define DEBUG */ - -#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg) - #include #include #include @@ -49,14 +45,14 @@ static int hid_zpff_play(struct input_dev *dev, void *data, left = effect->u.rumble.strong_magnitude; right = effect->u.rumble.weak_magnitude; - debug("called with 0x%04x 0x%04x", left, right); + dbg_hid("called with 0x%04x 0x%04x\n", left, right); left = left * 0x7f / 0xffff; right = right * 0x7f / 0xffff; zpff->report->field[2]->value[0] = left; zpff->report->field[3]->value[0] = right; - debug("running with 0x%02x 0x%02x", left, right); + dbg_hid("running with 0x%02x 0x%02x\n", left, right); usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); return 0; diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 488d61bdbf2c..e793127f971e 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -779,7 +779,7 @@ int hiddev_connect(struct hid_device *hid) retval = usb_register_dev(usbhid->intf, &hiddev_class); if (retval) { - err("Not able to get a minor for this device."); + err_hid("Not able to get a minor for this device."); kfree(hiddev); return -1; } diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 130978780713..b76b02f7b52d 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c @@ -125,7 +125,7 @@ static void usb_kbd_irq(struct urb *urb) resubmit: i = usb_submit_urb (urb, GFP_ATOMIC); if (i) - err ("can't resubmit intr, %s-%s/input0, status %d", + err_hid ("can't resubmit intr, %s-%s/input0, status %d", kbd->usbdev->bus->bus_name, kbd->usbdev->devpath, i); } @@ -151,7 +151,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type, *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - err("usb_submit_urb(leds) failed"); + err_hid("usb_submit_urb(leds) failed"); return 0; } @@ -169,7 +169,7 @@ static void usb_kbd_led(struct urb *urb) *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - err("usb_submit_urb(leds) failed"); + err_hid("usb_submit_urb(leds) failed"); } static int usb_kbd_open(struct input_dev *dev) diff --git a/include/linux/hid.h b/include/linux/hid.h index 827ee748fd4c..eb53d9a9ae54 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -488,6 +488,11 @@ struct hid_descriptor { #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) /* HID core API */ + +#ifdef CONFIG_HID_DEBUG +extern int hid_debug; +#endif + extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); @@ -523,14 +528,19 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } #else static inline int hid_ff_init(struct hid_device *hid) { return -1; } #endif -#ifdef DEBUG -#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ - __FILE__ , ## arg) + +#ifdef CONFIG_HID_DEBUG +#define dbg_hid(format, arg...) if (hid_debug) \ + printk(KERN_DEBUG "%s: " format ,\ + __FILE__ , ## arg) +#define dbg_hid_line(format, arg...) if (hid_debug) \ + printk(format, ## arg) #else -#define dbg(format, arg...) do {} while (0) +#define dbg_hid(format, arg...) do {} while (0) +#define dbg_hid_line dbg_hid #endif -#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ +#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ __FILE__ , ## arg) #endif From cb1d93c98c49e268918e35e45e5c407fc4dc4e9f Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 14 May 2007 10:20:29 +0200 Subject: [PATCH 187/551] HID: input mapping for Chicony KU-0418 tactical pad Chicony KU-0418 (aka Saitek PZ08AU gaming keyboard) has a separate "tactical pad" with 11 non-functional buttons - they generate usage codes from 0xff00 (MSVENDOR) usage page. Special case handling for this keyboard added, so no later clash with MSVENDOR mappings is going to occur. Pointed out in bugzilla #7352 Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 7f817897b178..ce6d7644e6a1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -688,7 +688,28 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; case HID_UP_MSVENDOR: - goto ignore; + + /* special case - Chicony Chicony KU-0418 tactical pad */ + if (device->vendor == 0x04f2 && device->product == 0x0418) { + set_bit(EV_REP, input->evbit); + switch(usage->hid & HID_USAGE) { + case 0xff01: map_key_clear(BTN_1); break; + case 0xff02: map_key_clear(BTN_2); break; + case 0xff03: map_key_clear(BTN_3); break; + case 0xff04: map_key_clear(BTN_4); break; + case 0xff05: map_key_clear(BTN_5); break; + case 0xff06: map_key_clear(BTN_6); break; + case 0xff07: map_key_clear(BTN_7); break; + case 0xff08: map_key_clear(BTN_8); break; + case 0xff09: map_key_clear(BTN_9); break; + case 0xff0a: map_key_clear(BTN_A); break; + case 0xff0b: map_key_clear(BTN_B); break; + default: goto ignore; + } + } else { + goto ignore; + } + break; case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ From defd208681b721dbf2b69347cca5302d60246405 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Sat, 19 May 2007 16:28:04 +0200 Subject: [PATCH 188/551] HID: force hid-input for Microsoft SideWinder GameVoice device Microsoft SideWinder GameVoice driver is a trivial device with a few buttons (0x09 HID usage) and an audio connector, which just forwards the audio input into oridinary sound card present in the computer. Despite this fact, the only interface of this device reports itself as a Telephony/Headset type of HID device. This is apparently incorrect - the device itself doesn't provide any audio/telephony functionality. This is achieved in userland application which only needs to receive the button events from the HID driver. This patch establishes a new quirk which forces hid-input to claim a device it will otherwise leave untouched. Reported-by: Tomas Carnecky Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 2 +- drivers/hid/usbhid/hid-quirks.c | 4 ++++ include/linux/hid.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index ce6d7644e6a1..70bf54167083 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -997,7 +997,7 @@ int hidinput_connect(struct hid_device *hid) if (IS_INPUT_APPLICATION(hid->collection[i].usage)) break; - if (i == hid->maxcollection) + if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0) return -1; if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index f6c4145dc202..62a7f1e9b58c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -209,6 +209,9 @@ #define USB_DEVICE_ID_MGE_UPS 0xffff #define USB_DEVICE_ID_MGE_UPS1 0x0001 +#define USB_VENDOR_ID_MICROSOFT 0x045e +#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b + #define USB_VENDOR_ID_NEC 0x073e #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 @@ -290,6 +293,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, diff --git a/include/linux/hid.h b/include/linux/hid.h index 827ee748fd4c..6e45d1056e1b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -276,6 +276,7 @@ struct hid_item { #define HID_QUIRK_DUPLICATE_USAGES 0x00200000 #define HID_QUIRK_RESET_LEDS 0x00400000 #define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000 +#define HID_QUIRK_HIDINPUT 0x01000000 /* * This is the global environment of the parser. This information is From 3cd709866f639d24b0d0f38567c19662c98ea92e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 30 Apr 2007 13:27:48 +0200 Subject: [PATCH 189/551] HID: Use menuconfig objects Make a "menuconfig" out of the Kconfig objects "menu, ..., endmenu", so that the user can disable all the options in that menu at once instead of having to disable each option separately. Signed-off-by: Jan Engelhardt Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8fbe9fdac128..d96eb0865829 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1,8 +1,12 @@ # # HID driver configuration # -menu "HID Devices" +menuconfig HID_SUPPORT + bool "HID Devices" depends on INPUT + default y + +if HID_SUPPORT config HID tristate "Generic HID support" @@ -38,5 +42,4 @@ config HID_DEBUG source "drivers/hid/usbhid/Kconfig" -endmenu - +endif # HID_SUPPORT From 2fa45a4cffd0c4ab4e238e8ad3b4f9b0c10ac1f3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 30 May 2007 11:11:12 -0400 Subject: [PATCH 190/551] USB HID: avoid flush_scheduled_work() This patch (as914) replaces a call to flush_scheduled_work() with cancel_work_sync(), in order to help avoid potential deadlocks. Signed-off-by: Alan Stern Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index d91b9dac6dff..093abb5c9879 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -956,7 +956,7 @@ static void hid_disconnect(struct usb_interface *intf) usb_kill_urb(usbhid->urbctrl); del_timer_sync(&usbhid->io_retry); - flush_scheduled_work(); + cancel_work_sync(&usbhid->reset_work); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hid); From 1b3ebe931195725cceee825c430a8bd5319c2566 Mon Sep 17 00:00:00 2001 From: Julien Eyries Date: Tue, 12 Jun 2007 10:12:40 +0200 Subject: [PATCH 191/551] HID: support for Gameron dual psx adaptor This patch provides support for the Gameron dual psx adaptor. The modification is to add the quirk HID_QUIRK_MULTI_INPUT for this specific USB device. Signed-off-by: Julien Eyries Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 62a7f1e9b58c..a320c24ea6e8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -105,6 +105,9 @@ #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 +#define USB_VENDOR_ID_GAMERON 0x0810 +#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 + #define USB_VENDOR_ID_GLAB 0x06c2 #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 #define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 @@ -281,6 +284,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, From 5fce620c0c7caa9e8d9588e8dcc66c52c456851a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Jun 2007 22:04:32 +0200 Subject: [PATCH 192/551] HID: fix mismatch between hid-input HUT find/search mapping and the HUT When comparing usb vs ps2 / testing the keycodes generated for the easy access keys on my trust (microsoft compatible) keyboard. I noticed the search key generated the keycode for find when connected through USB. This lead me to check the consumer page mappings in hid-input.c . And it turns out the the mapping for ID 0x221 deviates from the HUT standard document: http://www.usb.org/developers/devclass_docs/Hut1_12.pdf Currently it is incorrectly mapped to find, whereas it should be mapped to search. I also added missing bindings for ID 0x21f, the real find and for 0x222, goto. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 70bf54167083..6cb884638fda 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -598,7 +598,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x21b: map_key_clear(KEY_COPY); break; case 0x21c: map_key_clear(KEY_CUT); break; case 0x21d: map_key_clear(KEY_PASTE); break; - case 0x221: map_key_clear(KEY_FIND); break; + case 0x21f: map_key_clear(KEY_FIND); break; + case 0x221: map_key_clear(KEY_SEARCH); break; + case 0x222: map_key_clear(KEY_GOTO); break; case 0x223: map_key_clear(KEY_HOMEPAGE); break; case 0x224: map_key_clear(KEY_BACK); break; case 0x225: map_key_clear(KEY_FORWARD); break; From 92d9e6e607eb7f8f1d2a43935f45cf300cf6fdf8 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 18 Jun 2007 13:30:11 +0200 Subject: [PATCH 193/551] HID: support for Petalynx Maxter remote control Petalynx Maxter remote control [1] 0x18b1/0x0037 emits 0xfa and 0xfc from consumer page (reserved in HUT 1.12) for back and more keys. It also emits a few usages from LOGIVENDOR page, which need adding. Also, this device has broken report descriptor - the reported maximum is too low - it doesn't contain the range for 'back' and 'more' keys, so we need to bump it up before the report descriptor is being parsed. Besides all this, it also requires NOGET quirk. This patch does so. [1] http://www.elmak.pl/index.php?option=com_phpshop&page=shop.browse&category_id=14&ext=opis&lang=en Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 17 +++++++++++++++-- drivers/hid/usbhid/hid-core.c | 18 ++++++++++++++++++ drivers/hid/usbhid/hid-quirks.c | 5 +++++ include/linux/hid.h | 1 + 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 6cb884638fda..1b8b33341408 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -566,6 +566,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x0e5: map_key_clear(KEY_BASSBOOST); break; case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; + + /* reserved in HUT 1.12. Reported on Petalynx remote */ + case 0x0f6: map_key_clear(KEY_NEXT); break; + case 0x0fa: map_key_clear(KEY_BACK); break; + case 0x183: map_key_clear(KEY_CONFIG); break; case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; case 0x185: map_key_clear(KEY_EDITOR); break; @@ -727,10 +732,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } break; - case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ - + case HID_UP_LOGIVENDOR: set_bit(EV_REP, input->evbit); switch(usage->hid & HID_USAGE) { + /* Reported on Logitech Ultra X Media Remote */ case 0x004: map_key_clear(KEY_AGAIN); break; case 0x00d: map_key_clear(KEY_HOME); break; case 0x024: map_key_clear(KEY_SHUFFLE); break; @@ -748,6 +753,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x04d: map_key_clear(KEY_SUBTITLE); break; case 0x051: map_key_clear(KEY_RED); break; case 0x052: map_key_clear(KEY_CLOSE); break; + + /* Reported on Petalynx Maxter remote */ + case 0x05a: map_key_clear(KEY_TEXT); break; + case 0x05b: map_key_clear(KEY_RED); break; + case 0x05c: map_key_clear(KEY_GREEN); break; + case 0x05d: map_key_clear(KEY_YELLOW); break; + case 0x05e: map_key_clear(KEY_BLUE); break; + default: goto ignore; } break; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 093abb5c9879..ef7b881aab3a 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -688,6 +688,21 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) } } +/* Petalynx Maxter Remote has maximum for consumer page set too low */ +static void hid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 60 && rdesc[39] == 0x2a + && rdesc[40] == 0xf5 + && rdesc[41] == 0x00 + && rdesc[59] == 0x26 + && rdesc[60] == 0xf9 + && rdesc[61] == 0x00) { + info("Fixing up Petalynx Maxter Remote report descriptor"); + rdesc[60] = 0xfa; + rdesc[40] = 0xfa; + } +} + /* * Some USB barcode readers from cypress have usage min and usage max in * the wrong order @@ -781,6 +796,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (quirks & HID_QUIRK_SWAPPED_MIN_MAX) hid_fixup_cypress_descriptor(rdesc, rsize); + if (quirks & HID_QUIRK_PETALYNX_DESCRIPTOR) + hid_fixup_petalynx_descriptor(rdesc, rsize); + #ifdef CONFIG_HID_DEBUG printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); for (n = 0; n < rsize; n++) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a320c24ea6e8..ad8a4ac8e43c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -226,6 +226,9 @@ #define USB_VENDOR_ID_PANTHERLORD 0x0810 #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 +#define USB_VENDOR_ID_PETALYNX 0x18b1 +#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 + #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 @@ -426,6 +429,8 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_PETALYNX_DESCRIPTOR | HID_QUIRK_NOGET }, + { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, diff --git a/include/linux/hid.h b/include/linux/hid.h index 6e45d1056e1b..e41067951dd9 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -277,6 +277,7 @@ struct hid_item { #define HID_QUIRK_RESET_LEDS 0x00400000 #define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000 #define HID_QUIRK_HIDINPUT 0x01000000 +#define HID_QUIRK_PETALYNX_DESCRIPTOR 0x02000000 /* * This is the global environment of the parser. This information is From b8e98f1c47b743e56f8ebe21006199cefd577ce5 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 18 Jun 2007 17:41:14 +0200 Subject: [PATCH 194/551] HID: Add NOGET quirk for all NCR devices Devices manufactured by NCR have userspace hiddev-based drivers, which do all the necessary device querying by themselves. The devices must not be queried directly by the generic HID driver, as reported by NCR engineers. Cc: Petr Ostadal Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ad8a4ac8e43c..a78f5187b6ef 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -215,6 +215,10 @@ #define USB_VENDOR_ID_MICROSOFT 0x045e #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b +#define USB_VENDOR_ID_NCR 0x0404 +#define USB_DEVICE_ID_NCR_FIRST 0x0300 +#define USB_DEVICE_ID_NCR_LAST 0x03ff + #define USB_VENDOR_ID_NEC 0x073e #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 @@ -688,6 +692,12 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) return HID_QUIRK_IGNORE; + /* NCR devices must not be queried for reports */ + if (idVendor == USB_VENDOR_ID_NCR && + idProduct >= USB_DEVICE_ID_NCR_FIRST && + idProduct <= USB_DEVICE_ID_NCR_LAST) + return HID_QUIRK_NOGET; + down_read(&dquirks_rwsem); bl_entry = usbhid_exists_dquirk(idVendor, idProduct); if (!bl_entry) From ea9a4a8b0e5a34eca6613e39d21be879d92ecff5 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 19 Jun 2007 14:09:14 +0200 Subject: [PATCH 195/551] HID: separate quirks for report descriptor fixup Lately there have been quite a lot of bug reports against broken devices which require us to fix their report descriptor in the runtime, before it is passed to the HID parser. Those devices have eaten quite an amount of our quirks space, which isn't particularly necessary - the quirks are not needed after the report descriptor is parsed, and they just consume bits. Therefore this patch separates the quirks for report descriptor fixup, and moves their handling into separate code. The quirks are then forgotten as soon as the report descriptor has been parsed. Module parameter 'rdesc_quirks' is introduced to be able to modify these quirks in runtime in a similar way to 'quirks' parameter for ordinary HID quirks. Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 89 ++---------------- drivers/hid/usbhid/hid-quirks.c | 155 +++++++++++++++++++++++++++++--- include/linux/hid.h | 36 ++++---- 3 files changed, 174 insertions(+), 106 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ef7b881aab3a..3efc3734cec2 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -60,6 +60,12 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " " quirks=vendorID:productID:quirks" " where vendorID, productID, and quirks are all in" " 0x-prefixed hex"); +static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; +module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444); +MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying " + " rdesc_quirks=vendorID:productID:rdesc_quirks" + " where vendorID, productID, and rdesc_quirks are all in" + " 0x-prefixed hex"); /* * Input submission and I/O error handler. */ @@ -632,20 +638,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); } -/* - * Cherry Cymotion keyboard have an invalid HID report descriptor, - * that needs fixing before we can parse it. - */ - -static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) -{ - if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - info("Fixing up Cherry Cymotion report descriptor"); - rdesc[11] = rdesc[16] = 0xff; - rdesc[12] = rdesc[17] = 0x03; - } -} - /* * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller * to "operational". Without this, the ps3 controller will not report any @@ -672,61 +664,6 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) kfree(buf); } -/* - * Certain Logitech keyboards send in report #3 keys which are far - * above the logical maximum described in descriptor. This extends - * the original value of 0x28c of logical maximum to 0x104d - */ -static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) -{ - if (rsize >= 90 && rdesc[83] == 0x26 - && rdesc[84] == 0x8c - && rdesc[85] == 0x02) { - info("Fixing up Logitech keyboard report descriptor"); - rdesc[84] = rdesc[89] = 0x4d; - rdesc[85] = rdesc[90] = 0x10; - } -} - -/* Petalynx Maxter Remote has maximum for consumer page set too low */ -static void hid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) -{ - if (rsize >= 60 && rdesc[39] == 0x2a - && rdesc[40] == 0xf5 - && rdesc[41] == 0x00 - && rdesc[59] == 0x26 - && rdesc[60] == 0xf9 - && rdesc[61] == 0x00) { - info("Fixing up Petalynx Maxter Remote report descriptor"); - rdesc[60] = 0xfa; - rdesc[40] = 0xfa; - } -} - -/* - * Some USB barcode readers from cypress have usage min and usage max in - * the wrong order - */ -static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize) -{ - short fixed = 0; - int i; - - for (i = 0; i < rsize - 4; i++) { - if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) { - unsigned char tmp; - - rdesc[i] = 0x19; rdesc[i+2] = 0x29; - tmp = rdesc[i+3]; - rdesc[i+3] = rdesc[i+1]; - rdesc[i+1] = tmp; - } - } - - if (fixed) - info("Fixing up Cypress report descriptor"); -} - static struct hid_device *usb_hid_configure(struct usb_interface *intf) { struct usb_host_interface *interface = intf->cur_altsetting; @@ -787,17 +724,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) return NULL; } - if ((quirks & HID_QUIRK_CYMOTION)) - hid_fixup_cymotion_descriptor(rdesc, rsize); - - if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR) - hid_fixup_logitech_descriptor(rdesc, rsize); - - if (quirks & HID_QUIRK_SWAPPED_MIN_MAX) - hid_fixup_cypress_descriptor(rdesc, rsize); - - if (quirks & HID_QUIRK_PETALYNX_DESCRIPTOR) - hid_fixup_petalynx_descriptor(rdesc, rsize); + usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct), rdesc, + rsize, rdesc_quirks_param); #ifdef CONFIG_HID_DEBUG printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a78f5187b6ef..a75c236fcafc 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -299,8 +299,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, - { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, @@ -424,17 +422,11 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR }, - { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR }, - { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_LOGITECH_DESCRIPTOR }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_PETALYNX_DESCRIPTOR | HID_QUIRK_NOGET }, - { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, @@ -443,6 +435,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, @@ -466,8 +459,26 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX }, + { 0, 0 } +}; + +/* Quirks for devices which require report descriptor fixup go here */ +static const struct hid_rdesc_blacklist { + __u16 idVendor; + __u16 idProduct; + __u32 quirks; +} hid_rdesc_blacklist[] = { + + { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION }, + + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, + + { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, + + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, { 0, 0 } }; @@ -576,7 +587,6 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, return 0; } - /** * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory * @@ -709,3 +719,126 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) return quirks; } +/* + * Cherry Cymotion keyboard have an invalid HID report descriptor, + * that needs fixing before we can parse it. + */ +static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize) +{ + if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { + printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n"); + rdesc[11] = rdesc[16] = 0xff; + rdesc[12] = rdesc[17] = 0x03; + } +} + + +/* + * Certain Logitech keyboards send in report #3 keys which are far + * above the logical maximum described in descriptor. This extends + * the original value of 0x28c of logical maximum to 0x104d + */ +static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 90 && rdesc[83] == 0x26 + && rdesc[84] == 0x8c + && rdesc[85] == 0x02) { + printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n"); + rdesc[84] = rdesc[89] = 0x4d; + rdesc[85] = rdesc[90] = 0x10; + } +} + +/* Petalynx Maxter Remote has maximum for consumer page set too low */ +static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) +{ + if (rsize >= 60 && rdesc[39] == 0x2a + && rdesc[40] == 0xf5 + && rdesc[41] == 0x00 + && rdesc[59] == 0x26 + && rdesc[60] == 0xf9 + && rdesc[61] == 0x00) { + printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n"); + rdesc[60] = 0xfa; + rdesc[40] = 0xfa; + } +} + +/* + * Some USB barcode readers from cypress have usage min and usage max in + * the wrong order + */ +static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize) +{ + short fixed = 0; + int i; + + for (i = 0; i < rsize - 4; i++) { + if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) { + unsigned char tmp; + + rdesc[i] = 0x19; rdesc[i+2] = 0x29; + tmp = rdesc[i+3]; + rdesc[i+3] = rdesc[i+1]; + rdesc[i+1] = tmp; + } + } + + if (fixed) + printk(KERN_INFO "Fixing up Cypress report descriptor\n"); +} + + +static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) +{ + if ((quirks & HID_QUIRK_RDESC_CYMOTION)) + usbhid_fixup_cymotion_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_LOGITECH) + usbhid_fixup_logitech_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX) + usbhid_fixup_cypress_descriptor(rdesc, rsize); + + if (quirks & HID_QUIRK_RDESC_PETALYNX) + usbhid_fixup_petalynx_descriptor(rdesc, rsize); +} + +/** + * usbhid_fixup_report_descriptor: check if report descriptor needs fixup + * + * Description: + * Walks the hid_rdesc_blacklist[] array and checks whether the device + * is known to have broken report descriptor that needs to be fixed up + * prior to entering the HID parser + * + * Returns: nothing + */ +void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct, + char *rdesc, unsigned rsize, char **quirks_param) +{ + int n, m; + u16 paramVendor, paramProduct; + u32 quirks; + + /* static rdesc quirk entries */ + for (n = 0; hid_rdesc_blacklist[n].idVendor; n++) + if (hid_rdesc_blacklist[n].idVendor == idVendor && + hid_rdesc_blacklist[n].idProduct == idProduct) + __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks, + rdesc, rsize); + + /* runtime rdesc quirk entries handling */ + for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) { + m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", + ¶mVendor, ¶mProduct, &quirks); + + if (m != 3) + printk(KERN_WARNING + "Could not parse HID quirk module param %s\n", + quirks_param[n]); + else if (paramVendor == idVendor && paramProduct == idProduct) + __usbhid_fixup_report_descriptor(quirks, rdesc, rsize); + } + +} diff --git a/include/linux/hid.h b/include/linux/hid.h index e41067951dd9..4daf5eea78a1 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -263,21 +263,26 @@ struct hid_item { #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 #define HID_QUIRK_MIGHTYMOUSE 0x00000400 -#define HID_QUIRK_CYMOTION 0x00000800 -#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 -#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 -#define HID_QUIRK_INVERT_HWHEEL 0x00004000 -#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 -#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 -#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 -#define HID_QUIRK_IGNORE_MOUSE 0x00040000 -#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 -#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 -#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 -#define HID_QUIRK_RESET_LEDS 0x00400000 -#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000 -#define HID_QUIRK_HIDINPUT 0x01000000 -#define HID_QUIRK_PETALYNX_DESCRIPTOR 0x02000000 +#define HID_QUIRK_POWERBOOK_HAS_FN 0x00000800 +#define HID_QUIRK_POWERBOOK_FN_ON 0x00001000 +#define HID_QUIRK_INVERT_HWHEEL 0x00002000 +#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00004000 +#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000 +#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 +#define HID_QUIRK_IGNORE_MOUSE 0x00020000 +#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 +#define HID_QUIRK_DUPLICATE_USAGES 0x00080000 +#define HID_QUIRK_RESET_LEDS 0x00100000 +#define HID_QUIRK_HIDINPUT 0x00200000 + +/* + * Separate quirks for runtime report descriptor fixup + */ + +#define HID_QUIRK_RDESC_CYMOTION 0x00000001 +#define HID_QUIRK_RDESC_LOGITECH 0x00000002 +#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 +#define HID_QUIRK_RDESC_PETALYNX 0x00000008 /* * This is the global environment of the parser. This information is @@ -508,6 +513,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks); int usbhid_quirks_init(char **quirks_param); void usbhid_quirks_exit(void); +void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); From 816cbfda8b5113629707f604660204701e93b7ce Mon Sep 17 00:00:00 2001 From: Diogo Kastrup Date: Tue, 19 Jun 2007 14:16:15 +0200 Subject: [PATCH 196/551] HID: fix autocentering of PID devices When setting the autocentering of PID devices, PID_DIRECTION_ENABLE is not being explicitely set to 1. This results in autocentering working only on the vertical axis when this field is preset to 0. Fix that by setting it explicitely to 1 when preparing the set_effect report for autocentering spring effect. Signed-off-by: Diogo Kastrup Signed-off-by: Anssi Hannula Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-pidff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index f5a90e950e6b..011326178c06 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -738,6 +738,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0; pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0; pidff_set(&pidff->set_effect[PID_GAIN], magnitude); + pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1; pidff->set_effect[PID_START_DELAY].value[0] = 0; usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], From 5f9c464aaa1ba3a773c47004e98eb1f3aa2ab2a4 Mon Sep 17 00:00:00 2001 From: Ryo Dairiki Date: Mon, 25 Jun 2007 10:31:12 +0200 Subject: [PATCH 197/551] HID: support for logitech cordless desktop LX500 special mapping This keyboard has wireless mouse which has left, middle, right buttons and 2-dimensional scrolling wheel. Unfornetuly, this wheel reports side scrolling events and 11 or 12 button events at the same time. I've wrote a patch to fix this mapping. I'm not sure if this mapping is proper for buttons, because , for example, there is no entry for "burn cd" in input.h. The patch also supress 11 and 12 button events from mouse when you scroll the wheel left and right. With this patch, only side scrolling events are reported. (This mouse has only 4 buttons and 2D wheel. There is no such buttons like 11 and 12.) Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 28 ++++++++++++++++++++++++++++ drivers/hid/usbhid/hid-quirks.c | 3 +++ include/linux/hid.h | 2 ++ 3 files changed, 33 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 1b8b33341408..60de16a83c3e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -60,6 +60,19 @@ static const unsigned char hid_keyboard[256] = { 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; +/* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */ +#define LOGITECH_EXPANDED_KEYMAP_SIZE 80 +static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = { + 0,216, 0,213,175,156, 0, 0, 0, 0, + 144, 0, 0, 0, 0, 0, 0, 0, 0,212, + 174,167,152,161,112, 0, 0, 0,154, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,183,184,185,186,187, + 188,189,190,191,192,193,194, 0, 0, 0 +}; + static const struct { __s32 x; __s32 y; @@ -378,6 +391,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } } + /* Special handling for Logitech Cordless Desktop */ + if (field->application != HID_GD_MOUSE) { + if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) { + int hid = usage->hid & HID_USAGE; + if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0) + code = logitech_expanded_keymap[hid]; + } + } else { + if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) { + int hid = usage->hid & HID_USAGE; + if (hid == 7 || hid == 8) + goto ignore; + } + } + map_key(code); break; diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a75c236fcafc..5614a70f564f 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -201,6 +201,7 @@ #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 +#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 #define USB_DEVICE_ID_DINOVO_EDGE 0xc714 @@ -422,6 +423,8 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, diff --git a/include/linux/hid.h b/include/linux/hid.h index 4daf5eea78a1..44b64f0d0555 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -274,6 +274,8 @@ struct hid_item { #define HID_QUIRK_DUPLICATE_USAGES 0x00080000 #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 +#define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL 0x00400000 +#define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP 0x00800000 /* * Separate quirks for runtime report descriptor fixup From 3c5f4b25f3552c9bcb52eb956753a3c8140480b7 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 28 Jun 2007 22:33:47 +0200 Subject: [PATCH 198/551] HID: Logitech keyboard 0xc311 needs reset leds quirk The keyboard 0x046d/0xc311 needs reset leds quirk Tested-by: Antonino Ingargiola Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 5614a70f564f..ce6c970b5979 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -199,6 +199,7 @@ #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 +#define USB_DEVICE_ID_LOGITECH_KBD 0xc311 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 @@ -461,6 +462,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, { 0, 0 } }; From 2c1d8aea2ca76df1b1de2aed23e3ceda2a044ed1 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 4 Jul 2007 16:45:59 +0200 Subject: [PATCH 199/551] HID: handle cases of volume knobs generating relative values There are some devices (for example Dell Multimedia Keyboard SK-8135) that have a volume control knob which generates relative events instead of absolute. hid-input maps them to ABS_VOLUME. HUT pages don't restrict volume to absolute values. Adding REL_VOLUME doesn't seem feasible, nothing knows how to handle it. This patch translates relative ABS_VOLUME events into appropriate number of series of VOLUME_UP or VOLUME_DOWN events respectively, so that userspace sees the correct values in the end. kernel.org bugzilla 5233 Reported-by: Jochen Eisinger Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 60de16a83c3e..bf7e307503cc 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -882,6 +882,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel field->dpad = usage->code; } + /* for those devices which produce Consumer volume usage as relative, + * we emulate pressing volumeup/volumedown appropriate number of times + * in hidinput_hid_event() + */ + if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && + (usage->code == ABS_VOLUME)) { + set_bit(KEY_VOLUMEUP, input->keybit); + set_bit(KEY_VOLUMEDOWN, input->keybit); + } + hid_resolv_event(usage->type, usage->code); #ifdef CONFIG_HID_DEBUG printk("\n"); @@ -972,6 +982,21 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ return; + if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && + (usage->code == ABS_VOLUME)) { + int count = abs(value); + int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN; + int i; + + for (i = 0; i < count; i++) { + input_event(input, EV_KEY, direction, 1); + input_sync(input); + input_event(input, EV_KEY, direction, 0); + input_sync(input); + } + return; + } + input_event(input, usage->type, usage->code, value); if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) From a0a24741cac414aba5918e9939afafa70c37f952 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 9 Jul 2007 15:43:07 +0100 Subject: [PATCH 200/551] [GFS2] Small fixes to logging code This reverts part of an earlier patch which tried to reclaim gfs2_bufdata structures too early and resulted in a "use after free" case (this bit from me). Also a change to not write out log headers unless we really need to (in the case of flushing nothing we don't need a header) from Bob. Signed-off-by: Steven Whitehouse Signed-off-by: Bob Peterson --- fs/gfs2/log.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 8fcfb784f906..f49a12e24086 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -237,10 +237,7 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) list_del(&bd->bd_ail_st_list); list_del(&bd->bd_ail_gl_list); atomic_dec(&bd->bd_gl->gl_ail_count); - if (bd->bd_bh) - brelse(bd->bd_bh); - else - kmem_cache_free(gfs2_bufdata_cachep, bd); + brelse(bd->bd_bh); } } @@ -583,6 +580,7 @@ static void log_flush_commit(struct gfs2_sbd *sdp) struct list_head *head = &sdp->sd_log_flush_list; struct gfs2_log_buf *lb; struct buffer_head *bh; + int flushcount = 0; while (!list_empty(head)) { lb = list_entry(head->next, struct gfs2_log_buf, lb_list); @@ -599,9 +597,20 @@ static void log_flush_commit(struct gfs2_sbd *sdp) } else brelse(bh); kfree(lb); + flushcount++; } - log_write_header(sdp, 0, 0); + /* If nothing was journaled, the header is unplanned and unwanted. */ + if (flushcount) { + log_write_header(sdp, 0, 0); + } else { + unsigned int tail; + tail = current_tail(sdp); + + gfs2_ail1_empty(sdp, 0); + if (sdp->sd_log_tail != tail) + log_pull_tail(sdp, tail); + } } /** From fafbae87db88a73b166d3bc3294d209207f27056 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 201/551] libata-acpi: implement ata_acpi_associate() * Add acpi_handle to ata_host and ata_port. Rename ata_device->obj_handle to ->acpi_handle and move it above such that it doesn't get cleared on reconfiguration. * Replace ACPI node association which ata_acpi_associate() which is called once during host initialization. Unlike the previous implementation, ata_acpi_associate() uses ATA_FLAG_ACPI_SATA to choose between IDE or SATA ACPI hierarchy and uses simple child look up instead of recursive walk to match the nodes. This is way safer and simpler. Please read the following message for more info. http://article.gmane.org/gmane.linux.ide/17554 Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 371 +++++--------------------------------- drivers/ata/libata-core.c | 3 + drivers/ata/libata.h | 2 + include/linux/libata.h | 13 +- 4 files changed, 64 insertions(+), 325 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 02236739b40f..eda4263b4017 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -24,10 +24,8 @@ #include #include -#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff) -#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */ #define NO_PORT_MULT 0xffff -#define SATA_ADR_RSVD 0xffffffff +#define SATA_ADR(root,pmp) (((root) << 16) | (pmp)) #define REGS_PER_GTF 7 struct taskfile_array { @@ -42,230 +40,64 @@ static int is_pci_dev(struct device *dev) return (dev->bus == &pci_bus_type); } -/** - * sata_get_dev_handle - finds acpi_handle and PCI device.function - * @dev: device to locate - * @handle: returned acpi_handle for @dev - * @pcidevfn: return PCI device.func for @dev - * - * This function is somewhat SATA-specific. Or at least the - * PATA & SATA versions of this function are different, - * so it's not entirely generic code. - * - * Returns 0 on success, <0 on error. - */ -static int sata_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) +static void ata_acpi_associate_sata_port(struct ata_port *ap) { - struct pci_dev *pci_dev; - acpi_integer addr; + acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT); - if (!is_pci_dev(dev)) - return -ENODEV; + ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); +} - pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */ - /* Please refer to the ACPI spec for the syntax of _ADR. */ - addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); - *pcidevfn = addr; - *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); - if (!*handle) - return -ENODEV; - return 0; +static void ata_acpi_associate_ide_port(struct ata_port *ap) +{ + int max_devices, i; + + ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no); + if (!ap->acpi_handle) + return; + + max_devices = 1; + if (ap->flags & ATA_FLAG_SLAVE_POSS) + max_devices++; + + for (i = 0; i < max_devices; i++) { + struct ata_device *dev = &ap->device[i]; + + dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); + } } /** - * pata_get_dev_handle - finds acpi_handle and PCI device.function - * @dev: device to locate - * @handle: returned acpi_handle for @dev - * @pcidevfn: return PCI device.func for @dev + * ata_acpi_associate - associate ATA host with ACPI objects + * @host: target ATA host * - * The PATA and SATA versions of this function are different. + * Look up ACPI objects associated with @host and initialize + * acpi_handle fields of @host, its ports and devices accordingly. * - * Returns 0 on success, <0 on error. + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ -static int pata_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) +void ata_acpi_associate(struct ata_host *host) { - unsigned int bus, devnum, func; - acpi_integer addr; - acpi_handle dev_handle, parent_handle; - struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; - acpi_status status; - struct acpi_device_info *dinfo = NULL; - int ret = -ENODEV; - struct pci_dev *pdev; + int i; - if (!is_pci_dev(dev)) - return -ENODEV; + if (!is_pci_dev(host->dev) || libata_noacpi) + return; - pdev = to_pci_dev(dev); + host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev); + if (!host->acpi_handle) + return; - bus = pdev->bus->number; - devnum = PCI_SLOT(pdev->devfn); - func = PCI_FUNC(pdev->devfn); + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; - dev_handle = DEVICE_ACPI_HANDLE(dev); - parent_handle = DEVICE_ACPI_HANDLE(dev->parent); - - status = acpi_get_object_info(parent_handle, &buffer); - if (ACPI_FAILURE(status)) - goto err; - - dinfo = buffer.pointer; - if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && - dinfo->address == bus) { - /* ACPI spec for _ADR for PCI bus: */ - addr = (acpi_integer)(devnum << 16 | func); - *pcidevfn = addr; - *handle = dev_handle; - } else { - goto err; + if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA) + ata_acpi_associate_sata_port(ap); + else + ata_acpi_associate_ide_port(ap); } - - if (!*handle) - goto err; - ret = 0; -err: - kfree(dinfo); - return ret; -} - -struct walk_info { /* can be trimmed some */ - struct device *dev; - struct acpi_device *adev; - acpi_handle handle; - acpi_integer pcidevfn; - unsigned int drivenum; - acpi_handle obj_handle; - struct ata_port *ataport; - struct ata_device *atadev; - u32 sata_adr; - int status; - char basepath[ACPI_PATHNAME_MAX]; - int basepath_len; -}; - -static acpi_status get_devices(acpi_handle handle, - u32 level, void *context, void **return_value) -{ - acpi_status status; - struct walk_info *winfo = context; - struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL}; - char *pathname; - struct acpi_buffer buffer; - struct acpi_device_info *dinfo; - - status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf); - if (status) - goto ret; - pathname = namebuf.pointer; - - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - status = acpi_get_object_info(handle, &buffer); - if (ACPI_FAILURE(status)) - goto out2; - - dinfo = buffer.pointer; - - /* find full device path name for pcidevfn */ - if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && - dinfo->address == winfo->pcidevfn) { - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - ":%s: matches pcidevfn (0x%llx)\n", - pathname, winfo->pcidevfn); - strlcpy(winfo->basepath, pathname, - sizeof(winfo->basepath)); - winfo->basepath_len = strlen(pathname); - goto out; - } - - /* if basepath is not yet known, ignore this object */ - if (!winfo->basepath_len) - goto out; - - /* if this object is in scope of basepath, maybe use it */ - if (strncmp(pathname, winfo->basepath, - winfo->basepath_len) == 0) { - if (!(dinfo->valid & ACPI_VALID_ADR)) - goto out; - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "GOT ONE: (%s) root_port = 0x%llx," - " port_num = 0x%llx\n", pathname, - SATA_ROOT_PORT(dinfo->address), - SATA_PORT_NUMBER(dinfo->address)); - /* heuristics: */ - if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT) - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, - KERN_DEBUG, "warning: don't" - " know how to handle SATA port" - " multiplier\n"); - if (SATA_ROOT_PORT(dinfo->address) == - winfo->ataport->port_no && - SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) { - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, - KERN_DEBUG, - "THIS ^^^^^ is the requested" - " SATA drive (handle = 0x%p)\n", - handle); - winfo->sata_adr = dinfo->address; - winfo->obj_handle = handle; - } - } -out: - kfree(dinfo); -out2: - kfree(pathname); - -ret: - return status; -} - -/* Get the SATA drive _ADR object. */ -static int get_sata_adr(struct device *dev, acpi_handle handle, - acpi_integer pcidevfn, unsigned int drive, - struct ata_port *ap, - struct ata_device *atadev, u32 *dev_adr) -{ - acpi_status status; - struct walk_info *winfo; - int err = -ENOMEM; - - winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL); - if (!winfo) - goto out; - - winfo->dev = dev; - winfo->atadev = atadev; - winfo->ataport = ap; - if (acpi_bus_get_device(handle, &winfo->adev) < 0) - if (ata_msg_probe(ap)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "acpi_bus_get_device failed\n"); - winfo->handle = handle; - winfo->pcidevfn = pcidevfn; - winfo->drivenum = drive; - - status = acpi_get_devices(NULL, get_devices, winfo, NULL); - if (ACPI_FAILURE(status)) { - if (ata_msg_probe(ap)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "%s: acpi_get_devices failed\n", - __FUNCTION__); - err = -ENODEV; - } else { - *dev_adr = winfo->sata_adr; - atadev->obj_handle = winfo->obj_handle; - err = 0; - } - kfree(winfo); -out: - return err; } /** @@ -290,20 +122,15 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, { struct ata_port *ap = dev->ap; acpi_status status; - acpi_handle dev_handle = NULL; - acpi_handle chan_handle, drive_handle; - acpi_integer pcidevfn = 0; - u32 dev_adr; struct acpi_buffer output; union acpi_object *out_obj; - struct device *gdev = ap->host->dev; int err = -ENODEV; *gtf_length = 0; *gtf_address = 0UL; *obj_loc = 0UL; - if (libata_noacpi) + if (!dev->acpi_handle) return 0; if (ata_msg_probe(ap)) @@ -319,78 +146,14 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, goto out; } - /* Don't continue if device has no _ADR method. - * _GTF is intended for known motherboard devices. */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: pata_get_dev_handle failed (%d)\n", - __FUNCTION__, err); - goto out; - } - } else { - err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: sata_get_dev_handle failed (%d\n", - __FUNCTION__, err); - goto out; - } - } - - /* Get this drive's _ADR info. if not already known. */ - if (!dev->obj_handle) { - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - /* get child objects of dev_handle == channel objects, - * + _their_ children == drive objects */ - /* channel is ap->port_no */ - chan_handle = acpi_get_child(dev_handle, - ap->port_no); - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: chan adr=%d: chan_handle=0x%p\n", - __FUNCTION__, ap->port_no, - chan_handle); - if (!chan_handle) { - err = -ENODEV; - goto out; - } - /* TBD: could also check ACPI object VALID bits */ - drive_handle = acpi_get_child(chan_handle, dev->devno); - if (!drive_handle) { - err = -ENODEV; - goto out; - } - dev_adr = dev->devno; - dev->obj_handle = drive_handle; - } else { /* for SATA mode */ - dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(gdev, dev_handle, pcidevfn, 0, - ap, dev, &dev_adr); - } - if (err < 0 || dev_adr == SATA_ADR_RSVD || - !dev->obj_handle) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: get_sata/pata_adr failed: " - "err=%d, dev_adr=%u, obj_handle=0x%p\n", - __FUNCTION__, err, dev_adr, - dev->obj_handle); - goto out; - } - } - /* Setting up output buffer */ output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ /* _GTF has no input parameters */ err = -EIO; - status = acpi_evaluate_object(dev->obj_handle, "_GTF", - NULL, &output); + status = acpi_evaluate_object(dev->acpi_handle, "_GTF", + NULL, &output); if (ACPI_FAILURE(status)) { if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, @@ -528,7 +291,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev, ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", __FUNCTION__, ap->port_no); - if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA)) + if (!(ap->flags & ATA_FLAG_ACPI_SATA)) return 0; if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) @@ -571,8 +334,6 @@ int ata_acpi_exec_tfs(struct ata_port *ap) unsigned long gtf_address; unsigned long obj_loc; - if (libata_noacpi) - return 0; /* * TBD - implement PATA support. For now, * we should not run GTF on PATA devices since some @@ -624,16 +385,12 @@ int ata_acpi_exec_tfs(struct ata_port *ap) int ata_acpi_push_id(struct ata_device *dev) { struct ata_port *ap = dev->ap; - acpi_handle handle; - acpi_integer pcidevfn; int err; - struct device *gdev = ap->host->dev; - u32 dev_adr; acpi_status status; struct acpi_object_list input; union acpi_object in_params[1]; - if (libata_noacpi) + if (!dev->acpi_handle) return 0; if (ata_msg_probe(ap)) @@ -648,34 +405,6 @@ int ata_acpi_push_id(struct ata_device *dev) goto out; } - /* Don't continue if device has no _ADR method. - * _SDD is intended for known motherboard devices. */ - err = sata_get_dev_handle(gdev, &handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: sata_get_dev_handle failed (%d\n", - __FUNCTION__, err); - goto out; - } - - /* Get this drive's _ADR info, if not already known */ - if (!dev->obj_handle) { - dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev, - &dev_adr); - if (err < 0 || dev_adr == SATA_ADR_RSVD || - !dev->obj_handle) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: get_sata_adr failed: " - "err=%d, dev_adr=%u, obj_handle=0x%p\n", - __FUNCTION__, err, dev_adr, - dev->obj_handle); - goto out; - } - } - /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ input.count = 1; @@ -687,7 +416,7 @@ int ata_acpi_push_id(struct ata_device *dev) /* It's OK for _SDD to be missing too. */ swap_buf_le16(dev->id, ATA_ID_WORDS); - status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL); + status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL); swap_buf_le16(dev->id, ATA_ID_WORDS); err = ACPI_FAILURE(status) ? -EIO : 0; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 981b397cb46b..5a46cdebc588 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6293,6 +6293,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) if (rc) return rc; + /* associate with ACPI nodes */ + ata_acpi_associate(host); + /* set cable, sata_spd_limit and report */ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 5e2466658420..29037cd7c651 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -98,9 +98,11 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI +extern void ata_acpi_associate(struct ata_host *host); extern int ata_acpi_exec_tfs(struct ata_port *ap); extern int ata_acpi_push_id(struct ata_device *dev); #else +static inline void ata_acpi_associate(struct ata_host *host) { } static inline int ata_acpi_exec_tfs(struct ata_port *ap) { return 0; diff --git a/include/linux/libata.h b/include/linux/libata.h index 620da7be07b7..d758168ee45d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -363,6 +363,9 @@ struct ata_host { void *private_data; const struct ata_port_operations *ops; unsigned long flags; +#ifdef CONFIG_ATA_ACPI + acpi_handle acpi_handle; +#endif struct ata_port *simplex_claimed; /* channel owning the DMA */ struct ata_port *ports[0]; }; @@ -429,6 +432,9 @@ struct ata_device { unsigned int devno; /* 0 or 1 */ unsigned long flags; /* ATA_DFLAG_xxx */ struct scsi_device *sdev; /* attached SCSI device */ +#ifdef CONFIG_ATA_ACPI + acpi_handle acpi_handle; +#endif /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ @@ -457,10 +463,6 @@ struct ata_device { struct ata_ering ering; int spdn_cnt; unsigned int horkage; /* List of broken features */ -#ifdef CONFIG_ATA_ACPI - /* ACPI objects info */ - acpi_handle obj_handle; -#endif }; /* Offset into struct ata_device. Fields above it are maintained @@ -549,6 +551,9 @@ struct ata_port { void *private_data; +#ifdef CONFIG_ATA_ACPI + acpi_handle acpi_handle; +#endif u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ }; From 4700c4bc9262a9e78f7197c4c41cc2be085d5276 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 202/551] libata-acpi: clean up ata_acpi_exec_tfs() This patch cleans up ata_acpi_exec_tfs() and its friends. * Rename taskfile_array to ata_acpi_gtf and make it __packed as it's used as argument to ACPI method, and use pointer to ata_acpi_gtf and number of taskfiles to represent _GTF taskfiles instead of a pointer casted into unsigned long and byte count. This makes argument re-checking in do_drive_set_taskfiles() unnecessary. * Pointer in void * not in unsigned long. * Clean up do_drive_get_GTF() error handling and make do_drive_get_GTF() return number of taskfiles on success, 0 if _GTF doesn't exist or doesn't contain valid ata. -errno on other errors. * Remove superflous check for acpi->buffer.pointer. * Update taskfile_load_raw() such that printed messages look similar to the messages printed by ata_eh_report(). * s/do_drive_get_GTF/ata_dev_get_GTF/ s/do_drive_set_taskfiles/ata_dev_set_taskfiles/ Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 224 +++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 114 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index eda4263b4017..4d36d254730b 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -28,9 +28,9 @@ #define SATA_ADR(root,pmp) (((root) << 16) | (pmp)) #define REGS_PER_GTF 7 -struct taskfile_array { - u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ -}; +struct ata_acpi_gtf { + u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ +} __packed; /* * Helper - belongs in the PCI layer somewhere eventually @@ -101,10 +101,10 @@ void ata_acpi_associate(struct ata_host *host) } /** - * do_drive_get_GTF - get the drive bootup default taskfile settings + * ata_dev_get_GTF - get the drive bootup default taskfile settings * @dev: target ATA device - * @gtf_length: number of bytes of _GTF data returned at @gtf_address - * @gtf_address: buffer containing _GTF taskfile arrays + * @gtf: output parameter for buffer containing _GTF taskfile arrays + * @ptr_to_free: pointer which should be freed * * This applies to both PATA and SATA drives. * @@ -114,24 +114,28 @@ void ata_acpi_associate(struct ata_host *host) * The is not known in advance, so have ACPI-CA * allocate the buffer as needed and return it, then free it later. * - * The returned @gtf_length and @gtf_address are only valid if the - * function return value is 0. + * LOCKING: + * EH context. + * + * RETURNS: + * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't + * contain valid data. -errno on other errors. */ -static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, - unsigned long *gtf_address, unsigned long *obj_loc) +static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, + void **ptr_to_free) { struct ata_port *ap = dev->ap; acpi_status status; struct acpi_buffer output; union acpi_object *out_obj; - int err = -ENODEV; + int rc = 0; - *gtf_length = 0; - *gtf_address = 0UL; - *obj_loc = 0UL; + /* set up output buffer */ + output.length = ACPI_ALLOCATE_BUFFER; + output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ if (!dev->acpi_handle) - return 0; + goto out_free; if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", @@ -143,23 +147,20 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, "ata_dev_present: %d, PORT_DISABLED: %lu\n", __FUNCTION__, ata_dev_enabled(dev), ap->flags & ATA_FLAG_DISABLED); - goto out; + goto out_free; } - /* Setting up output buffer */ - output.length = ACPI_ALLOCATE_BUFFER; - output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - /* _GTF has no input parameters */ - err = -EIO; - status = acpi_evaluate_object(dev->acpi_handle, "_GTF", - NULL, &output); + status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); + if (ACPI_FAILURE(status)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: Run _GTF error: status = 0x%x\n", - __FUNCTION__, status); - goto out; + if (status != AE_NOT_FOUND) { + ata_dev_printk(dev, KERN_WARNING, + "_GTF evaluation failed (AE 0x%x)\n", + status); + rc = -EIO; + } + goto out_free; } if (!output.length || !output.pointer) { @@ -169,43 +170,43 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, __FUNCTION__, (unsigned long long)output.length, output.pointer); - kfree(output.pointer); - goto out; + goto out_free; } out_obj = output.pointer; if (out_obj->type != ACPI_TYPE_BUFFER) { - kfree(output.pointer); if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " "error: expected object type of " " ACPI_TYPE_BUFFER, got 0x%x\n", __FUNCTION__, out_obj->type); - err = -ENOENT; - goto out; + rc = -EINVAL; + goto out_free; } - if (!out_obj->buffer.length || !out_obj->buffer.pointer || - out_obj->buffer.length % REGS_PER_GTF) { + if (out_obj->buffer.length % REGS_PER_GTF) { if (ata_msg_drv(ap)) ata_dev_printk(dev, KERN_ERR, "%s: unexpected GTF length (%d) or addr (0x%p)\n", __FUNCTION__, out_obj->buffer.length, out_obj->buffer.pointer); - err = -ENOENT; - goto out; + rc = -EINVAL; + goto out_free; } - *gtf_length = out_obj->buffer.length; - *gtf_address = (unsigned long)out_obj->buffer.pointer; - *obj_loc = (unsigned long)out_obj; + *ptr_to_free = out_obj; + *gtf = (void *)out_obj->buffer.pointer; + rc = out_obj->buffer.length / REGS_PER_GTF; + if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: returning " - "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", - __FUNCTION__, *gtf_length, *gtf_address, *obj_loc); - err = 0; -out: - return err; + "gtf=%p, gtf_count=%d, ptr_to_free=%p\n", + __FUNCTION__, *gtf, rc, *ptr_to_free); + return rc; + + out_free: + kfree(output.pointer); + return rc; } /** @@ -224,68 +225,78 @@ out: * function also waits for idle after writing control and before * writing the remaining registers. * - * LOCKING: TBD: - * Inherited from caller. + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ -static void taskfile_load_raw(struct ata_device *dev, - const struct taskfile_array *gtf) +static int taskfile_load_raw(struct ata_device *dev, + const struct ata_acpi_gtf *gtf) { struct ata_port *ap = dev->ap; - struct ata_taskfile tf; - unsigned int err; + struct ata_taskfile tf, rtf; + unsigned int err_mask; - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " - "%02x %02x %02x %02x %02x %02x %02x\n", - __FUNCTION__, - gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], - gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); - - if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0) - && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0) - && (gtf->tfa[6] == 0)) - return; + if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) + && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) + && (gtf->tf[6] == 0)) + return 0; ata_tf_init(dev, &tf); /* convert gtf to tf */ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ tf.protocol = ATA_PROT_NODATA; - tf.feature = gtf->tfa[0]; /* 0x1f1 */ - tf.nsect = gtf->tfa[1]; /* 0x1f2 */ - tf.lbal = gtf->tfa[2]; /* 0x1f3 */ - tf.lbam = gtf->tfa[3]; /* 0x1f4 */ - tf.lbah = gtf->tfa[4]; /* 0x1f5 */ - tf.device = gtf->tfa[5]; /* 0x1f6 */ - tf.command = gtf->tfa[6]; /* 0x1f7 */ + tf.feature = gtf->tf[0]; /* 0x1f1 */ + tf.nsect = gtf->tf[1]; /* 0x1f2 */ + tf.lbal = gtf->tf[2]; /* 0x1f3 */ + tf.lbam = gtf->tf[3]; /* 0x1f4 */ + tf.lbah = gtf->tf[4]; /* 0x1f5 */ + tf.device = gtf->tf[5]; /* 0x1f6 */ + tf.command = gtf->tf[6]; /* 0x1f7 */ - err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); - if (err && ata_msg_probe(ap)) + if (ata_msg_probe(ap)) + ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd " + "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n", + tf.command, tf.feature, tf.nsect, + tf.lbal, tf.lbam, tf.lbah, tf.device); + + rtf = tf; + err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0); + if (err_mask) { ata_dev_printk(dev, KERN_ERR, - "%s: ata_exec_internal failed: %u\n", - __FUNCTION__, err); + "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " + "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n", + tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, + tf.lbah, tf.device, err_mask, rtf.command, rtf.feature); + return -EIO; + } + + return 0; } /** - * do_drive_set_taskfiles - write the drive taskfile settings from _GTF + * ata_dev_set_taskfiles - write the drive taskfile settings from _GTF * @dev: target ATA device - * @gtf_length: total number of bytes of _GTF taskfiles - * @gtf_address: location of _GTF taskfile arrays + * @gtf: pointer to array of _GTF taskfiles to execute + * @gtf_count: number of taskfiles * * This applies to both PATA and SATA drives. * - * Write {gtf_address, length gtf_length} in groups of - * REGS_PER_GTF bytes. + * Execute taskfiles in @gtf. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ -static int do_drive_set_taskfiles(struct ata_device *dev, - unsigned int gtf_length, - unsigned long gtf_address) +static int ata_dev_set_taskfiles(struct ata_device *dev, + struct ata_acpi_gtf *gtf, int gtf_count) { struct ata_port *ap = dev->ap; - int err = -ENODEV; - int gtf_count = gtf_length / REGS_PER_GTF; int ix; - struct taskfile_array *gtf; if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", @@ -295,29 +306,13 @@ static int do_drive_set_taskfiles(struct ata_device *dev, return 0; if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) - goto out; - if (!gtf_count) /* shouldn't be here */ - goto out; + return -ENODEV; - if (gtf_length % REGS_PER_GTF) { - if (ata_msg_drv(ap)) - ata_dev_printk(dev, KERN_ERR, - "%s: unexpected GTF length (%d)\n", - __FUNCTION__, gtf_length); - goto out; - } + /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ + for (ix = 0; ix < gtf_count; ix++) + taskfile_load_raw(dev, gtf++); - for (ix = 0; ix < gtf_count; ix++) { - gtf = (struct taskfile_array *) - (gtf_address + ix * REGS_PER_GTF); - - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - taskfile_load_raw(dev, gtf); - } - - err = 0; -out: - return err; + return 0; } /** @@ -328,11 +323,7 @@ out: */ int ata_acpi_exec_tfs(struct ata_port *ap) { - int ix; - int ret = 0; - unsigned int gtf_length; - unsigned long gtf_address; - unsigned long obj_loc; + int ix, ret = 0; /* * TBD - implement PATA support. For now, @@ -344,12 +335,16 @@ int ata_acpi_exec_tfs(struct ata_port *ap) for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { struct ata_device *dev = &ap->device[ix]; + struct ata_acpi_gtf *gtf = NULL; + int gtf_count; + void *ptr_to_free = NULL; if (!ata_dev_enabled(dev)) continue; - ret = do_drive_get_GTF(dev, >f_length, >f_address, - &obj_loc); + ret = ata_dev_get_GTF(dev, >f, &ptr_to_free); + if (ret == 0) + continue; if (ret < 0) { if (ata_msg_probe(ap)) ata_port_printk(ap, KERN_DEBUG, @@ -357,9 +352,10 @@ int ata_acpi_exec_tfs(struct ata_port *ap) __FUNCTION__, ret); break; } + gtf_count = ret; - ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address); - kfree((void *)obj_loc); + ret = ata_dev_set_taskfiles(dev, gtf, gtf_count); + kfree(ptr_to_free); if (ret < 0) { if (ata_msg_probe(ap)) ata_port_printk(ap, KERN_DEBUG, From 69b16a5f4c4f1dab70d4d555c487c318c6878b3e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 203/551] libata-acpi: miscellaneous cleanups * Add missing LOCKING: and RETURNS: to function comment. * Don't conditionalize warning messages with ata_msg_probe(). Print directly with KERN_WARNING. * Drop duplicate debug messages. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 51 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 4d36d254730b..ae2077e1e78f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -175,21 +175,17 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, out_obj = output.pointer; if (out_obj->type != ACPI_TYPE_BUFFER) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " - "error: expected object type of " - " ACPI_TYPE_BUFFER, got 0x%x\n", - __FUNCTION__, out_obj->type); + ata_dev_printk(dev, KERN_WARNING, + "_GTF unexpected object type 0x%x\n", + out_obj->type); rc = -EINVAL; goto out_free; } if (out_obj->buffer.length % REGS_PER_GTF) { - if (ata_msg_drv(ap)) - ata_dev_printk(dev, KERN_ERR, - "%s: unexpected GTF length (%d) or addr (0x%p)\n", - __FUNCTION__, out_obj->buffer.length, - out_obj->buffer.pointer); + ata_dev_printk(dev, KERN_WARNING, + "unexpected _GTF length (%d)\n", + out_obj->buffer.length); rc = -EINVAL; goto out_free; } @@ -320,6 +316,12 @@ static int ata_dev_set_taskfiles(struct ata_device *dev, * @ap: the ata_port for the drive * * This applies to both PATA and SATA drives. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ int ata_acpi_exec_tfs(struct ata_port *ap) { @@ -345,24 +347,14 @@ int ata_acpi_exec_tfs(struct ata_port *ap) ret = ata_dev_get_GTF(dev, >f, &ptr_to_free); if (ret == 0) continue; - if (ret < 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - "%s: get_GTF error (%d)\n", - __FUNCTION__, ret); + if (ret < 0) break; - } gtf_count = ret; ret = ata_dev_set_taskfiles(dev, gtf, gtf_count); kfree(ptr_to_free); - if (ret < 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - "%s: set_taskfiles error (%d)\n", - __FUNCTION__, ret); + if (ret < 0) break; - } } return ret; @@ -377,6 +369,12 @@ int ata_acpi_exec_tfs(struct ata_port *ap) * ATM this function never returns a failure. It is an optional * method and if it fails for whatever reason, we should still * just keep going. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ int ata_acpi_push_id(struct ata_device *dev) { @@ -416,12 +414,9 @@ int ata_acpi_push_id(struct ata_device *dev) swap_buf_le16(dev->id, ATA_ID_WORDS); err = ACPI_FAILURE(status) ? -EIO : 0; - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s _SDD error: status = 0x%x\n", - __FUNCTION__, status); - } + if (err < 0) + ata_dev_printk(dev, KERN_WARNING, + "ACPI _SDD failed (AE 0x%x)\n", status); /* always return success */ out: From 6746544c3b143ca7071d144f1882ccbe1f47b08d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 204/551] libata: reimplement ACPI invocation This patch reimplements ACPI invocation such that, instead of exporting ACPI details to the rest of libata, ACPI event handlers - ata_acpi_on_resume() and ata_acpi_on_devcfg() - are used. These two functions are responsible for determining whether specific ACPI method is used and when. On resume, _GTF is scheduled by setting ATA_DFLAG_ACPI_PENDING device flag. This is done this way to avoid performing the action on wrong device device (device swapping while suspended). On every ata_dev_configure(), ata_acpi_on_devcfg() is called, which performs _SDD and _GTF. _GTF is performed only after resuming and, if SATA, hardreset as the ACPI spec specifies. As _GTF may contain arbitrary commands, IDENTIFY page is re-read after _GTF taskfiles are executed. If one of ACPI methods fails, ata_acpi_on_devcfg() retries on the first failure. If it fails again on the second try, ACPI is disabled on the device. Note that successful configuration clears ACPI failed status. With all feature checks moved to the above two functions, do_drive_set_taskfiles() is trivial and thus collapsed into ata_acpi_exec_tfs(), which is now static and converted to return the number of executed taskfiles to be used by ata_acpi_on_resume(). As failures are handled properly, ata_acpi_push_id() now returns -errno on errors instead of unconditional zero. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 198 +++++++++++++++++++++++--------------- drivers/ata/libata-core.c | 16 ++- drivers/ata/libata-eh.c | 3 + drivers/ata/libata.h | 14 +-- include/linux/libata.h | 2 + 5 files changed, 137 insertions(+), 96 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index ae2077e1e78f..e09df442a52f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -272,92 +272,48 @@ static int taskfile_load_raw(struct ata_device *dev, return 0; } -/** - * ata_dev_set_taskfiles - write the drive taskfile settings from _GTF - * @dev: target ATA device - * @gtf: pointer to array of _GTF taskfiles to execute - * @gtf_count: number of taskfiles - * - * This applies to both PATA and SATA drives. - * - * Execute taskfiles in @gtf. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -static int ata_dev_set_taskfiles(struct ata_device *dev, - struct ata_acpi_gtf *gtf, int gtf_count) -{ - struct ata_port *ap = dev->ap; - int ix; - - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", - __FUNCTION__, ap->port_no); - - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) - return 0; - - if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) - return -ENODEV; - - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - for (ix = 0; ix < gtf_count; ix++) - taskfile_load_raw(dev, gtf++); - - return 0; -} - /** * ata_acpi_exec_tfs - get then write drive taskfile settings - * @ap: the ata_port for the drive + * @dev: target ATA device * - * This applies to both PATA and SATA drives. + * Evaluate _GTF and excute returned taskfiles. * * LOCKING: * EH context. * * RETURNS: - * 0 on success, -errno on failure. + * Number of executed taskfiles on success, 0 if _GTF doesn't exist or + * doesn't contain valid data. -errno on other errors. */ -int ata_acpi_exec_tfs(struct ata_port *ap) +static int ata_acpi_exec_tfs(struct ata_device *dev) { - int ix, ret = 0; + struct ata_acpi_gtf *gtf = NULL; + void *ptr_to_free = NULL; + int gtf_count, i, rc; - /* - * TBD - implement PATA support. For now, - * we should not run GTF on PATA devices since some - * PATA require execution of GTM/STM before GTF. - */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) - return 0; + /* get taskfiles */ + rc = ata_dev_get_GTF(dev, >f, &ptr_to_free); + if (rc < 0) + return rc; + gtf_count = rc; - for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { - struct ata_device *dev = &ap->device[ix]; - struct ata_acpi_gtf *gtf = NULL; - int gtf_count; - void *ptr_to_free = NULL; + /* execute them */ + for (i = 0, rc = 0; i < gtf_count; i++) { + int tmp; - if (!ata_dev_enabled(dev)) - continue; - - ret = ata_dev_get_GTF(dev, >f, &ptr_to_free); - if (ret == 0) - continue; - if (ret < 0) - break; - gtf_count = ret; - - ret = ata_dev_set_taskfiles(dev, gtf, gtf_count); - kfree(ptr_to_free); - if (ret < 0) - break; + /* ACPI errors are eventually ignored. Run till the + * end even after errors. + */ + tmp = taskfile_load_raw(dev, gtf++); + if (!rc) + rc = tmp; } - return ret; + kfree(ptr_to_free); + + if (rc == 0) + return gtf_count; + return rc; } /** @@ -376,7 +332,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) * RETURNS: * 0 on success, -errno on failure. */ -int ata_acpi_push_id(struct ata_device *dev) +static int ata_acpi_push_id(struct ata_device *dev) { struct ata_port *ap = dev->ap; int err; @@ -396,7 +352,7 @@ int ata_acpi_push_id(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: Not a SATA device\n", __FUNCTION__); - goto out; + return 0; } /* Give the drive Identify data to the drive via the _SDD method */ @@ -418,9 +374,99 @@ int ata_acpi_push_id(struct ata_device *dev) ata_dev_printk(dev, KERN_WARNING, "ACPI _SDD failed (AE 0x%x)\n", status); - /* always return success */ -out: - return 0; + return err; } +/** + * ata_acpi_on_resume - ATA ACPI hook called on resume + * @ap: target ATA port + * + * This function is called when @ap is resumed - right after port + * itself is resumed but before any EH action is taken. + * + * LOCKING: + * EH context. + */ +void ata_acpi_on_resume(struct ata_port *ap) +{ + int i; + /* schedule _GTF */ + for (i = 0; i < ATA_MAX_DEVICES; i++) + ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING; +} + +/** + * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration + * @dev: target ATA device + * + * This function is called when @dev is about to be configured. + * IDENTIFY data might have been modified after this hook is run. + * + * LOCKING: + * EH context. + * + * RETURNS: + * Positive number if IDENTIFY data needs to be refreshed, 0 if not, + * -errno on failure. + */ +int ata_acpi_on_devcfg(struct ata_device *dev) +{ + struct ata_port *ap = dev->ap; + struct ata_eh_context *ehc = &ap->eh_context; + int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; + int rc; + + /* XXX: _STM isn't implemented yet, skip if IDE for now */ + if (!acpi_sata) + return 0; + + if (!dev->acpi_handle) + return 0; + + /* do we need to do _GTF? */ + if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) && + !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET))) + return 0; + + /* do _SDD if SATA */ + if (acpi_sata) { + rc = ata_acpi_push_id(dev); + if (rc) + goto acpi_err; + } + + /* do _GTF */ + rc = ata_acpi_exec_tfs(dev); + if (rc < 0) + goto acpi_err; + + dev->flags &= ~ATA_DFLAG_ACPI_PENDING; + + /* refresh IDENTIFY page if any _GTF command has been executed */ + if (rc > 0) { + rc = ata_dev_reread_id(dev, 0); + if (rc < 0) { + ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " + "after ACPI commands\n"); + return rc; + } + } + + return 0; + + acpi_err: + /* let EH retry on the first failure, disable ACPI on the second */ + if (dev->flags & ATA_DFLAG_ACPI_FAILED) { + ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " + "second time, disabling (errno=%d)\n", rc); + + dev->acpi_handle = NULL; + + /* if port is working, request IDENTIFY reload and continue */ + if (!(ap->pflags & ATA_PFLAG_FROZEN)) + rc = 1; + } + dev->flags |= ATA_DFLAG_ACPI_FAILED; + return rc; +} diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5a46cdebc588..90ed2b9a34de 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1845,7 +1845,8 @@ static void ata_dev_config_ncq(struct ata_device *dev, int ata_dev_configure(struct ata_device *dev) { struct ata_port *ap = dev->ap; - int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; + struct ata_eh_context *ehc = &ap->eh_context; + int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; const u16 *id = dev->id; unsigned int xfer_mask; char revbuf[7]; /* XYZ-99\0 */ @@ -1862,15 +1863,10 @@ int ata_dev_configure(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); - /* set _SDD */ - rc = ata_acpi_push_id(dev); - if (rc) { - ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", - rc); - } - - /* retrieve and execute the ATA task file of _GTF */ - ata_acpi_exec_tfs(ap); + /* let ACPI work its magic */ + rc = ata_acpi_on_devcfg(dev); + if (rc) + return rc; /* print device capabilities */ if (ata_msg_probe(ap)) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f7582c9c320e..fed217db82d2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2207,6 +2207,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); + /* tell ACPI that we're resuming */ + ata_acpi_on_resume(ap); + /* report result */ spin_lock_irqsave(ap->lock, flags); ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 29037cd7c651..bee7cbc4c97c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -99,18 +99,12 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern void ata_acpi_associate(struct ata_host *host); -extern int ata_acpi_exec_tfs(struct ata_port *ap); -extern int ata_acpi_push_id(struct ata_device *dev); +extern void ata_acpi_on_resume(struct ata_port *ap); +extern int ata_acpi_on_devcfg(struct ata_device *adev); #else static inline void ata_acpi_associate(struct ata_host *host) { } -static inline int ata_acpi_exec_tfs(struct ata_port *ap) -{ - return 0; -} -static inline int ata_acpi_push_id(struct ata_device *dev) -{ - return 0; -} +static inline void ata_acpi_on_resume(struct ata_port *ap) { } +static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } #endif /* libata-scsi.c */ diff --git a/include/linux/libata.h b/include/linux/libata.h index d758168ee45d..0c4f63b55ec6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -136,6 +136,8 @@ enum { ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */ + ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */ + ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */ ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ From e5fa24dfdb522b642dbe9b8b1b692f68dce89835 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 205/551] libata-acpi: remove redundant checks Remove remaining unnecessary feature and status checks. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index e09df442a52f..78db2e67d7c7 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -134,22 +134,10 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - if (!dev->acpi_handle) - goto out_free; - if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", __FUNCTION__, ap->port_no); - if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: " - "ata_dev_present: %d, PORT_DISABLED: %lu\n", - __FUNCTION__, ata_dev_enabled(dev), - ap->flags & ATA_FLAG_DISABLED); - goto out_free; - } - /* _GTF has no input parameters */ status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); @@ -340,21 +328,10 @@ static int ata_acpi_push_id(struct ata_device *dev) struct acpi_object_list input; union acpi_object in_params[1]; - if (!dev->acpi_handle) - return 0; - if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", __FUNCTION__, dev->devno, ap->port_no); - /* Don't continue if not a SATA device. */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: Not a SATA device\n", __FUNCTION__); - return 0; - } - /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ input.count = 1; From 64578a3de723d502621860f9d4d28f34d001b066 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 May 2007 03:28:16 +0900 Subject: [PATCH 206/551] libata-acpi: implement _GTM/_STM support Implement _GTM/_STM support. acpi_gtm is added to ata_port which stores _GTM parameters over suspend/resume cycle. A new hook ata_acpi_on_suspend() is responsible for storing _GTM parameters during suspend. _STM is executed in ata_acpi_on_resume(). With this change, invoking _GTF is safe on IDE hierarchy and acpi_sata check before _GTF is removed. ata_acpi_gtm() and ata_acpi_stm() implementation is taken from Alan Cox's pata_acpi implementation. ata_acpi_gtm() is fixed such that the result parameter is not shifted by sizeof(union acpi_object). Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 153 +++++++++++++++++++++++++++++++++++++- drivers/ata/libata-eh.c | 8 +- drivers/ata/libata.h | 2 + include/linux/libata.h | 13 ++++ 4 files changed, 171 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 78db2e67d7c7..c059f78ad944 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -100,6 +100,108 @@ void ata_acpi_associate(struct ata_host *host) } } +/** + * ata_acpi_gtm - execute _GTM + * @ap: target ATA port + * @gtm: out parameter for _GTM result + * + * Evaluate _GTM and store the result in @gtm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. + */ +static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm) +{ + struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; + union acpi_object *out_obj; + acpi_status status; + int rc = 0; + + status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output); + + rc = -ENOENT; + if (status == AE_NOT_FOUND) + goto out_free; + + rc = -EINVAL; + if (ACPI_FAILURE(status)) { + ata_port_printk(ap, KERN_ERR, + "ACPI get timing mode failed (AE 0x%x)\n", + status); + goto out_free; + } + + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER) { + ata_port_printk(ap, KERN_WARNING, + "_GTM returned unexpected object type 0x%x\n", + out_obj->type); + + goto out_free; + } + + if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) { + ata_port_printk(ap, KERN_ERR, + "_GTM returned invalid length %d\n", + out_obj->buffer.length); + goto out_free; + } + + memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm)); + rc = 0; + out_free: + kfree(output.pointer); + return rc; +} + +/** + * ata_acpi_stm - execute _STM + * @ap: target ATA port + * @stm: timing parameter to _STM + * + * Evaluate _STM with timing parameter @stm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. + */ +static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm) +{ + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[3]; + + in_params[0].type = ACPI_TYPE_BUFFER; + in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); + in_params[0].buffer.pointer = (u8 *)stm; + /* Buffers for id may need byteswapping ? */ + in_params[1].type = ACPI_TYPE_BUFFER; + in_params[1].buffer.length = 512; + in_params[1].buffer.pointer = (u8 *)ap->device[0].id; + in_params[2].type = ACPI_TYPE_BUFFER; + in_params[2].buffer.length = 512; + in_params[2].buffer.pointer = (u8 *)ap->device[1].id; + + input.count = 3; + input.pointer = in_params; + + status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL); + + if (status == AE_NOT_FOUND) + return -ENOENT; + if (ACPI_FAILURE(status)) { + ata_port_printk(ap, KERN_ERR, + "ACPI set timing mode failed (status=0x%x)\n", status); + return -EINVAL; + } + return 0; +} + /** * ata_dev_get_GTF - get the drive bootup default taskfile settings * @dev: target ATA device @@ -354,6 +456,46 @@ static int ata_acpi_push_id(struct ata_device *dev) return err; } +/** + * ata_acpi_on_suspend - ATA ACPI hook called on suspend + * @ap: target ATA port + * + * This function is called when @ap is about to be suspended. All + * devices are already put to sleep but the port_suspend() callback + * hasn't been executed yet. Error return from this function aborts + * suspend. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_acpi_on_suspend(struct ata_port *ap) +{ + unsigned long flags; + int rc; + + /* proceed iff per-port acpi_handle is valid */ + if (!ap->acpi_handle) + return 0; + BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); + + /* store timing parameters */ + rc = ata_acpi_gtm(ap, &ap->acpi_gtm); + + spin_lock_irqsave(ap->lock, flags); + if (rc == 0) + ap->pflags |= ATA_PFLAG_GTM_VALID; + else + ap->pflags &= ~ATA_PFLAG_GTM_VALID; + spin_unlock_irqrestore(ap->lock, flags); + + if (rc == -ENOENT) + rc = 0; + return rc; +} + /** * ata_acpi_on_resume - ATA ACPI hook called on resume * @ap: target ATA port @@ -368,6 +510,13 @@ void ata_acpi_on_resume(struct ata_port *ap) { int i; + if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { + BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); + + /* restore timing parameters */ + ata_acpi_stm(ap, &ap->acpi_gtm); + } + /* schedule _GTF */ for (i = 0; i < ATA_MAX_DEVICES; i++) ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING; @@ -394,10 +543,6 @@ int ata_acpi_on_devcfg(struct ata_device *dev) int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; int rc; - /* XXX: _STM isn't implemented yet, skip if IDE for now */ - if (!acpi_sata) - return 0; - if (!dev->acpi_handle) return 0; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index fed217db82d2..9ee0a8c08d96 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2154,19 +2154,25 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); + /* tell ACPI we're suspending */ + rc = ata_acpi_on_suspend(ap); + if (rc) + goto out; + /* suspend */ ata_eh_freeze_port(ap); if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); + out: /* report result */ spin_lock_irqsave(ap->lock, flags); ap->pflags &= ~ATA_PFLAG_PM_PENDING; if (rc == 0) ap->pflags |= ATA_PFLAG_SUSPENDED; - else + else if (ap->pflags & ATA_PFLAG_FROZEN) ata_port_schedule_eh(ap); if (ap->pm_result) { diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index bee7cbc4c97c..ba17fc5f2e99 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -99,10 +99,12 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern void ata_acpi_associate(struct ata_host *host); +extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *adev); #else static inline void ata_acpi_associate(struct ata_host *host) { } +static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } #endif diff --git a/include/linux/libata.h b/include/linux/libata.h index 0c4f63b55ec6..8d3e391ab8d3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -198,6 +198,7 @@ enum { ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ + ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */ /* struct ata_queued_cmd flags */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ @@ -493,6 +494,17 @@ struct ata_eh_context { unsigned int did_probe_mask; }; +struct ata_acpi_drive +{ + u32 pio; + u32 dma; +} __packed; + +struct ata_acpi_gtm { + struct ata_acpi_drive drive[2]; + u32 flags; +} __packed; + struct ata_port { struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ const struct ata_port_operations *ops; @@ -555,6 +567,7 @@ struct ata_port { #ifdef CONFIG_ATA_ACPI acpi_handle acpi_handle; + struct ata_acpi_gtm acpi_gtm; #endif u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ }; From 1ca972c2028edd6cd6a6ca40bd1f58b91fb4ea58 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 24 May 2007 23:05:25 -0400 Subject: [PATCH 207/551] [libata] pata_atiixp: add SB700 PCI ID From AMD. Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 844914681a2a..eceea6c64504 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -285,6 +285,7 @@ static const struct pci_device_id atiixp[] = { { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), }, { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), }, { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), }, + { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), }, { }, }; From a16abc0b5ff3ef655e40cb5e6671d57f5dde513d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 21 May 2007 18:33:47 +0200 Subject: [PATCH 208/551] libata: replace ap->cbl tests with ATA_FLAG_SATA tests ap->cbl == ATA_CBL_SATA indicates SATA cable while ap->flags & ATA_FLAG_SATA indicates SATA host port. Till now they always gave the same result but SATA/PATA bridge handling will change that. Switch to ATA_FLAG_SATA test if we're testing for host port type. Signed-off-by: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 90ed2b9a34de..74c4cd9ad82b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3355,7 +3355,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline) return 0; /* if SATA, resume phy */ - if (ap->cbl == ATA_CBL_SATA) { + if (ap->flags & ATA_FLAG_SATA) { rc = sata_phy_resume(ap, timing, deadline); /* whine about phy resume failure but proceed */ if (rc && rc != -EOPNOTSUPP) @@ -5656,7 +5656,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance) */ int sata_scr_valid(struct ata_port *ap) { - return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read; + return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read; } /** @@ -6323,7 +6323,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) if (!ata_port_is_dummy(ap)) ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " "ctl 0x%p bmdma 0x%p irq %d\n", - ap->cbl == ATA_CBL_SATA ? 'S' : 'P', + (ap->flags & ATA_FLAG_SATA) ? 'S' : 'P', ata_mode_string(xfer_mask), ap->ioaddr.cmd_addr, ap->ioaddr.ctl_addr, From be5d82183f1ebb022f923b008acf3b760d3a571d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 22 May 2007 09:45:39 +0200 Subject: [PATCH 209/551] use_clustering (sht) bit set to 0 in AHCI ? ahci: enable sg segment clustering The specification states that ahci supports segments up to 4MiB in size, so enable clustering. Signed-off-by: Jens Axboe Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ca5229d24d8e..f55c9e746b73 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -54,7 +54,7 @@ enum { AHCI_MAX_PORTS = 32, AHCI_MAX_SG = 168, /* hardware max is 64K */ AHCI_DMA_BOUNDARY = 0xffffffff, - AHCI_USE_CLUSTERING = 0, + AHCI_USE_CLUSTERING = 1, AHCI_MAX_CMDS = 32, AHCI_CMD_SZ = 32, AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, From 5bcd7a00a464fd81b4b68847b9b811a635a15b61 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 26 May 2007 16:35:42 -0400 Subject: [PATCH 210/551] [libata] sata_sil: register table cleanup Make the register offset table more maintainable. From the 'sii-lbt' branch, which enables the LBT chip feature. Signed-off-by: Jeff Garzik --- drivers/ata/sata_sil.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index a3b339bcf3cf..c3f0a86cb735 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -262,8 +262,9 @@ static const struct { unsigned long sfis_cfg; /* SATA FIS reception config register */ } sil_port[] = { /* port 0 ... */ - { 0x80, 0x8A, 0x00, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c }, - { 0xC0, 0xCA, 0x08, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, + /* tf ctl bmdma bmdma2 fifo scr sien mode sfis */ + { 0x80, 0x8A, 0x0, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c }, + { 0xC0, 0xCA, 0x8, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c }, { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc }, /* ... port 3 */ From 1d2808fd3d2d5d2c0483796a0f443d1cb3f11367 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 06:59:48 -0400 Subject: [PATCH 211/551] [libata] PATA drivers: remove ATA_FLAG_SRST This flag only has meaning in old-EH drivers, and these drivers have already been converted to the new EH. Remove. Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 2 +- drivers/ata/pata_ali.c | 14 +++++++------- drivers/ata/pata_amd.c | 20 ++++++++++---------- drivers/ata/pata_artop.c | 6 +++--- drivers/ata/pata_atiixp.c | 2 +- drivers/ata/pata_cmd640.c | 2 +- drivers/ata/pata_cmd64x.c | 12 ++++++------ drivers/ata/pata_cs5530.c | 4 ++-- drivers/ata/pata_cs5535.c | 2 +- drivers/ata/pata_cypress.c | 2 +- drivers/ata/pata_efar.c | 2 +- drivers/ata/pata_hpt366.c | 2 +- drivers/ata/pata_hpt37x.c | 12 ++++++------ drivers/ata/pata_hpt3x2n.c | 2 +- drivers/ata/pata_hpt3x3.c | 2 +- drivers/ata/pata_icside.c | 2 +- drivers/ata/pata_it8213.c | 2 +- drivers/ata/pata_it821x.c | 4 ++-- drivers/ata/pata_jmicron.c | 2 +- drivers/ata/pata_marvell.c | 4 ++-- drivers/ata/pata_netcell.c | 2 +- drivers/ata/pata_ns87410.c | 2 +- drivers/ata/pata_oldpiix.c | 2 +- drivers/ata/pata_opti.c | 2 +- drivers/ata/pata_optidma.c | 4 ++-- drivers/ata/pata_pdc202xx_old.c | 6 +++--- drivers/ata/pata_radisys.c | 2 +- drivers/ata/pata_rz1000.c | 2 +- drivers/ata/pata_sc1200.c | 2 +- drivers/ata/pata_serverworks.c | 8 ++++---- drivers/ata/pata_sil680.c | 4 ++-- drivers/ata/pata_sis.c | 14 +++++++------- drivers/ata/pata_sl82c105.c | 4 ++-- drivers/ata/pata_triflex.c | 2 +- 34 files changed, 78 insertions(+), 78 deletions(-) diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 4c6e95c95e4a..0878fb5b3254 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -143,7 +143,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id u16 command; static const struct ata_port_info info = { .sht = &generic_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 75e95bdbe02f..5c53d5aa13a8 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -520,14 +520,14 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info_early = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &ali_early_port_ops }; /* Revision 0x20 added DMA */ static const struct ata_port_info info_20 = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &ali_20_port_ops @@ -535,7 +535,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Revision 0x20 with support logic added UDMA */ static const struct ata_port_info info_20_udma = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, /* UDMA33 */ @@ -544,7 +544,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Revision 0xC2 adds UDMA66 */ static const struct ata_port_info info_c2 = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, @@ -553,7 +553,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Revision 0xC3 is UDMA66 for now */ static const struct ata_port_info info_c3 = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, @@ -562,7 +562,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Revision 0xC4 is UDMA100 */ static const struct ata_port_info info_c4 = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, @@ -571,7 +571,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Revision 0xC5 is UDMA133 with LBA48 DMA */ static const struct ata_port_info info_c5 = { .sht = &ali_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index a16f629b7b38..533bcc9d1542 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -541,7 +541,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static const struct ata_port_info info[10] = { { /* 0: AMD 7401 */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, /* No SWDMA */ .udma_mask = 0x07, /* UDMA 33 */ @@ -549,7 +549,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 1: Early AMD7409 - no swdma */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, /* UDMA 66 */ @@ -557,7 +557,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 2: AMD 7409, no swdma errata */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, /* UDMA 66 */ @@ -565,7 +565,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 3: AMD 7411 */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, /* UDMA 100 */ @@ -573,7 +573,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 4: AMD 7441 */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, /* UDMA 100 */ @@ -581,7 +581,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 5: AMD 8111*/ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, /* UDMA 133, no swdma */ @@ -589,7 +589,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 6: AMD 8111 UDMA 100 (Serenade) */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, /* UDMA 100, no swdma */ @@ -597,7 +597,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 7: Nvidia Nforce */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, /* UDMA 100 */ @@ -605,7 +605,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 8: Nvidia Nforce2 and later */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, /* UDMA 133, no swdma */ @@ -613,7 +613,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* 9: AMD CS5536 (Geode companion) */ .sht = &amd_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, /* UDMA 100 */ diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 03b6ddd2abd2..ce589d96ca42 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -416,7 +416,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) static int printed_version; static const struct ata_port_info info_6210 = { .sht = &artop_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA2, @@ -424,7 +424,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) }; static const struct ata_port_info info_626x = { .sht = &artop_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA4, @@ -432,7 +432,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) }; static const struct ata_port_info info_626x_fast = { .sht = &artop_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = ATA_UDMA5, diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index eceea6c64504..80509be49e7a 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -270,7 +270,7 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &atiixp_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x06, /* No MWDMA0 support */ .udma_mask = 0x3F, diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 31cbf8daa299..0feb5ae8c486 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -251,7 +251,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &cmd640_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &cmd640_port_ops }; diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 320a5b10aa98..dc443e7dc37c 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -380,21 +380,21 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static const struct ata_port_info cmd_info[6] = { { /* CMD 643 - no UDMA */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &cmd64x_port_ops }, { /* CMD 646 with broken UDMA */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &cmd64x_port_ops }, { /* CMD 646 with working UDMA */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA1, @@ -402,14 +402,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* CMD 646 rev 1 */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &cmd646r1_port_ops }, { /* CMD 648 */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA2, @@ -417,7 +417,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }, { /* CMD 649 */ .sht = &cmd64x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA3, diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 848f0309bf03..797a6f67e8f5 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -337,7 +337,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &cs5530_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, @@ -346,7 +346,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* The docking connector doesn't do UDMA, and it seems not MWDMA */ static const struct ata_port_info info_palmax_secondary = { .sht = &cs5530_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &cs5530_port_ops }; diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index aa3256fb9f7a..7eeed578af0b 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -225,7 +225,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &cs5535_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index d41a7691dd8e..6cbc8778bf4f 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -167,7 +167,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i { static const struct ata_port_info info = { .sht = &cy82c693_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &cy82c693_port_ops diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 079248a9b460..c8ba59c56114 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -303,7 +303,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int printed_version; static const struct ata_port_info info = { .sht = &efar_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma1-2 */ .udma_mask = 0x0f, /* UDMA 66 */ diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 0c9cb6090711..7a6ff3dfc775 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -393,7 +393,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info_hpt366 = { .sht = &hpt36x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index a8c0cbeca399..d2278fdb1025 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -889,7 +889,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT370 - UDMA100 */ static const struct ata_port_info info_hpt370 = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, @@ -898,7 +898,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT370A - UDMA100 */ static const struct ata_port_info info_hpt370a = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, @@ -907,7 +907,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT370 - UDMA100 */ static const struct ata_port_info info_hpt370_33 = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x0f, @@ -916,7 +916,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT370A - UDMA100 */ static const struct ata_port_info info_hpt370a_33 = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x0f, @@ -925,7 +925,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT371, 372 and friends - UDMA133 */ static const struct ata_port_info info_hpt372 = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, @@ -934,7 +934,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT374 - UDMA100 */ static const struct ata_port_info info_hpt374 = { .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index e947433cb37d..809d3385df7d 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -490,7 +490,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* HPT372N and friends - UDMA133 */ static const struct ata_port_info info = { .sht = &hpt3x2n_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 8ce5e23a5f75..d928c9105034 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -173,7 +173,7 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &hpt3x3_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index c791a46df461..321d98b0bed2 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -530,7 +530,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info) ap->pio_mask = 0x1f; ap->mwdma_mask = info->mwdma_mask; - ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; + ap->flags |= ATA_FLAG_SLAVE_POSS; ap->ops = &pata_icside_port_ops; pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]); diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 95b0bb61788b..41fb08bd1776 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -313,7 +313,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en static int printed_version; static const struct ata_port_info info = { .sht = &it8213_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x1f, /* UDMA 100 */ diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 12c6e08cc4d1..4f26ef1665d4 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -714,14 +714,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static const struct ata_port_info info_smart = { .sht = &it821x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &it821x_smart_port_ops }; static const struct ata_port_info info_passthru = { .sht = &it821x_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 2af7ff8256ca..1a6c4dbba5cf 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -193,7 +193,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i { static const struct ata_port_info info = { .sht = &jmicron_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index edbfe0dbbf78..73f1e4b66038 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -163,7 +163,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i { static const struct ata_port_info info = { .sht = &marvell_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, @@ -174,7 +174,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i static const struct ata_port_info info_sata = { .sht = &marvell_sht, /* Slave possible as its magically mapped not real */ - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 81f563458666..b7c8b13ffda8 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -94,7 +94,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e static int printed_version; static const struct ata_port_info info = { .sht = &netcell_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, /* Actually we don't really care about these as the firmware deals with it */ .pio_mask = 0x1f, /* pio0-4 */ diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index ea70ec744879..2f5d714ebfc4 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -193,7 +193,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &ns87410_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x0F, .port_ops = &ns87410_port_ops }; diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 29c23ddd6550..091a70a0ef1c 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -291,7 +291,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e static int printed_version; static const struct ata_port_info info = { .sht = &oldpiix_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma1-2 */ .port_ops = &oldpiix_pata_ops, diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index 1c44653e1e06..458bf67f766f 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c @@ -218,7 +218,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &opti_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &opti_port_ops }; diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 3093b02286ce..f89bdfde16d0 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -484,14 +484,14 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info_82c700 = { .sht = &optidma_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &optidma_port_ops }; static const struct ata_port_info info_82c700_udma = { .sht = &optidma_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index d277246b7337..92447bed5e77 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -320,7 +320,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id static const struct ata_port_info info[3] = { { .sht = &pdc202xx_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA2, @@ -328,7 +328,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id }, { .sht = &pdc202xx_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA4, @@ -336,7 +336,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id }, { .sht = &pdc202xx_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA5, diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index ba96b54f5b87..7d1aabed422d 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -257,7 +257,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e static int printed_version; static const struct ata_port_info info = { .sht = &radisys_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma1-2 */ .udma_mask = 0x14, /* UDMA33/66 only */ diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index a3488b41ad26..7632fcb070ca 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -133,7 +133,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en static int printed_version; static const struct ata_port_info info = { .sht = &rz1000_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &rz1000_port_ops }; diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 1233063ab9a8..7ff39cf9dc0b 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -245,7 +245,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &sc1200_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 1e8f421963c7..2c0bc3bb1692 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -478,28 +478,28 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id static const struct ata_port_info info[4] = { { /* OSB4 */ .sht = &serverworks_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x07, .port_ops = &serverworks_osb4_port_ops }, { /* OSB4 no UDMA */ .sht = &serverworks_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x00, .port_ops = &serverworks_osb4_port_ops }, { /* CSB5 */ .sht = &serverworks_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x1f, .port_ops = &serverworks_csb_port_ops }, { /* CSB5 - later revisions*/ .sht = &serverworks_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 440e2cb6ee75..b7dfb959fa9e 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -343,7 +343,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &sil680_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, @@ -351,7 +351,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; static const struct ata_port_info info_slow = { .sht = &sil680_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x3f, diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index cfe4ec6eb3d5..2b4508206a6c 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -732,7 +732,7 @@ static const struct ata_port_operations sis_old_ops = { static const struct ata_port_info sis_info = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, .udma_mask = 0, @@ -740,7 +740,7 @@ static const struct ata_port_info sis_info = { }; static const struct ata_port_info sis_info33 = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, .udma_mask = ATA_UDMA2, /* UDMA 33 */ @@ -748,28 +748,28 @@ static const struct ata_port_info sis_info33 = { }; static const struct ata_port_info sis_info66 = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA4, /* UDMA 66 */ .port_ops = &sis_66_ops, }; static const struct ata_port_info sis_info100 = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA5, .port_ops = &sis_100_ops, }; static const struct ata_port_info sis_info100_early = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .udma_mask = ATA_UDMA5, .pio_mask = 0x1f, /* pio0-4 */ .port_ops = &sis_66_ops, }; static const struct ata_port_info sis_info133 = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &sis_133_ops, @@ -783,7 +783,7 @@ const struct ata_port_info sis_info133_for_sata = { }; static const struct ata_port_info sis_info133_early = { .sht = &sis_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &sis_133_early_ops, diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index e5aaec43694d..bde734189623 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -303,14 +303,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id { static const struct ata_port_info info_dma = { .sht = &sl82c105_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &sl82c105_port_ops }; static const struct ata_port_info info_early = { .sht = &sl82c105_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .port_ops = &sl82c105_port_ops }; diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index b1d3076dfe51..af21f443db6e 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -235,7 +235,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &triflex_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &triflex_port_ops From 59f998802bd5df56cd824f313cf5b0c3e356ec59 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 07:07:20 -0400 Subject: [PATCH 212/551] [libata] drivers: remove 'void __iomem *' casts from pre-iomap days Signed-off-by: Jeff Garzik --- drivers/ata/pata_ixp4xx_cf.c | 2 +- drivers/ata/sata_inic162x.c | 4 ++-- drivers/ata/sata_promise.c | 8 ++++---- drivers/ata/sata_svw.c | 11 ++++++----- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 8d2bc1e9e871..887bbaae6efc 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -56,7 +56,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int words = buflen >> 1; u16 *buf16 = (u16 *) buf; struct ata_port *ap = adev->ap; - void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; + void __iomem *mmio = ap->ioaddr.data_addr; struct ixp4xx_pata_data *data = ap->host->dev->platform_data; /* set the expansion bus in 16bit mode and restore diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index dc3bbce04676..8efc5316b32e 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -192,7 +192,7 @@ static void inic_reset_port(void __iomem *port_base) static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) { - void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; + void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; u32 val; @@ -210,7 +210,7 @@ static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { - void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; + void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 6dc0b011a6b7..7fcc4fe4d79b 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -382,7 +382,7 @@ static int pdc_sata_port_start(struct ata_port *ap) /* fix up PHYMODE4 align timing */ if (ap->flags & PDC_FLAG_GEN_II) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; + void __iomem *mmio = ap->ioaddr.scr_addr; unsigned int tmp; tmp = readl(mmio + 0x014); @@ -418,7 +418,7 @@ static void pdc_reset_port(struct ata_port *ap) static int pdc_pata_cable_detect(struct ata_port *ap) { u8 tmp; - void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; + void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; tmp = readb(mmio); if (tmp & 0x01) @@ -573,7 +573,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) static void pdc_freeze(struct ata_port *ap) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *mmio = ap->ioaddr.cmd_addr; u32 tmp; tmp = readl(mmio + PDC_CTLSTAT); @@ -585,7 +585,7 @@ static void pdc_freeze(struct ata_port *ap) static void pdc_thaw(struct ata_port *ap) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *mmio = ap->ioaddr.cmd_addr; u32 tmp; /* clear IRQ */ diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index bcb2cd8b063d..4fd4f107187c 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -107,7 +107,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) return 0xffffffffU; - return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -116,7 +116,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, { if (sc_reg > SCR_CONTROL) return; - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -197,7 +197,8 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); u8 dmactl; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + void __iomem *mmio = ap->ioaddr.bmdma_addr; + /* load PRD table addr. */ mb(); /* make sure PRD table writes are visible to controller */ writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); @@ -225,7 +226,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + void __iomem *mmio = ap->ioaddr.bmdma_addr; u8 dmactl; /* start host DMA transaction */ @@ -253,7 +254,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) static u8 k2_stat_check_status(struct ata_port *ap) { - return readl((void __iomem *) ap->ioaddr.status_addr); + return readl(ap->ioaddr.status_addr); } #ifdef CONFIG_PPC_OF From 49de0ac823ed7826695c6a2ac62dc1f730a8b17d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 26 May 2007 18:20:51 -0400 Subject: [PATCH 213/551] [libata] pdc_adma: Reorder initializers with a couple structs Make it easier to verify which struct initializers are present, by presenting them in the order in which they are defined in the API header. Signed-off-by: Jeff Garzik --- drivers/ata/pdc_adma.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index f12c2b6ac08e..74c50c90e4d0 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -145,32 +145,32 @@ static struct scsi_host_template adma_ata_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, - .can_queue = ATA_DEF_QUEUE, - .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ENABLE_CLUSTERING, - .proc_name = DRV_NAME, - .dma_boundary = ADMA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, + .proc_name = DRV_NAME, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .dma_boundary = ADMA_DMA_BOUNDARY, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .use_clustering = ENABLE_CLUSTERING, + .emulated = ATA_SHT_EMULATED, }; static const struct ata_port_operations adma_ata_ops = { .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, - .check_status = ata_check_status, - .check_atapi_dma = adma_check_atapi_dma, .exec_command = ata_exec_command, + .check_status = ata_check_status, .dev_select = ata_std_dev_select, .phy_reset = adma_phy_reset, + .check_atapi_dma = adma_check_atapi_dma, + .data_xfer = ata_data_xfer, .qc_prep = adma_qc_prep, .qc_issue = adma_qc_issue, .eng_timeout = adma_eng_timeout, - .data_xfer = ata_data_xfer, .irq_clear = adma_irq_clear, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, From 5d4c51f6beab08ada99064bab6ee74e995a4f24d Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Sat, 26 May 2007 19:26:55 -0400 Subject: [PATCH 214/551] [libata] pata_ixp4xx: convert to new EH Signed-off-by: Jeff Garzik --- drivers/ata/pata_ixp4xx_cf.c | 63 +++++++++++++++--------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 887bbaae6efc..76332109a4f7 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -1,13 +1,14 @@ /* * ixp4xx PATA/Compact Flash driver - * Copyright (c) 2006 Tower Technologies + * Copyright (C) 2006-07 Tower Technologies * Author: Alessandro Zummo * * An ATA driver to handle a Compact Flash connected * to the ixp4xx expansion bus in TrueIDE mode. The CF * must have it chip selects connected to two CS lines - * on the ixp4xx. The interrupt line is optional, if not - * specified the driver will run in polling mode. + * on the ixp4xx. In the irq is not available, you might + * want to modify both this driver and libata to run in + * polling mode. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -23,7 +24,7 @@ #include #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.3" +#define DRV_VERSION "0.2" static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) { @@ -42,13 +43,6 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) return 0; } -static void ixp4xx_phy_reset(struct ata_port *ap) -{ - ap->cbl = ATA_CBL_PATA40; - ata_port_probe(ap); - ata_bus_reset(ap); -} - static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) { @@ -92,10 +86,6 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, *data->cs0_cfg |= 0x01; } -static void ixp4xx_irq_clear(struct ata_port *ap) -{ -} - static struct scsi_host_template ixp4xx_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -115,29 +105,32 @@ static struct scsi_host_template ixp4xx_sht = { }; static struct ata_port_operations ixp4xx_port_ops = { - .set_mode = ixp4xx_set_mode, - .mode_filter = ata_pci_default_filter, + .set_mode = ixp4xx_set_mode, + .mode_filter = ata_pci_default_filter, - .port_disable = ata_port_disable, - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .check_status = ata_check_status, - .exec_command = ata_exec_command, - .dev_select = ata_std_dev_select, + .port_disable = ata_port_disable, + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .exec_command = ata_exec_command, + .check_status = ata_check_status, + .dev_select = ata_std_dev_select, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .eng_timeout = ata_eng_timeout, - .data_xfer = ixp4xx_mmio_data_xfer, - .cable_detect = ata_cable_40wire, + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_clear = ixp4xx_irq_clear, - .irq_on = ata_irq_on, - .irq_ack = ata_irq_ack, + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + .data_xfer = ixp4xx_mmio_data_xfer, + .cable_detect = ata_cable_40wire, - .port_start = ata_port_start, + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + .irq_ack = ata_dummy_irq_ack, - .phy_reset = ixp4xx_phy_reset, + .port_start = ata_port_start, }; static void ixp4xx_setup_port(struct ata_ioports *ioaddr, @@ -211,10 +204,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) ap->pio_mask = 0x1f; /* PIO4 */ ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; - /* run in polling mode if no irq has been assigned */ - if (!irq) - ap->flags |= ATA_FLAG_PIO_POLLING; - ixp4xx_setup_port(&ap->ioaddr, data); dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); From b2d46b61bdb2bd45b93f88892461fa568df721d4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 27 May 2007 22:58:54 -0400 Subject: [PATCH 215/551] [libata] sata_sx4: named constant cleanup * convert tabs to spaces * convert some hex numbers to (1 << n) preferred format * document i2c and timer control register bits Signed-off-by: Jeff Garzik --- drivers/ata/sata_sx4.c | 115 ++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 2d14f3d56d92..ff0a78dc8b86 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -87,48 +87,59 @@ enum { board_20621 = 0, /* FastTrak S150 SX4 */ - PDC_RESET = (1 << 11), /* HDMA reset */ + PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */ + PDC_RESET = (1 << 11), /* HDMA/ATA reset */ PDC_MAX_HDMA = 32, PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1), - PDC_DIMM0_SPD_DEV_ADDRESS = 0x50, - PDC_DIMM1_SPD_DEV_ADDRESS = 0x51, - PDC_MAX_DIMM_MODULE = 0x02, - PDC_I2C_CONTROL_OFFSET = 0x48, - PDC_I2C_ADDR_DATA_OFFSET = 0x4C, - PDC_DIMM0_CONTROL_OFFSET = 0x80, - PDC_DIMM1_CONTROL_OFFSET = 0x84, - PDC_SDRAM_CONTROL_OFFSET = 0x88, - PDC_I2C_WRITE = 0x00000000, - PDC_I2C_READ = 0x00000040, - PDC_I2C_START = 0x00000080, - PDC_I2C_MASK_INT = 0x00000020, - PDC_I2C_COMPLETE = 0x00010000, - PDC_I2C_NO_ACK = 0x00100000, - PDC_DIMM_SPD_SUBADDRESS_START = 0x00, - PDC_DIMM_SPD_SUBADDRESS_END = 0x7F, - PDC_DIMM_SPD_ROW_NUM = 3, - PDC_DIMM_SPD_COLUMN_NUM = 4, - PDC_DIMM_SPD_MODULE_ROW = 5, - PDC_DIMM_SPD_TYPE = 11, - PDC_DIMM_SPD_FRESH_RATE = 12, - PDC_DIMM_SPD_BANK_NUM = 17, - PDC_DIMM_SPD_CAS_LATENCY = 18, - PDC_DIMM_SPD_ATTRIBUTE = 21, - PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, - PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, - PDC_DIMM_SPD_RAS_CAS_DELAY = 29, - PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, - PDC_DIMM_SPD_SYSTEM_FREQ = 126, - PDC_CTL_STATUS = 0x08, - PDC_DIMM_WINDOW_CTLR = 0x0C, - PDC_TIME_CONTROL = 0x3C, - PDC_TIME_PERIOD = 0x40, - PDC_TIME_COUNTER = 0x44, - PDC_GENERAL_CTLR = 0x484, - PCI_PLL_INIT = 0x8A531824, - PCI_X_TCOUNT = 0xEE1E5CFF + PDC_DIMM0_SPD_DEV_ADDRESS = 0x50, + PDC_DIMM1_SPD_DEV_ADDRESS = 0x51, + PDC_I2C_CONTROL = 0x48, + PDC_I2C_ADDR_DATA = 0x4C, + PDC_DIMM0_CONTROL = 0x80, + PDC_DIMM1_CONTROL = 0x84, + PDC_SDRAM_CONTROL = 0x88, + PDC_I2C_WRITE = 0, /* master -> slave */ + PDC_I2C_READ = (1 << 6), /* master <- slave */ + PDC_I2C_START = (1 << 7), /* start I2C proto */ + PDC_I2C_MASK_INT = (1 << 5), /* mask I2C interrupt */ + PDC_I2C_COMPLETE = (1 << 16), /* I2C normal compl. */ + PDC_I2C_NO_ACK = (1 << 20), /* slave no-ack addr */ + PDC_DIMM_SPD_SUBADDRESS_START = 0x00, + PDC_DIMM_SPD_SUBADDRESS_END = 0x7F, + PDC_DIMM_SPD_ROW_NUM = 3, + PDC_DIMM_SPD_COLUMN_NUM = 4, + PDC_DIMM_SPD_MODULE_ROW = 5, + PDC_DIMM_SPD_TYPE = 11, + PDC_DIMM_SPD_FRESH_RATE = 12, + PDC_DIMM_SPD_BANK_NUM = 17, + PDC_DIMM_SPD_CAS_LATENCY = 18, + PDC_DIMM_SPD_ATTRIBUTE = 21, + PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, + PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, + PDC_DIMM_SPD_RAS_CAS_DELAY = 29, + PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, + PDC_DIMM_SPD_SYSTEM_FREQ = 126, + PDC_CTL_STATUS = 0x08, + PDC_DIMM_WINDOW_CTLR = 0x0C, + PDC_TIME_CONTROL = 0x3C, + PDC_TIME_PERIOD = 0x40, + PDC_TIME_COUNTER = 0x44, + PDC_GENERAL_CTLR = 0x484, + PCI_PLL_INIT = 0x8A531824, + PCI_X_TCOUNT = 0xEE1E5CFF, + + /* PDC_TIME_CONTROL bits */ + PDC_TIMER_BUZZER = (1 << 10), + PDC_TIMER_MODE_PERIODIC = 0, /* bits 9:8 == 00 */ + PDC_TIMER_MODE_ONCE = (1 << 8), /* bits 9:8 == 01 */ + PDC_TIMER_ENABLE = (1 << 7), + PDC_TIMER_MASK_INT = (1 << 5), + PDC_TIMER_SEQ_MASK = 0x1f, /* SEQ ID for timer */ + PDC_TIMER_DEFAULT = PDC_TIMER_MODE_ONCE | + PDC_TIMER_ENABLE | + PDC_TIMER_MASK_INT, }; @@ -999,17 +1010,17 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device, i2creg |= subaddr << 16; /* Set the device and subaddress */ - writel(i2creg, mmio + PDC_I2C_ADDR_DATA_OFFSET); - readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); + writel(i2creg, mmio + PDC_I2C_ADDR_DATA); + readl(mmio + PDC_I2C_ADDR_DATA); /* Write Control to perform read operation, mask int */ writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, - mmio + PDC_I2C_CONTROL_OFFSET); + mmio + PDC_I2C_CONTROL); for (count = 0; count <= 1000; count ++) { - status = readl(mmio + PDC_I2C_CONTROL_OFFSET); + status = readl(mmio + PDC_I2C_CONTROL); if (status & PDC_I2C_COMPLETE) { - status = readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); + status = readl(mmio + PDC_I2C_ADDR_DATA); break; } else if (count == 1000) return 0; @@ -1099,8 +1110,8 @@ static int pdc20621_prog_dimm0(struct ata_host *host) data |= (((size / 16) - 1) << 16); data |= (0 << 23); data |= 8; - writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); - readl(mmio + PDC_DIMM0_CONTROL_OFFSET); + writel(data, mmio + PDC_DIMM0_CONTROL); + readl(mmio + PDC_DIMM0_CONTROL); return size; } @@ -1122,27 +1133,27 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host) */ data = 0x022259F1; - writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); - readl(mmio + PDC_SDRAM_CONTROL_OFFSET); + writel(data, mmio + PDC_SDRAM_CONTROL); + readl(mmio + PDC_SDRAM_CONTROL); /* Turn on for ECC */ pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE, &spd0); if (spd0 == 0x02) { data |= (0x01 << 16); - writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); - readl(mmio + PDC_SDRAM_CONTROL_OFFSET); + writel(data, mmio + PDC_SDRAM_CONTROL); + readl(mmio + PDC_SDRAM_CONTROL); printk(KERN_ERR "Local DIMM ECC Enabled\n"); } /* DIMM Initialization Select/Enable (bit 18/19) */ data &= (~(1<<18)); data |= (1<<19); - writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); + writel(data, mmio + PDC_SDRAM_CONTROL); error = 1; for (i = 1; i <= 10; i++) { /* polling ~5 secs */ - data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); + data = readl(mmio + PDC_SDRAM_CONTROL); if (!(data & (1<<19))) { error = 0; break; @@ -1176,7 +1187,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) VPRINTK("Time Period Register (0x40): 0x%x\n", time_period); /* Enable timer */ - writel(0x00001a0, mmio + PDC_TIME_CONTROL); + writel(PDC_TIMER_DEFAULT, mmio + PDC_TIME_CONTROL); readl(mmio + PDC_TIME_CONTROL); /* Wait 3 seconds */ From 79b0bde157e71071320e7a723c5a669cb2c822cf Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 07:22:30 -0400 Subject: [PATCH 216/551] [libata] pata_sil680: minor cleanups from benh Merge unrelated cleanups (__devinit, dev_dbg, hardware constant) from changeset "pata_sil680: Add MMIO support" authored by Benjamin Herrenschmidt Signed-off-by: Jeff Garzik --- drivers/ata/pata_sil680.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index b7dfb959fa9e..9b645c5ec955 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -35,6 +35,8 @@ #define DRV_NAME "pata_sil680" #define DRV_VERSION "0.4.6" +#define SIL680_MMIO_BAR 5 + /** * sil680_selreg - return register base * @hwif: interface @@ -293,8 +295,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev) pci_read_config_byte(pdev, 0x8A, &tmpbyte); - printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", - tmpbyte & 1, tmpbyte & 0x30); + dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n", + tmpbyte & 1, tmpbyte & 0x30); switch(tmpbyte & 0x30) { case 0x00: @@ -315,8 +317,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev) } pci_read_config_byte(pdev, 0x8A, &tmpbyte); - printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", - tmpbyte & 1, tmpbyte & 0x30); + dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n", + tmpbyte & 1, tmpbyte & 0x30); pci_write_config_byte(pdev, 0xA1, 0x72); pci_write_config_word(pdev, 0xA2, 0x328A); @@ -339,7 +341,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev) return tmpbyte & 0x30; } -static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) +static int __devinit sil680_init_one(struct pci_dev *pdev, + const struct pci_device_id *id) { static const struct ata_port_info info = { .sht = &sil680_sht, From 2bcd866be55f8fe259ccac8eef2b8a7f7721b1d5 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 07:45:27 -0400 Subject: [PATCH 217/551] [libata] ahci: Factor out SATA port init into a separate function Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 50 +++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f55c9e746b73..4f2c05ef1f09 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -814,39 +814,49 @@ static int ahci_reset_controller(struct ata_host *host) return 0; } +static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap, + int port_no, void __iomem *mmio, + void __iomem *port_mmio) +{ + const char *emsg = NULL; + int rc; + u32 tmp; + + /* make sure port is not active */ + rc = ahci_deinit_port(ap, &emsg); + if (rc) + dev_printk(KERN_WARNING, &pdev->dev, + "%s (%d)\n", emsg, rc); + + /* clear SError */ + tmp = readl(port_mmio + PORT_SCR_ERR); + VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); + writel(tmp, port_mmio + PORT_SCR_ERR); + + /* clear port IRQ */ + tmp = readl(port_mmio + PORT_IRQ_STAT); + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + + writel(1 << port_no, mmio + HOST_IRQ_STAT); +} + static void ahci_init_controller(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; - int i, rc; + int i; u32 tmp; for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; void __iomem *port_mmio = ahci_port_base(ap); - const char *emsg = NULL; if (ata_port_is_dummy(ap)) continue; - /* make sure port is not active */ - rc = ahci_deinit_port(ap, &emsg); - if (rc) - dev_printk(KERN_WARNING, &pdev->dev, - "%s (%d)\n", emsg, rc); - - /* clear SError */ - tmp = readl(port_mmio + PORT_SCR_ERR); - VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); - writel(tmp, port_mmio + PORT_SCR_ERR); - - /* clear port IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); - if (tmp) - writel(tmp, port_mmio + PORT_IRQ_STAT); - - writel(1 << i, mmio + HOST_IRQ_STAT); + ahci_port_init(pdev, ap, i, mmio, port_mmio); } tmp = readl(mmio + HOST_CTL); From df69c9c5438b4e396a64d42608b2a6c48a3e7475 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 26 May 2007 20:46:51 -0400 Subject: [PATCH 218/551] [libata] ahci: minor internal cleanups Function renaming and factorization. Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 4f2c05ef1f09..779a2b0aadda 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -228,9 +228,9 @@ static void ahci_thaw(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap); static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); +static int ahci_port_resume(struct ata_port *ap); #ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); -static int ahci_port_resume(struct ata_port *ap); static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int ahci_pci_device_resume(struct pci_dev *pdev); #endif @@ -740,7 +740,7 @@ static void ahci_power_down(struct ata_port *ap) } #endif -static void ahci_init_port(struct ata_port *ap) +static void ahci_start_port(struct ata_port *ap) { /* enable FIS reception */ ahci_start_fis_rx(ap); @@ -1242,7 +1242,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ata_port_abort(ap); } -static void ahci_host_intr(struct ata_port *ap) +static void ahci_port_intr(struct ata_port *ap) { void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ata_eh_info *ehi = &ap->eh_info; @@ -1368,7 +1368,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) ap = host->ports[i]; if (ap) { - ahci_host_intr(ap); + ahci_port_intr(ap); VPRINTK("port %u\n", i); } else { VPRINTK("port %u (no irq)\n", i); @@ -1476,7 +1476,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) ahci_power_down(ap); else { ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); - ahci_init_port(ap); + ahci_start_port(ap); } return rc; @@ -1485,7 +1485,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) static int ahci_port_resume(struct ata_port *ap) { ahci_power_up(ap); - ahci_init_port(ap); + ahci_start_port(ap); return 0; } @@ -1583,13 +1583,8 @@ static int ahci_port_start(struct ata_port *ap) ap->private_data = pp; - /* power up port */ - ahci_power_up(ap); - - /* initialize port */ - ahci_init_port(ap); - - return 0; + /* engage engines, captain */ + return ahci_port_resume(ap); } static void ahci_port_stop(struct ata_port *ap) From a09060ffe516a0e55f29c89b7da2da760c9487d7 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 08:17:06 -0400 Subject: [PATCH 219/551] [libata] sata_sx4, sata_via: minor documentation updates sata_sx4: - describe overall driver theory of operation - add a few constants that will be used in the future sata_via: - remove mention of an old-EH function that is going away Signed-off-by: Jeff Garzik --- drivers/ata/sata_sx4.c | 51 ++++++++++++++++++++++++++++++++++++++++++ drivers/ata/sata_via.c | 4 +--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index ff0a78dc8b86..3d83ee273388 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -30,6 +30,54 @@ * */ +/* + Theory of operation + ------------------- + + The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy + engine, DIMM memory, and four ATA engines (one per SATA port). + Data is copied to/from DIMM memory by the HDMA engine, before + handing off to one (or more) of the ATA engines. The ATA + engines operate solely on DIMM memory. + + The SX4 behaves like a PATA chip, with no SATA controls or + knowledge whatsoever, leading to the presumption that + PATA<->SATA bridges exist on SX4 boards, external to the + PDC20621 chip itself. + + The chip is quite capable, supporting an XOR engine and linked + hardware commands (permits a string to transactions to be + submitted and waited-on as a single unit), and an optional + microprocessor. + + The limiting factor is largely software. This Linux driver was + written to multiplex the single HDMA engine to copy disk + transactions into a fixed DIMM memory space, from where an ATA + engine takes over. As a result, each WRITE looks like this: + + submit HDMA packet to hardware + hardware copies data from system memory to DIMM + hardware raises interrupt + + submit ATA packet to hardware + hardware executes ATA WRITE command, w/ data in DIMM + hardware raises interrupt + + and each READ looks like this: + + submit ATA packet to hardware + hardware executes ATA READ command, w/ data in DIMM + hardware raises interrupt + + submit HDMA packet to hardware + hardware copies data from DIMM to system memory + hardware raises interrupt + + This is a very slow, lock-step way of doing things that can + certainly be improved by motivated kernel hackers. + + */ + #include #include #include @@ -58,6 +106,8 @@ enum { PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */ + PDC_CTLSTAT = 0x60, /* IDEn control / status */ + PDC_20621_SEQCTL = 0x400, PDC_20621_SEQMASK = 0x480, PDC_20621_GENERAL_CTL = 0x484, @@ -89,6 +139,7 @@ enum { PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */ PDC_RESET = (1 << 11), /* HDMA/ATA reset */ + PDC_DMA_ENABLE = (1 << 7), /* DMA start/stop */ PDC_MAX_HDMA = 32, PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1), diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index e8b90e7b42dd..e816965ef4f1 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -303,9 +303,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) if (!(ap->pflags & ATA_PFLAG_LOADING)) goto skip_scr; - /* Resume phy. This is the old resume sequence from - * __sata_phy_reset(). - */ + /* Resume phy. This is the old SATA resume sequence */ svia_scr_write(ap, SCR_CONTROL, 0x300); svia_scr_read(ap, SCR_CONTROL); /* flush */ From ab2181cf390902f0371f30e4ebeb407b4aaa7314 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 08:30:36 -0400 Subject: [PATCH 220/551] [ATA] Add named constant for ATAPI command DEVICE RESET Signed-off-by: Jeff Garzik --- include/linux/ata.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ata.h b/include/linux/ata.h index 703febb2df31..407dc7e098bc 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -126,6 +126,7 @@ enum { ATA_REG_IRQ = ATA_REG_NSECT, /* ATA device commands */ + ATA_CMD_DEV_RESET = 0x08, /* ATAPI device reset */ ATA_CMD_CHK_POWER = 0xE5, /* check power mode */ ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */ ATA_CMD_IDLE = 0xE3, /* place in idle power mode */ From dab632e8c483532bd84e1f3401c72612e39a7c40 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 08:33:01 -0400 Subject: [PATCH 221/551] [libata] ahci: minor internal cleanups Minor cleanups, in preparation for merging Marvell PATA AHCI support in the future. Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 779a2b0aadda..b14e7ef343f3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -229,6 +229,9 @@ static void ahci_error_handler(struct ata_port *ap); static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static int ahci_port_resume(struct ata_port *ap); +static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); +static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, + u32 opts); #ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); @@ -481,11 +484,17 @@ static inline int ahci_nr_ports(u32 cap) return (cap & 0x1f) + 1; } +static inline void __iomem *__ahci_port_base(struct ata_host *host, + unsigned int port_no) +{ + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; + + return mmio + 0x100 + (port_no * 0x80); +} + static inline void __iomem *ahci_port_base(struct ata_port *ap) { - void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; - - return mmio + 0x100 + (ap->port_no * 0x80); + return __ahci_port_base(ap->host, ap->port_no); } /** @@ -1750,14 +1759,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->private_data = hpriv; for (i = 0; i < host->n_ports; i++) { - if (hpriv->port_map & (1 << i)) { - struct ata_port *ap = host->ports[i]; - void __iomem *port_mmio = ahci_port_base(ap); + struct ata_port *ap = host->ports[i]; + void __iomem *port_mmio = ahci_port_base(ap); + /* standard SATA port setup */ + if (hpriv->port_map & (1 << i)) { ap->ioaddr.cmd_addr = port_mmio; ap->ioaddr.scr_addr = port_mmio + PORT_SCR; - } else - host->ports[i]->ops = &ata_dummy_port_ops; + } + + /* disabled/not-implemented port */ + else + ap->ops = &ata_dummy_port_ops; } /* initialize adapter */ From a5bf5f5a370ba7c10f5362265e360952145a7da1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 25 May 2007 19:16:58 +0200 Subject: [PATCH 222/551] ata_piix: fix pio/mwdma programming Fix various bugs in pio/mwdma mode programming. * Control bits in the timing register wasn't cleared properly while programming PIO mode. * MWDMA mode programming cleared the wrong part of control bits. * MWDMA mode programming cleared udma_mask even when the controller doesn't support UDMA. Signed-off-by: Tejun Heo Cc: Art Haas Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9c07b88631be..924e4474068d 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -685,8 +685,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) if (adev->class == ATA_DEV_ATA) control |= 4; /* PPE enable */ + /* PIO configuration clears DTE unconditionally. It will be + * programmed in set_dmamode which is guaranteed to be called + * after set_piomode if any DMA mode is available. + */ pci_read_config_word(dev, master_port, &master_data); if (is_slave) { + /* clear TIME1|IE1|PPE1|DTE1 */ + master_data &= 0xff0f; /* Enable SITRE (seperate slave timing register) */ master_data |= 0x4000; /* enable PPE1, IE1 and TIME1 as needed */ @@ -694,12 +700,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) pci_read_config_byte(dev, slave_port, &slave_data); slave_data &= (ap->port_no ? 0x0f : 0xf0); /* Load the timing nibble for this slave */ - slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); + slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) + << (ap->port_no ? 4 : 0); } else { - /* Master keeps the bits in a different format */ - master_data &= 0xccf8; + /* clear ISP|RCT|TIME0|IE0|PPE0|DTE0 */ + master_data &= 0xccf0; /* Enable PPE, IE and TIME as appropriate */ master_data |= control; + /* load ISP and RCT */ master_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8); @@ -816,7 +824,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ master_data |= control << 4; pci_read_config_byte(dev, 0x44, &slave_data); - slave_data &= (0x0F + 0xE1 * ap->port_no); + slave_data &= (ap->port_no ? 0x0f : 0xf0); /* Load the matching timing */ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); pci_write_config_byte(dev, 0x44, slave_data); @@ -828,8 +836,11 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i (timings[pio][0] << 12) | (timings[pio][1] << 8); } - udma_enable &= ~(1 << devid); - pci_write_config_word(dev, master_port, master_data); + + if (ap->udma_mask) { + udma_enable &= ~(1 << devid); + pci_write_config_word(dev, master_port, master_data); + } } /* Don't scribble on 0x48 if the controller does not support UDMA */ if (ap->udma_mask) From 5446b656ddebc2f3902242fda4e860fb343d2787 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 28 May 2007 09:03:51 -0400 Subject: [PATCH 223/551] [libata] pata_ixp4xx: kill unused var Reported by Michael-Luke Jones. Signed-off-by: Jeff Garzik --- drivers/ata/pata_ixp4xx_cf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 76332109a4f7..4ca7fd6118d5 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -171,7 +171,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) struct ata_host *host; struct ata_port *ap; struct ixp4xx_pata_data *data = pdev->dev.platform_data; - int rc; cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); From d0e580316e3db9f5cf6a605cc311ffb0372f0a35 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 19 Jun 2007 21:53:30 +0200 Subject: [PATCH 224/551] sata_promise: cleanups This patch applies some trivial cleanups to sata_promise: - repair whitespace damage - correct comment at board_2057x_pata definition - pull SATAII TX4 support code out to separate functions - rename ata_nr to ata_no for consistency with libata's port_no - remove some init-time debug printks (requested by Jeff) This patch should cause no behavioural changes, except for the removed printks. Signed-off-by: Mikael Pettersson -- drivers/ata/sata_promise.c | 56 ++++++++++++++++++--------------------------- 1 files changed, 23 insertions(+), 33 deletions(-) Signed-off-by: Jeff Garzik --- drivers/ata/sata_promise.c | 56 ++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 7fcc4fe4d79b..78bdfd00b218 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -45,8 +45,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_promise" -#define DRV_VERSION "2.07" - +#define DRV_VERSION "2.08" enum { PDC_MAX_PORTS = 4, @@ -94,7 +93,7 @@ enum { board_20319 = 2, /* FastTrak S150 TX4 */ board_20619 = 3, /* FastTrak TX4000 */ board_2057x = 4, /* SATAII150 Tx2plus */ - board_2057x_pata = 5, /* SATAII150 Tx2plus */ + board_2057x_pata = 5, /* SATAII150 Tx2plus PATA port */ board_40518 = 6, /* SATAII150 Tx4 */ PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ @@ -124,7 +123,6 @@ enum { PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ }; - struct pdc_port_priv { u8 *pkt; dma_addr_t pkt_dma; @@ -340,7 +338,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { { } /* terminate list */ }; - static struct pci_driver pdc_ata_pci_driver = { .name = DRV_NAME, .id_table = pdc_ata_pci_tbl, @@ -348,7 +345,6 @@ static struct pci_driver pdc_ata_pci_driver = { .remove = ata_pci_remove_one, }; - static int pdc_common_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; @@ -438,7 +434,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } - static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { @@ -657,8 +652,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, ata_port_abort(ap); } -static inline unsigned int pdc_host_intr( struct ata_port *ap, - struct ata_queued_cmd *qc) +static inline unsigned int pdc_host_intr(struct ata_port *ap, + struct ata_queued_cmd *qc) { unsigned int handled = 0; void __iomem *port_mmio = ap->ioaddr.cmd_addr; @@ -685,10 +680,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap, handled = 1; break; - default: + default: ap->stats.idle_irq++; break; - } + } return handled; } @@ -701,6 +696,18 @@ static void pdc_irq_clear(struct ata_port *ap) readl(mmio + PDC_INT_SEQMASK); } +static inline int pdc_is_sataii_tx4(unsigned long flags) +{ + const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS; + return (flags & mask) == mask; +} + +static inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4) +{ + static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2}; + return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no; +} + static irqreturn_t pdc_interrupt (int irq, void *dev_instance) { struct ata_host *host = dev_instance; @@ -807,7 +814,6 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) ata_tf_load(ap, tf); } - static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) { WARN_ON (tf->protocol == ATA_PROT_DMA || @@ -867,7 +873,6 @@ static void pdc_ata_setup_port(struct ata_port *ap, ap->ioaddr.scr_addr = scr_addr; } - static void pdc_host_init(struct ata_host *host) { void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; @@ -955,10 +960,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e if (pi->flags & PDC_FLAG_SATA_PATA) { u8 tmp = readb(base + PDC_FLASH_CTL+1); - if (!(tmp & 0x80)) { + if (!(tmp & 0x80)) ppi[n_ports++] = pi + 1; - dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n"); - } } host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); @@ -968,22 +971,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e } host->iomap = pcim_iomap_table(pdev); - is_sataii_tx4 = 0; - if ((pi->flags & (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) == (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) { - is_sataii_tx4 = 1; - dev_printk(KERN_INFO, &pdev->dev, "applying SATAII TX4 port numbering workaround\n"); - } + is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags); for (i = 0; i < host->n_ports; i++) { - static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2}; - int ata_nr; - - ata_nr = i; - if (is_sataii_tx4) - ata_nr = sataii_tx4_port_remap[i]; - + unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); pdc_ata_setup_port(host->ports[i], - base + 0x200 + ata_nr * 0x80, - base + 0x400 + ata_nr * 0x100); + base + 0x200 + ata_no * 0x80, + base + 0x400 + ata_no * 0x100); } /* initialize adapter */ @@ -1002,19 +995,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e &pdc_ata_sht); } - static int __init pdc_ata_init(void) { return pci_register_driver(&pdc_ata_pci_driver); } - static void __exit pdc_ata_exit(void) { pci_unregister_driver(&pdc_ata_pci_driver); } - MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver"); MODULE_LICENSE("GPL"); From 5f45bc50976ee1f408f7171af155aec646655a37 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 15 Jun 2007 17:45:49 +0800 Subject: [PATCH 225/551] Add irq_flags to struct pata_platform_info On some embedded platforms, such as blackfin, the gpio interrupt for IDE interface is designed to be triggered with high voltage. The gpio port should be configured properly by set_irq_type() when register the irq. This patch enable the generic pata platform driver to accept platform irq flags data. Signed-off-by: Sonic Zhang Signed-off-by: Jeff Garzik --- drivers/ata/pata_platform.c | 6 ++++-- include/linux/pata_platform.h | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index cbb7866940d6..79f841bca593 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -139,6 +139,7 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) struct resource *io_res, *ctl_res; struct ata_host *host; struct ata_port *ap; + struct pata_platform_info *pp_info; unsigned int mmio; /* @@ -208,11 +209,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data); + pp_info = (struct pata_platform_info *)(pdev->dev.platform_data); + pata_platform_setup_port(&ap->ioaddr, pp_info); /* activate */ return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, - 0, &pata_platform_sht); + pp_info->irq_flags, &pata_platform_sht); } /** diff --git a/include/linux/pata_platform.h b/include/linux/pata_platform.h index 2d5fd647e0e9..5799e8d50623 100644 --- a/include/linux/pata_platform.h +++ b/include/linux/pata_platform.h @@ -8,6 +8,11 @@ struct pata_platform_info { * spacing used by ata_std_ports(). */ unsigned int ioport_shift; + /* + * Indicate platform specific irq types and initial + * IRQ flags when call request_irq() + */ + unsigned int irq_flags; }; #endif /* __LINUX_PATA_PLATFORM_H */ From 825cd6dd793770ebd42d9ca19f5ee7d082350317 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 3 Jul 2007 01:10:25 +0200 Subject: [PATCH 226/551] sata_sil24: sil24_interrupt() micro-optimisation sil24_interrupt() loads host->ports[i] into a local variable, validates it, and then loads the value again in the call to sil24_host_intr(). This patch replaces the second load by a reference to the local variable. This is safe since no side-effects have occurred since the initial load. It also improves readability since it makes it clear that the parameter to sil24_host_intr() is the same value which was just validated. Signed-off-by: Mikael Pettersson Signed-off-by: Jeff Garzik --- drivers/ata/sata_sil24.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 0ddfae9911cd..14261f393c67 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -888,7 +888,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance) if (status & (1 << i)) { struct ata_port *ap = host->ports[i]; if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { - sil24_host_intr(host->ports[i]); + sil24_host_intr(ap); handled++; } else printk(KERN_ERR DRV_NAME From c1e6f28cc5de37dcd113b9668a185c0b9334ba8a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 3 Jul 2007 10:19:20 -0400 Subject: [PATCH 227/551] Add a PCI ID for santa rosa's PATA controller. Signed-off-by: Christian Lamparter Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 924e4474068d..76cbdf0094f3 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = { /* ICH7/7-R (i945, i975) UDMA 100*/ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + /* ICH8 Mobile PATA Controller */ + { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* NOTE: The following PCI ids must be kept in sync with the * list in drivers/pci/quirks.c. From d26fc9551a15fdad0d5de8376a78816b8af44f00 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 6 Jul 2007 19:13:52 -0400 Subject: [PATCH 228/551] libata: Support chips with 64K PRD quirk Add ata_dumb_qc_prep and supporting logic so that a driver can just specify it needs to be helped in this area. 64K entries are split as with drivers/ide. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 80 +++++++++++++++++++++++++++++++++++++++ drivers/ata/libata-scsi.c | 2 +- drivers/ata/pata_cs5520.c | 4 +- drivers/ata/pata_cs5530.c | 4 +- drivers/ata/pata_sc1200.c | 4 +- include/linux/libata.h | 2 + 6 files changed, 89 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 74c4cd9ad82b..5b25311ba885 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4102,6 +4102,68 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } +/** + * ata_fill_sg_dumb - Fill PCI IDE PRD table + * @qc: Metadata associated with taskfile to be transferred + * + * Fill PCI IDE PRD (scatter-gather) table with segments + * associated with the current disk command. Perform the fill + * so that we avoid writing any length 64K records for + * controllers that don't follow the spec. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + */ +static void ata_fill_sg_dumb(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct scatterlist *sg; + unsigned int idx; + + WARN_ON(qc->__sg == NULL); + WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); + + idx = 0; + ata_for_each_sg(sg, qc) { + u32 addr, offset; + u32 sg_len, len, blen; + + /* determine if physical DMA addr spans 64K boundary. + * Note h/w doesn't support 64-bit, so we unconditionally + * truncate dma_addr_t to u32. + */ + addr = (u32) sg_dma_address(sg); + sg_len = sg_dma_len(sg); + + while (sg_len) { + offset = addr & 0xffff; + len = sg_len; + if ((offset + sg_len) > 0x10000) + len = 0x10000 - offset; + + blen = len & 0xffff; + ap->prd[idx].addr = cpu_to_le32(addr); + if (blen == 0) { + /* Some PATA chipsets like the CS5530 can't + cope with 0x0000 meaning 64K as the spec says */ + ap->prd[idx].flags_len = cpu_to_le32(0x8000); + blen = 0x8000; + ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000); + } + ap->prd[idx].flags_len = cpu_to_le32(blen); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); + + idx++; + sg_len -= len; + addr += len; + } + } + + if (idx) + ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); +} + /** * ata_check_atapi_dma - Check whether ATAPI DMA can be supported * @qc: Metadata associated with taskfile to check @@ -4149,6 +4211,23 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ata_fill_sg(qc); } +/** + * ata_dumb_qc_prep - Prepare taskfile for submission + * @qc: Metadata associated with taskfile to be prepared + * + * Prepare ATA taskfile for submission. + * + * LOCKING: + * spin_lock_irqsave(host lock) + */ +void ata_dumb_qc_prep(struct ata_queued_cmd *qc) +{ + if (!(qc->flags & ATA_QCFLAG_DMAMAP)) + return; + + ata_fill_sg_dumb(qc); +} + void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } /** @@ -6821,6 +6900,7 @@ EXPORT_SYMBOL_GPL(ata_do_set_mode); EXPORT_SYMBOL_GPL(ata_data_xfer); EXPORT_SYMBOL_GPL(ata_data_xfer_noirq); EXPORT_SYMBOL_GPL(ata_qc_prep); +EXPORT_SYMBOL_GPL(ata_dumb_qc_prep); EXPORT_SYMBOL_GPL(ata_noop_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); EXPORT_SYMBOL_GPL(ata_bmdma_start); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4ddf00c8c5f5..cfde22da07ac 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2620,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ata_dev_printk(dev, KERN_WARNING, "invalid multi_count %u ignored\n", multi_count); - } + } /* READ/WRITE LONG use a non-standard sect_size */ qc->sect_size = ATA_SECT_SIZE; diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 00cf0134079c..6bf037d82b5a 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = { .queuecommand = ata_scsi_queuecmd, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = LIBATA_DUMB_MAX_PRD, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -178,7 +178,7 @@ static struct ata_port_operations cs5520_port_ops = { .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, + .qc_prep = ata_dumb_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 797a6f67e8f5..3fca5898642b 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -167,7 +167,7 @@ static struct scsi_host_template cs5530_sht = { .queuecommand = ata_scsi_queuecmd, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = LIBATA_DUMB_MAX_PRD, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -201,7 +201,7 @@ static struct ata_port_operations cs5530_port_ops = { .post_internal_cmd = ata_bmdma_post_internal_cmd, .cable_detect = ata_cable_40wire, - .qc_prep = ata_qc_prep, + .qc_prep = ata_dumb_qc_prep, .qc_issue = cs5530_qc_issue_prot, .data_xfer = ata_data_xfer, diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 7ff39cf9dc0b..b8b2d11e4180 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = { .queuecommand = ata_scsi_queuecmd, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = LIBATA_DUMB_MAX_PRD, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -219,7 +219,7 @@ static struct ata_port_operations sc1200_port_ops = { .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, + .qc_prep = ata_dumb_qc_prep, .qc_issue = sc1200_qc_issue_prot, .data_xfer = ata_data_xfer, diff --git a/include/linux/libata.h b/include/linux/libata.h index 8d3e391ab8d3..a3df64677ac3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -116,6 +116,7 @@ static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) enum { /* various global constants */ LIBATA_MAX_PRD = ATA_MAX_PRD / 2, + LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */ ATA_MAX_PORTS = 8, ATA_DEF_QUEUE = 1, /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ @@ -778,6 +779,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data); extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data); +extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); From 469248abf00dfa813356b372ffe153b85f27f4bf Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 8 Jul 2007 01:13:16 -0400 Subject: [PATCH 229/551] [libata] Clean up driver udma_mask initializers * Use ATA_UDMA* * Remove FIXME notations that once served to remind us to verify that these were indeed the correct UDMA masks. They are. Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 10 +++++----- drivers/ata/sata_promise.c | 14 +++++++------- drivers/ata/sata_sx4.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b14e7ef343f3..f66e2a50158b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -330,14 +330,14 @@ static const struct ata_port_info ahci_port_info[] = { { .flags = AHCI_FLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, /* board_ahci_pi */ { .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, /* board_ahci_vt8251 */ @@ -345,14 +345,14 @@ static const struct ata_port_info ahci_port_info[] = { .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &ahci_vt8251_ops, }, /* board_ahci_ign_iferr */ { .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, /* board_ahci_sb600 */ @@ -361,7 +361,7 @@ static const struct ata_port_info ahci_port_info[] = { AHCI_FLAG_IGN_SERR_INTERNAL | AHCI_FLAG_32BIT_ONLY, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, }; diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 78bdfd00b218..2ad5872fe90c 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -250,7 +250,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_SATA_PATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_old_sata_ops, }, @@ -259,7 +259,7 @@ static const struct ata_port_info pdc_port_info[] = { .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_pata_ops, }, @@ -269,7 +269,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_old_sata_ops, }, @@ -279,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_pata_ops, }, @@ -289,7 +289,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_sata_ops, }, @@ -299,7 +299,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_GEN_II, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_pata_ops, }, @@ -309,7 +309,7 @@ static const struct ata_port_info pdc_port_info[] = { PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_sata_ops, }, }; diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 3d83ee273388..5193bd8647ba 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -279,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = { ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .udma_mask = ATA_UDMA6, .port_ops = &pdc_20621_ops, }, From cd70c26617f4686355263be4533ce8030242740e Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 8 Jul 2007 02:29:42 -0400 Subject: [PATCH 230/551] [libata] AHCI: Add support for Marvell AHCI-like chips (initially 6145) Add support for the SATA portion of Marvell's AHCI-compatible chips. The PATA port capability, also available via AHCI, is disabled until support is completed. NCQ and PCI MSI are disabled by default. Marvell says "we use NCQ" in their drivers but "we do not use PCI MSI." Theoretically that implies we need to fix ahci.c to work with Marvell NCQ, but one wonders why Marvell NCQ is any different from other AHCI chips. Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 51 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f66e2a50158b..11e4eb9f304e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -46,7 +46,7 @@ #include #define DRV_NAME "ahci" -#define DRV_VERSION "2.2" +#define DRV_VERSION "2.3" enum { @@ -81,6 +81,7 @@ enum { board_ahci_vt8251 = 2, board_ahci_ign_iferr = 3, board_ahci_sb600 = 4, + board_ahci_mv = 5, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -171,6 +172,8 @@ enum { AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */ AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */ + AHCI_FLAG_MV_PATA = (1 << 29), /* PATA port */ + AHCI_FLAG_NO_MSI = (1 << 30), /* no PCI MSI */ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | @@ -364,6 +367,18 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + /* board_ahci_mv */ + { + .sht = &ahci_sht, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI | + AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI | + AHCI_FLAG_MV_PATA, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, }; static const struct pci_device_id ahci_pci_tbl[] = { @@ -459,6 +474,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ + /* Marvell */ + { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ + /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, @@ -544,6 +562,20 @@ static void ahci_save_initial_config(struct pci_dev *pdev, hpriv->saved_port_map = port_map; } + /* + * Temporary Marvell 6145 hack: PATA port presence + * is asserted through the standard AHCI port + * presence register, as bit 4 (counting from 0) + */ + if (pi->flags & AHCI_FLAG_MV_PATA) { + dev_printk(KERN_ERR, &pdev->dev, + "MV_AHCI HACK: port_map %x -> %x\n", + hpriv->port_map, + hpriv->port_map & 0xf); + + port_map &= 0xf; + } + /* cross check port_map and cap.n_ports */ if (pi->flags & AHCI_FLAG_HONOR_PI) { u32 tmp_port_map = port_map; @@ -856,12 +888,25 @@ static void ahci_init_controller(struct ata_host *host) struct pci_dev *pdev = to_pci_dev(host->dev); void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; int i; + void __iomem *port_mmio; u32 tmp; + if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) { + port_mmio = __ahci_port_base(host, 4); + + writel(0, port_mmio + PORT_IRQ_MASK); + + /* clear port IRQ */ + tmp = readl(port_mmio + PORT_IRQ_STAT); + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + } + for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - void __iomem *port_mmio = ahci_port_base(ap); + port_mmio = ahci_port_base(ap); if (ata_port_is_dummy(ap)) continue; @@ -1738,7 +1783,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - if (pci_enable_msi(pdev)) + if ((pi.flags & AHCI_FLAG_NO_MSI) || pci_enable_msi(pdev)) pci_intx(pdev, 1); hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); From bf6263a853c9c143bf03f0a6fdcc68ab714fb5f5 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 9 Jul 2007 12:16:50 -0400 Subject: [PATCH 231/551] [libata] Use ATA_UDMAx standard masks when filling driver's udma_mask info The ATA_UDMAx masks are self-documenting, and far better than manually writing in the hex mask. Note that pata_it8213 mask differed from the comment. Added a FIXME there. Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 2 +- drivers/ata/ata_piix.c | 10 +++++----- drivers/ata/pata_ali.c | 8 ++++---- drivers/ata/pata_amd.c | 18 +++++++++--------- drivers/ata/pata_cs5535.c | 2 +- drivers/ata/pata_hpt366.c | 2 +- drivers/ata/pata_hpt37x.c | 8 ++++---- drivers/ata/pata_hpt3x2n.c | 2 +- drivers/ata/pata_it8213.c | 2 +- drivers/ata/pata_it821x.c | 2 +- drivers/ata/pata_jmicron.c | 2 +- drivers/ata/pata_marvell.c | 4 ++-- drivers/ata/pata_netcell.c | 2 +- drivers/ata/pata_serverworks.c | 4 ++-- drivers/ata/pata_sil680.c | 4 ++-- drivers/ata/pata_via.c | 8 ++++---- drivers/ata/pdc_adma.c | 2 +- drivers/ata/sata_inic162x.c | 2 +- drivers/ata/sata_mv.c | 14 +++++++------- drivers/ata/sata_qstor.c | 2 +- drivers/ata/sata_sil.c | 8 ++++---- drivers/ata/sata_sil24.c | 6 +++--- drivers/ata/sata_sis.c | 2 +- drivers/ata/sata_svw.c | 4 ++-- drivers/ata/sata_uli.c | 2 +- drivers/ata/sata_via.c | 6 +++--- drivers/ata/sata_vsc.c | 2 +- 27 files changed, 65 insertions(+), 65 deletions(-) diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 0878fb5b3254..430fcf4f9ef3 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -146,7 +146,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &generic_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 76cbdf0094f3..6a3bfef58e13 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -497,7 +497,7 @@ static struct ata_port_info piix_port_info[] = { .flags = PIIX_SATA_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, @@ -507,7 +507,7 @@ static struct ata_port_info piix_port_info[] = { .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, @@ -518,7 +518,7 @@ static struct ata_port_info piix_port_info[] = { PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, @@ -529,7 +529,7 @@ static struct ata_port_info piix_port_info[] = { PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, @@ -540,7 +540,7 @@ static struct ata_port_info piix_port_info[] = { PIIX_FLAG_AHCI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 5c53d5aa13a8..30c4276ec882 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -547,7 +547,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &ali_c2_port_ops }; /* Revision 0xC3 is UDMA66 for now */ @@ -556,7 +556,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &ali_c2_port_ops }; /* Revision 0xC4 is UDMA100 */ @@ -565,7 +565,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &ali_c2_port_ops }; /* Revision 0xC5 is UDMA133 with LBA48 DMA */ @@ -574,7 +574,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &ali_c5_port_ops }; diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 533bcc9d1542..b9c44c575ce3 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -552,7 +552,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, /* UDMA 66 */ + .udma_mask = ATA_UDMA4, /* UDMA 66 */ .port_ops = &amd66_port_ops }, { /* 2: AMD 7409, no swdma errata */ @@ -560,7 +560,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, /* UDMA 66 */ + .udma_mask = ATA_UDMA4, /* UDMA 66 */ .port_ops = &amd66_port_ops }, { /* 3: AMD 7411 */ @@ -568,7 +568,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, /* UDMA 100 */ + .udma_mask = ATA_UDMA5, /* UDMA 100 */ .port_ops = &amd100_port_ops }, { /* 4: AMD 7441 */ @@ -576,7 +576,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, /* UDMA 100 */ + .udma_mask = ATA_UDMA5, /* UDMA 100 */ .port_ops = &amd100_port_ops }, { /* 5: AMD 8111*/ @@ -584,7 +584,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, /* UDMA 133, no swdma */ + .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */ .port_ops = &amd133_port_ops }, { /* 6: AMD 8111 UDMA 100 (Serenade) */ @@ -592,7 +592,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, /* UDMA 100, no swdma */ + .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */ .port_ops = &amd133_port_ops }, { /* 7: Nvidia Nforce */ @@ -600,7 +600,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, /* UDMA 100 */ + .udma_mask = ATA_UDMA5, /* UDMA 100 */ .port_ops = &nv100_port_ops }, { /* 8: Nvidia Nforce2 and later */ @@ -608,7 +608,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, /* UDMA 133, no swdma */ + .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */ .port_ops = &nv133_port_ops }, { /* 9: AMD CS5536 (Geode companion) */ @@ -616,7 +616,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, /* UDMA 100 */ + .udma_mask = ATA_UDMA5, /* UDMA 100 */ .port_ops = &amd100_port_ops } }; diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 7eeed578af0b..360b6f32e17e 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -228,7 +228,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &cs5535_port_ops }; const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 7a6ff3dfc775..6f7d34ad19ef 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -396,7 +396,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &hpt366_port_ops }; struct ata_port_info info = info_hpt366; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index d2278fdb1025..b0af65aadde3 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -892,7 +892,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &hpt370_port_ops }; /* HPT370A - UDMA100 */ @@ -901,7 +901,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &hpt370a_port_ops }; /* HPT370 - UDMA100 */ @@ -928,7 +928,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &hpt372_port_ops }; /* HPT374 - UDMA100 */ @@ -937,7 +937,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &hpt374_port_ops }; diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 809d3385df7d..aa29cde09f8b 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -493,7 +493,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &hpt3x2n_port_ops }; struct ata_port_info port = info; diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 41fb08bd1776..b8af55e89156 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -316,7 +316,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x1f, /* UDMA 100 */ + .udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */ .port_ops = &it8213_ops, }; /* Current IT8213 stuff is single port */ diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 4f26ef1665d4..b67bbf6516ba 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -724,7 +724,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &it821x_passthru_port_ops }; diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 1a6c4dbba5cf..4d67f238eee2 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -197,7 +197,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &jmicron_ops, }; diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 73f1e4b66038..87594c04d3a3 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -167,7 +167,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &marvell_ops, }; @@ -178,7 +178,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &marvell_ops, }; diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index b7c8b13ffda8..40eb574828bf 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -99,7 +99,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e firmware deals with it */ .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* UDMA 133 */ + .udma_mask = ATA_UDMA5, /* UDMA 133 */ .port_ops = &netcell_ops, }; const struct ata_port_info *port_info[] = { &info, NULL }; diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 2c0bc3bb1692..0231aba51ca4 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -495,14 +495,14 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &serverworks_csb_port_ops }, { /* CSB5 - later revisions*/ .sht = &serverworks_sht, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &serverworks_csb_port_ops } }; diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 9b645c5ec955..b0cd52d6e3fb 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -349,7 +349,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &sil680_port_ops }; static const struct ata_port_info info_slow = { @@ -357,7 +357,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &sil680_port_ops }; const struct ata_port_info *ppi[] = { &info, NULL }; diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 63eca299c62b..f0cadbe6aa11 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -471,7 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7, + .udma_mask = ATA_UDMA2, .port_ops = &via_port_ops }; /* VIA UDMA 66 devices */ @@ -480,7 +480,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x1f, + .udma_mask = ATA_UDMA4, .port_ops = &via_port_ops }; /* VIA UDMA 100 devices */ @@ -489,7 +489,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = ATA_UDMA5, .port_ops = &via_port_ops }; /* UDMA133 with bad AST (All current 133) */ @@ -498,7 +498,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, /* FIXME: should check north bridge */ + .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */ .port_ops = &via_port_ops }; struct ata_port_info type; diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 74c50c90e4d0..bec1de594de8 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -188,7 +188,7 @@ static struct ata_port_info adma_port_info[] = { ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, .pio_mask = 0x10, /* pio4 */ - .udma_mask = 0x1f, /* udma0-4 */ + .udma_mask = ATA_UDMA4, .port_ops = &adma_ata_ops, }, }; diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 8efc5316b32e..3de183461c3c 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -594,7 +594,7 @@ static struct ata_port_info inic_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &inic_port_ops }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 590f2f92b4e0..d65ec234be5c 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -526,44 +526,44 @@ static const struct ata_port_info mv_port_info[] = { { /* chip_504x */ .flags = MV_COMMON_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv5_ops, }, { /* chip_508x */ .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv5_ops, }, { /* chip_5080 */ .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv5_ops, }, { /* chip_604x */ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv6_ops, }, { /* chip_608x */ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv6_ops, }, { /* chip_6042 */ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv_iie_ops, }, { /* chip_7042 */ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &mv_iie_ops, }, }; diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 6688ccb66320..9ab554da89bf 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -176,7 +176,7 @@ static const struct ata_port_info qs_port_info[] = { //FIXME ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, .pio_mask = 0x10, /* pio4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &qs_ata_ops, }, }; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index c3f0a86cb735..2a86dc4598d0 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -218,7 +218,7 @@ static const struct ata_port_info sil_port_info[] = { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, .port_ops = &sil_ops, }, /* sil_3112_no_sata_irq */ @@ -227,7 +227,7 @@ static const struct ata_port_info sil_port_info[] = { SIL_FLAG_NO_SATA_IRQ, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, .port_ops = &sil_ops, }, /* sil_3512 */ @@ -235,7 +235,7 @@ static const struct ata_port_info sil_port_info[] = { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, .port_ops = &sil_ops, }, /* sil_3114 */ @@ -243,7 +243,7 @@ static const struct ata_port_info sil_port_info[] = { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, .port_ops = &sil_ops, }, }; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 14261f393c67..ac43a30ebe29 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -426,7 +426,7 @@ static const struct ata_port_info sil24_port_info[] = { SIL24_FLAG_PCIX_IRQ_WOC, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ .port_ops = &sil24_ops, }, /* sil_3132 */ @@ -434,7 +434,7 @@ static const struct ata_port_info sil24_port_info[] = { .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ .port_ops = &sil24_ops, }, /* sil_3131/sil_3531 */ @@ -442,7 +442,7 @@ static const struct ata_port_info sil24_port_info[] = { .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ .port_ops = &sil24_ops, }, }; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index f111c984a359..fd80bcf1b236 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -133,7 +133,7 @@ static const struct ata_port_info sis_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x7, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &sis_ops, }; diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 4fd4f107187c..63fe99afd59f 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -361,7 +361,7 @@ static const struct ata_port_info k2_port_info[] = { ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, /* board_svw8 */ @@ -371,7 +371,7 @@ static const struct ata_port_info k2_port_info[] = { K2_FLAG_SATA_8_PORTS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, }; diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 6815de7cca79..aca71819f6e8 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -129,7 +129,7 @@ static const struct ata_port_info uli_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .udma_mask = ATA_UDMA6, .port_ops = &uli_ops, }; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index e816965ef4f1..a4c0832033d8 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -223,7 +223,7 @@ static const struct ata_port_info vt6420_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &vt6420_sata_ops, }; @@ -231,7 +231,7 @@ static struct ata_port_info vt6421_sport_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &vt6421_sata_ops, }; @@ -239,7 +239,7 @@ static struct ata_port_info vt6421_pport_info = { .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &vt6421_pata_ops, }; diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 81330175fc89..1b5d81faa102 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -371,7 +371,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d ATA_FLAG_MMIO, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = ATA_UDMA6, .port_ops = &vsc_sata_ops, }; const struct ata_port_info *ppi[] = { &pi, NULL }; From c1e4fe711a410a139095e6b3e3ce3f07f466063c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 9 Jul 2007 12:29:31 -0400 Subject: [PATCH 232/551] [libata] sata_mv: print out additional chip info during probe Indicate whether this is a Generation-I (50xx), Generation-II (60xx), or Generation-II-E (6042/7042) chip. Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index d65ec234be5c..3873b29c80d6 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2338,7 +2338,7 @@ static void mv_print_info(struct ata_host *host) struct pci_dev *pdev = to_pci_dev(host->dev); struct mv_host_priv *hpriv = host->private_data; u8 rev_id, scc; - const char *scc_s; + const char *scc_s, *gen; /* Use this to determine the HW stepping of the chip so we know * what errata to workaround @@ -2351,11 +2351,20 @@ static void mv_print_info(struct ata_host *host) else if (scc == 0x01) scc_s = "RAID"; else - scc_s = "unknown"; + scc_s = "?"; + + if (IS_GEN_I(hpriv)) + gen = "I"; + else if (IS_GEN_II(hpriv)) + gen = "II"; + else if (IS_GEN_IIE(hpriv)) + gen = "IIE"; + else + gen = "?"; dev_printk(KERN_INFO, &pdev->dev, - "%u slots %u ports %s mode IRQ via %s\n", - (unsigned)MV_MAX_Q_DEPTH, host->n_ports, + "Gen-%s %u slots %u ports %s mode IRQ via %s\n", + gen, (unsigned)MV_MAX_Q_DEPTH, host->n_ports, scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); } From d15bcfdbe1818478891d714343f037cfe60875f0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:57 +0200 Subject: [PATCH 233/551] sched: rename idle_type/SCHED_IDLE enum idle_type (used by the load-balancer) clashes with the SCHED_IDLE name that we want to introduce. 'CPU_IDLE' instead of 'SCHED_IDLE' is more descriptive as well. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 27 ++++++++++--------- kernel/sched.c | 60 +++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 693f0e6c54d4..2acfb23f3681 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -639,12 +639,11 @@ static inline int sched_info_on(void) #endif } -enum idle_type -{ - SCHED_IDLE, - NOT_IDLE, - NEWLY_IDLE, - MAX_IDLE_TYPES +enum cpu_idle_type { + CPU_IDLE, + CPU_NOT_IDLE, + CPU_NEWLY_IDLE, + CPU_MAX_IDLE_TYPES }; /* @@ -719,14 +718,14 @@ struct sched_domain { #ifdef CONFIG_SCHEDSTATS /* load_balance() stats */ - unsigned long lb_cnt[MAX_IDLE_TYPES]; - unsigned long lb_failed[MAX_IDLE_TYPES]; - unsigned long lb_balanced[MAX_IDLE_TYPES]; - unsigned long lb_imbalance[MAX_IDLE_TYPES]; - unsigned long lb_gained[MAX_IDLE_TYPES]; - unsigned long lb_hot_gained[MAX_IDLE_TYPES]; - unsigned long lb_nobusyg[MAX_IDLE_TYPES]; - unsigned long lb_nobusyq[MAX_IDLE_TYPES]; + unsigned long lb_cnt[CPU_MAX_IDLE_TYPES]; + unsigned long lb_failed[CPU_MAX_IDLE_TYPES]; + unsigned long lb_balanced[CPU_MAX_IDLE_TYPES]; + unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES]; + unsigned long lb_gained[CPU_MAX_IDLE_TYPES]; + unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES]; + unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES]; + unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES]; /* Active load balancing */ unsigned long alb_cnt; diff --git a/kernel/sched.c b/kernel/sched.c index 50e1a3122699..ac054d9a0719 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -496,12 +496,12 @@ static int show_schedstat(struct seq_file *seq, void *v) /* domain-specific stats */ preempt_disable(); for_each_domain(cpu, sd) { - enum idle_type itype; + enum cpu_idle_type itype; char mask_str[NR_CPUS]; cpumask_scnprintf(mask_str, NR_CPUS, sd->span); seq_printf(seq, "domain%d %s", dcnt++, mask_str); - for (itype = SCHED_IDLE; itype < MAX_IDLE_TYPES; + for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES; itype++) { seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu " "%lu", @@ -2208,7 +2208,7 @@ static void pull_task(struct rq *src_rq, struct prio_array *src_array, */ static int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, - struct sched_domain *sd, enum idle_type idle, + struct sched_domain *sd, enum cpu_idle_type idle, int *all_pinned) { /* @@ -2254,7 +2254,7 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, */ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum idle_type idle, + struct sched_domain *sd, enum cpu_idle_type idle, int *all_pinned) { int idx, pulled = 0, pinned = 0, this_best_prio, best_prio, @@ -2372,7 +2372,7 @@ out: */ static struct sched_group * find_busiest_group(struct sched_domain *sd, int this_cpu, - unsigned long *imbalance, enum idle_type idle, int *sd_idle, + unsigned long *imbalance, enum cpu_idle_type idle, int *sd_idle, cpumask_t *cpus, int *balance) { struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups; @@ -2391,9 +2391,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, max_load = this_load = total_load = total_pwr = 0; busiest_load_per_task = busiest_nr_running = 0; this_load_per_task = this_nr_running = 0; - if (idle == NOT_IDLE) + if (idle == CPU_NOT_IDLE) load_idx = sd->busy_idx; - else if (idle == NEWLY_IDLE) + else if (idle == CPU_NEWLY_IDLE) load_idx = sd->newidle_idx; else load_idx = sd->idle_idx; @@ -2477,7 +2477,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, * Busy processors will not participate in power savings * balance. */ - if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) + if (idle == CPU_NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) goto group_next; /* @@ -2639,7 +2639,7 @@ small_imbalance: out_balanced: #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) - if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) + if (idle == CPU_NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) goto ret; if (this == group_leader && group_leader != group_min) { @@ -2656,7 +2656,7 @@ ret: * find_busiest_queue - find the busiest runqueue among the cpus in group. */ static struct rq * -find_busiest_queue(struct sched_group *group, enum idle_type idle, +find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle, unsigned long imbalance, cpumask_t *cpus) { struct rq *busiest = NULL, *rq; @@ -2698,7 +2698,7 @@ static inline unsigned long minus_1_or_zero(unsigned long n) * tasks if there is an imbalance. */ static int load_balance(int this_cpu, struct rq *this_rq, - struct sched_domain *sd, enum idle_type idle, + struct sched_domain *sd, enum cpu_idle_type idle, int *balance) { int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0; @@ -2712,9 +2712,9 @@ static int load_balance(int this_cpu, struct rq *this_rq, * When power savings policy is enabled for the parent domain, idle * sibling can pick up load irrespective of busy siblings. In this case, * let the state of idle sibling percolate up as IDLE, instead of - * portraying it as NOT_IDLE. + * portraying it as CPU_NOT_IDLE. */ - if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && + if (idle != CPU_NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) sd_idle = 1; @@ -2848,7 +2848,7 @@ out_one_pinned: * Check this_cpu to ensure it is balanced within domain. Attempt to move * tasks if there is an imbalance. * - * Called from schedule when this_rq is about to become idle (NEWLY_IDLE). + * Called from schedule when this_rq is about to become idle (CPU_NEWLY_IDLE). * this_rq is locked. */ static int @@ -2865,31 +2865,31 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd) * When power savings policy is enabled for the parent domain, idle * sibling can pick up load irrespective of busy siblings. In this case, * let the state of idle sibling percolate up as IDLE, instead of - * portraying it as NOT_IDLE. + * portraying it as CPU_NOT_IDLE. */ if (sd->flags & SD_SHARE_CPUPOWER && !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) sd_idle = 1; - schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); + schedstat_inc(sd, lb_cnt[CPU_NEWLY_IDLE]); redo: - group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE, + group = find_busiest_group(sd, this_cpu, &imbalance, CPU_NEWLY_IDLE, &sd_idle, &cpus, NULL); if (!group) { - schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]); + schedstat_inc(sd, lb_nobusyg[CPU_NEWLY_IDLE]); goto out_balanced; } - busiest = find_busiest_queue(group, NEWLY_IDLE, imbalance, + busiest = find_busiest_queue(group, CPU_NEWLY_IDLE, imbalance, &cpus); if (!busiest) { - schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); + schedstat_inc(sd, lb_nobusyq[CPU_NEWLY_IDLE]); goto out_balanced; } BUG_ON(busiest == this_rq); - schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance); + schedstat_add(sd, lb_imbalance[CPU_NEWLY_IDLE], imbalance); nr_moved = 0; if (busiest->nr_running > 1) { @@ -2897,7 +2897,7 @@ redo: double_lock_balance(this_rq, busiest); nr_moved = move_tasks(this_rq, this_cpu, busiest, minus_1_or_zero(busiest->nr_running), - imbalance, sd, NEWLY_IDLE, NULL); + imbalance, sd, CPU_NEWLY_IDLE, NULL); spin_unlock(&busiest->lock); if (!nr_moved) { @@ -2908,7 +2908,7 @@ redo: } if (!nr_moved) { - schedstat_inc(sd, lb_failed[NEWLY_IDLE]); + schedstat_inc(sd, lb_failed[CPU_NEWLY_IDLE]); if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) return -1; @@ -2918,7 +2918,7 @@ redo: return nr_moved; out_balanced: - schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); + schedstat_inc(sd, lb_balanced[CPU_NEWLY_IDLE]); if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) return -1; @@ -3003,7 +3003,7 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu) schedstat_inc(sd, alb_cnt); if (move_tasks(target_rq, target_cpu, busiest_rq, 1, - RTPRIO_TO_LOAD_WEIGHT(100), sd, SCHED_IDLE, + RTPRIO_TO_LOAD_WEIGHT(100), sd, CPU_IDLE, NULL)) schedstat_inc(sd, alb_pushed); else @@ -3120,7 +3120,7 @@ static DEFINE_SPINLOCK(balancing); * * Balancing parameters are set up in arch_init_sched_domains. */ -static inline void rebalance_domains(int cpu, enum idle_type idle) +static inline void rebalance_domains(int cpu, enum cpu_idle_type idle) { int balance = 1; struct rq *rq = cpu_rq(cpu); @@ -3134,7 +3134,7 @@ static inline void rebalance_domains(int cpu, enum idle_type idle) continue; interval = sd->balance_interval; - if (idle != SCHED_IDLE) + if (idle != CPU_IDLE) interval *= sd->busy_factor; /* scale ms to jiffies */ @@ -3154,7 +3154,7 @@ static inline void rebalance_domains(int cpu, enum idle_type idle) * longer idle, or one of our SMT siblings is * not idle. */ - idle = NOT_IDLE; + idle = CPU_NOT_IDLE; } sd->last_balance = jiffies; } @@ -3184,7 +3184,7 @@ static void run_rebalance_domains(struct softirq_action *h) { int local_cpu = smp_processor_id(); struct rq *local_rq = cpu_rq(local_cpu); - enum idle_type idle = local_rq->idle_at_tick ? SCHED_IDLE : NOT_IDLE; + enum cpu_idle_type idle = local_rq->idle_at_tick ? CPU_IDLE : CPU_NOT_IDLE; rebalance_domains(local_cpu, idle); @@ -3210,7 +3210,7 @@ static void run_rebalance_domains(struct softirq_action *h) if (need_resched()) break; - rebalance_domains(balance_cpu, SCHED_IDLE); + rebalance_domains(balance_cpu, CPU_IDLE); rq = cpu_rq(balance_cpu); if (time_after(local_rq->next_balance, rq->next_balance)) From 0e6aca43e08a62a48d6770e9a159dbec167bf4c6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:57 +0200 Subject: [PATCH 234/551] sched: add SCHED_IDLE policy this patch adds the SCHED_IDLE policy to sched.h. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 2acfb23f3681..7e74262f98e1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -34,6 +34,8 @@ #define SCHED_FIFO 1 #define SCHED_RR 2 #define SCHED_BATCH 3 +/* SCHED_ISO: reserved but not implemented yet */ +#define SCHED_IDLE 5 #ifdef __KERNEL__ From 0437e109e1841607f2988891eaa36c531c6aa6ac Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:57 +0200 Subject: [PATCH 235/551] sched: zap the migration init / cache-hot balancing code the SMP load-balancer uses the boot-time migration-cost estimation code to attempt to improve the quality of balancing. The reason for this code is that the discrete priority queues do not preserve the order of scheduling accurately, so the load-balancer skips tasks that were running on a CPU 'recently'. this code is fundamental fragile: the boot-time migration cost detector doesnt really work on systems that had large L3 caches, it caused boot delays on large systems and the whole cache-hot concept made the balancing code pretty undeterministic as well. (and hey, i wrote most of it, so i can say it out loud that it sucks ;-) under CFS the same purpose of cache affinity can be achieved without any special cache-hot special-case: tasks are sorted in the 'timeline' tree and the SMP balancer picks tasks from the left side of the tree, thus the most cache-cold task is balanced automatically. Signed-off-by: Ingo Molnar --- Documentation/kernel-parameters.txt | 43 --- arch/i386/kernel/smpboot.c | 12 - arch/ia64/kernel/setup.c | 6 - arch/mips/kernel/smp.c | 11 - arch/sparc/kernel/smp.c | 10 - arch/sparc64/kernel/smp.c | 27 -- include/linux/sched.h | 6 - kernel/sched.c | 481 ---------------------------- 8 files changed, 596 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index af50f9bbe68e..4d880b3d1f35 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1014,49 +1014,6 @@ and is between 256 and 4096 characters. It is defined in the file mga= [HW,DRM] - migration_cost= - [KNL,SMP] debug: override scheduler migration costs - Format: ,,... - This debugging option can be used to override the - default scheduler migration cost matrix. The numbers - are indexed by 'CPU domain distance'. - E.g. migration_cost=1000,2000,3000 on an SMT NUMA - box will set up an intra-core migration cost of - 1 msec, an inter-core migration cost of 2 msecs, - and an inter-node migration cost of 3 msecs. - - WARNING: using the wrong values here can break - scheduler performance, so it's only for scheduler - development purposes, not production environments. - - migration_debug= - [KNL,SMP] migration cost auto-detect verbosity - Format=<0|1|2> - If a system's migration matrix reported at bootup - seems erroneous then this option can be used to - increase verbosity of the detection process. - We default to 0 (no extra messages), 1 will print - some more information, and 2 will be really - verbose (probably only useful if you also have a - serial console attached to the system). - - migration_factor= - [KNL,SMP] multiply/divide migration costs by a factor - Format= - This debug option can be used to proportionally - increase or decrease the auto-detected migration - costs for all entries of the migration matrix. - E.g. migration_factor=150 will increase migration - costs by 50%. (and thus the scheduler will be less - eager migrating cache-hot tasks) - migration_factor=80 will decrease migration costs - by 20%. (thus the scheduler will be more eager to - migrate tasks) - - WARNING: using the wrong values here can break - scheduler performance, so it's only for scheduler - development purposes, not production environments. - mousedev.tap_time= [MOUSE] Maximum time between finger touching and leaving touchpad surface for touch to be considered diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 88baed1e7e83..0b2954534b8e 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -941,17 +941,6 @@ exit: } #endif -static void smp_tune_scheduling(void) -{ - if (cpu_khz) { - /* cache size in kB */ - long cachesize = boot_cpu_data.x86_cache_size; - - if (cachesize > 0) - max_cache_size = cachesize * 1024; - } -} - /* * Cycle through the processors sending APIC IPIs to boot each. */ @@ -980,7 +969,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus) x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; current_thread_info()->cpu = 0; - smp_tune_scheduling(); set_cpu_sibling_map(0); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index eaa6a24bc0b6..188fb73c6845 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -805,7 +805,6 @@ static void __cpuinit get_max_cacheline_size (void) { unsigned long line_size, max = 1; - unsigned int cache_size = 0; u64 l, levels, unique_caches; pal_cache_config_info_t cci; s64 status; @@ -835,8 +834,6 @@ get_max_cacheline_size (void) line_size = 1 << cci.pcci_line_size; if (line_size > max) max = line_size; - if (cache_size < cci.pcci_cache_size) - cache_size = cci.pcci_cache_size; if (!cci.pcci_unified) { status = ia64_pal_cache_config_info(l, /* cache_type (instruction)= */ 1, @@ -853,9 +850,6 @@ get_max_cacheline_size (void) ia64_i_cache_stride_shift = cci.pcci_stride; } out: -#ifdef CONFIG_SMP - max_cache_size = max(max_cache_size, cache_size); -#endif if (max > ia64_max_cacheline_size) ia64_max_cacheline_size = max; } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 67edfa7ed93a..a1b017f2dbb3 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -51,16 +51,6 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ EXPORT_SYMBOL(phys_cpu_present_map); EXPORT_SYMBOL(cpu_online_map); -/* This happens early in bootup, can't really do it better */ -static void smp_tune_scheduling (void) -{ - struct cache_desc *cd = ¤t_cpu_data.scache; - unsigned long cachesize = cd->linesz * cd->sets * cd->ways; - - if (cachesize > max_cache_size) - max_cache_size = cachesize; -} - extern void __init calibrate_delay(void); extern ATTRIB_NORET void cpu_idle(void); @@ -228,7 +218,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) { init_new_context(current, &init_mm); current_thread_info()->cpu = 0; - smp_tune_scheduling(); plat_prepare_cpus(max_cpus); #ifndef CONFIG_HOTPLUG_CPU cpu_present_map = cpu_possible_map; diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 4d9ad59031bb..4fea3ac7bff0 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -68,16 +68,6 @@ void __cpuinit smp_store_cpu_info(int id) cpu_data(id).prom_node = cpu_node; cpu_data(id).mid = cpu_get_hwmid(cpu_node); - /* this is required to tune the scheduler correctly */ - /* is it possible to have CPUs with different cache sizes? */ - if (id == boot_cpu_id) { - int cache_line,cache_nlines; - cache_line = 0x20; - cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line); - cache_nlines = 0x8000; - cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines); - max_cache_size = cache_line * cache_nlines; - } if (cpu_data(id).mid < 0) panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 4dcd7d0b60f2..40e40f968d61 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1163,32 +1163,6 @@ int setup_profiling_timer(unsigned int multiplier) return -EINVAL; } -static void __init smp_tune_scheduling(void) -{ - unsigned int smallest = ~0U; - int i; - - for (i = 0; i < NR_CPUS; i++) { - unsigned int val = cpu_data(i).ecache_size; - - if (val && val < smallest) - smallest = val; - } - - /* Any value less than 256K is nonsense. */ - if (smallest < (256U * 1024U)) - smallest = 256 * 1024; - - max_cache_size = smallest; - - if (smallest < 1U * 1024U * 1024U) - printk(KERN_INFO "Using max_cache_size of %uKB\n", - smallest / 1024U); - else - printk(KERN_INFO "Using max_cache_size of %uMB\n", - smallest / 1024U / 1024U); -} - /* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { @@ -1206,7 +1180,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; - smp_tune_scheduling(); } void __devinit smp_prepare_boot_cpu(void) diff --git a/include/linux/sched.h b/include/linux/sched.h index 7e74262f98e1..8764cda0feca 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -754,12 +754,6 @@ struct sched_domain { extern int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2); -/* - * Maximum cache size the migration-costs auto-tuning code will - * search from: - */ -extern unsigned int max_cache_size; - #endif /* CONFIG_SMP */ diff --git a/kernel/sched.c b/kernel/sched.c index ac054d9a0719..46b23f0fee24 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5797,483 +5797,6 @@ init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map, #define SD_NODES_PER_DOMAIN 16 -/* - * Self-tuning task migration cost measurement between source and target CPUs. - * - * This is done by measuring the cost of manipulating buffers of varying - * sizes. For a given buffer-size here are the steps that are taken: - * - * 1) the source CPU reads+dirties a shared buffer - * 2) the target CPU reads+dirties the same shared buffer - * - * We measure how long they take, in the following 4 scenarios: - * - * - source: CPU1, target: CPU2 | cost1 - * - source: CPU2, target: CPU1 | cost2 - * - source: CPU1, target: CPU1 | cost3 - * - source: CPU2, target: CPU2 | cost4 - * - * We then calculate the cost3+cost4-cost1-cost2 difference - this is - * the cost of migration. - * - * We then start off from a small buffer-size and iterate up to larger - * buffer sizes, in 5% steps - measuring each buffer-size separately, and - * doing a maximum search for the cost. (The maximum cost for a migration - * normally occurs when the working set size is around the effective cache - * size.) - */ -#define SEARCH_SCOPE 2 -#define MIN_CACHE_SIZE (64*1024U) -#define DEFAULT_CACHE_SIZE (5*1024*1024U) -#define ITERATIONS 1 -#define SIZE_THRESH 130 -#define COST_THRESH 130 - -/* - * The migration cost is a function of 'domain distance'. Domain - * distance is the number of steps a CPU has to iterate down its - * domain tree to share a domain with the other CPU. The farther - * two CPUs are from each other, the larger the distance gets. - * - * Note that we use the distance only to cache measurement results, - * the distance value is not used numerically otherwise. When two - * CPUs have the same distance it is assumed that the migration - * cost is the same. (this is a simplification but quite practical) - */ -#define MAX_DOMAIN_DISTANCE 32 - -static unsigned long long migration_cost[MAX_DOMAIN_DISTANCE] = - { [ 0 ... MAX_DOMAIN_DISTANCE-1 ] = -/* - * Architectures may override the migration cost and thus avoid - * boot-time calibration. Unit is nanoseconds. Mostly useful for - * virtualized hardware: - */ -#ifdef CONFIG_DEFAULT_MIGRATION_COST - CONFIG_DEFAULT_MIGRATION_COST -#else - -1LL -#endif -}; - -/* - * Allow override of migration cost - in units of microseconds. - * E.g. migration_cost=1000,2000,3000 will set up a level-1 cost - * of 1 msec, level-2 cost of 2 msecs and level3 cost of 3 msecs: - */ -static int __init migration_cost_setup(char *str) -{ - int ints[MAX_DOMAIN_DISTANCE+1], i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - printk("#ints: %d\n", ints[0]); - for (i = 1; i <= ints[0]; i++) { - migration_cost[i-1] = (unsigned long long)ints[i]*1000; - printk("migration_cost[%d]: %Ld\n", i-1, migration_cost[i-1]); - } - return 1; -} - -__setup ("migration_cost=", migration_cost_setup); - -/* - * Global multiplier (divisor) for migration-cutoff values, - * in percentiles. E.g. use a value of 150 to get 1.5 times - * longer cache-hot cutoff times. - * - * (We scale it from 100 to 128 to long long handling easier.) - */ - -#define MIGRATION_FACTOR_SCALE 128 - -static unsigned int migration_factor = MIGRATION_FACTOR_SCALE; - -static int __init setup_migration_factor(char *str) -{ - get_option(&str, &migration_factor); - migration_factor = migration_factor * MIGRATION_FACTOR_SCALE / 100; - return 1; -} - -__setup("migration_factor=", setup_migration_factor); - -/* - * Estimated distance of two CPUs, measured via the number of domains - * we have to pass for the two CPUs to be in the same span: - */ -static unsigned long domain_distance(int cpu1, int cpu2) -{ - unsigned long distance = 0; - struct sched_domain *sd; - - for_each_domain(cpu1, sd) { - WARN_ON(!cpu_isset(cpu1, sd->span)); - if (cpu_isset(cpu2, sd->span)) - return distance; - distance++; - } - if (distance >= MAX_DOMAIN_DISTANCE) { - WARN_ON(1); - distance = MAX_DOMAIN_DISTANCE-1; - } - - return distance; -} - -static unsigned int migration_debug; - -static int __init setup_migration_debug(char *str) -{ - get_option(&str, &migration_debug); - return 1; -} - -__setup("migration_debug=", setup_migration_debug); - -/* - * Maximum cache-size that the scheduler should try to measure. - * Architectures with larger caches should tune this up during - * bootup. Gets used in the domain-setup code (i.e. during SMP - * bootup). - */ -unsigned int max_cache_size; - -static int __init setup_max_cache_size(char *str) -{ - get_option(&str, &max_cache_size); - return 1; -} - -__setup("max_cache_size=", setup_max_cache_size); - -/* - * Dirty a big buffer in a hard-to-predict (for the L2 cache) way. This - * is the operation that is timed, so we try to generate unpredictable - * cachemisses that still end up filling the L2 cache: - */ -static void touch_cache(void *__cache, unsigned long __size) -{ - unsigned long size = __size / sizeof(long); - unsigned long chunk1 = size / 3; - unsigned long chunk2 = 2 * size / 3; - unsigned long *cache = __cache; - int i; - - for (i = 0; i < size/6; i += 8) { - switch (i % 6) { - case 0: cache[i]++; - case 1: cache[size-1-i]++; - case 2: cache[chunk1-i]++; - case 3: cache[chunk1+i]++; - case 4: cache[chunk2-i]++; - case 5: cache[chunk2+i]++; - } - } -} - -/* - * Measure the cache-cost of one task migration. Returns in units of nsec. - */ -static unsigned long long -measure_one(void *cache, unsigned long size, int source, int target) -{ - cpumask_t mask, saved_mask; - unsigned long long t0, t1, t2, t3, cost; - - saved_mask = current->cpus_allowed; - - /* - * Flush source caches to RAM and invalidate them: - */ - sched_cacheflush(); - - /* - * Migrate to the source CPU: - */ - mask = cpumask_of_cpu(source); - set_cpus_allowed(current, mask); - WARN_ON(smp_processor_id() != source); - - /* - * Dirty the working set: - */ - t0 = sched_clock(); - touch_cache(cache, size); - t1 = sched_clock(); - - /* - * Migrate to the target CPU, dirty the L2 cache and access - * the shared buffer. (which represents the working set - * of a migrated task.) - */ - mask = cpumask_of_cpu(target); - set_cpus_allowed(current, mask); - WARN_ON(smp_processor_id() != target); - - t2 = sched_clock(); - touch_cache(cache, size); - t3 = sched_clock(); - - cost = t1-t0 + t3-t2; - - if (migration_debug >= 2) - printk("[%d->%d]: %8Ld %8Ld %8Ld => %10Ld.\n", - source, target, t1-t0, t1-t0, t3-t2, cost); - /* - * Flush target caches to RAM and invalidate them: - */ - sched_cacheflush(); - - set_cpus_allowed(current, saved_mask); - - return cost; -} - -/* - * Measure a series of task migrations and return the average - * result. Since this code runs early during bootup the system - * is 'undisturbed' and the average latency makes sense. - * - * The algorithm in essence auto-detects the relevant cache-size, - * so it will properly detect different cachesizes for different - * cache-hierarchies, depending on how the CPUs are connected. - * - * Architectures can prime the upper limit of the search range via - * max_cache_size, otherwise the search range defaults to 20MB...64K. - */ -static unsigned long long -measure_cost(int cpu1, int cpu2, void *cache, unsigned int size) -{ - unsigned long long cost1, cost2; - int i; - - /* - * Measure the migration cost of 'size' bytes, over an - * average of 10 runs: - * - * (We perturb the cache size by a small (0..4k) - * value to compensate size/alignment related artifacts. - * We also subtract the cost of the operation done on - * the same CPU.) - */ - cost1 = 0; - - /* - * dry run, to make sure we start off cache-cold on cpu1, - * and to get any vmalloc pagefaults in advance: - */ - measure_one(cache, size, cpu1, cpu2); - for (i = 0; i < ITERATIONS; i++) - cost1 += measure_one(cache, size - i * 1024, cpu1, cpu2); - - measure_one(cache, size, cpu2, cpu1); - for (i = 0; i < ITERATIONS; i++) - cost1 += measure_one(cache, size - i * 1024, cpu2, cpu1); - - /* - * (We measure the non-migrating [cached] cost on both - * cpu1 and cpu2, to handle CPUs with different speeds) - */ - cost2 = 0; - - measure_one(cache, size, cpu1, cpu1); - for (i = 0; i < ITERATIONS; i++) - cost2 += measure_one(cache, size - i * 1024, cpu1, cpu1); - - measure_one(cache, size, cpu2, cpu2); - for (i = 0; i < ITERATIONS; i++) - cost2 += measure_one(cache, size - i * 1024, cpu2, cpu2); - - /* - * Get the per-iteration migration cost: - */ - do_div(cost1, 2 * ITERATIONS); - do_div(cost2, 2 * ITERATIONS); - - return cost1 - cost2; -} - -static unsigned long long measure_migration_cost(int cpu1, int cpu2) -{ - unsigned long long max_cost = 0, fluct = 0, avg_fluct = 0; - unsigned int max_size, size, size_found = 0; - long long cost = 0, prev_cost; - void *cache; - - /* - * Search from max_cache_size*5 down to 64K - the real relevant - * cachesize has to lie somewhere inbetween. - */ - if (max_cache_size) { - max_size = max(max_cache_size * SEARCH_SCOPE, MIN_CACHE_SIZE); - size = max(max_cache_size / SEARCH_SCOPE, MIN_CACHE_SIZE); - } else { - /* - * Since we have no estimation about the relevant - * search range - */ - max_size = DEFAULT_CACHE_SIZE * SEARCH_SCOPE; - size = MIN_CACHE_SIZE; - } - - if (!cpu_online(cpu1) || !cpu_online(cpu2)) { - printk("cpu %d and %d not both online!\n", cpu1, cpu2); - return 0; - } - - /* - * Allocate the working set: - */ - cache = vmalloc(max_size); - if (!cache) { - printk("could not vmalloc %d bytes for cache!\n", 2 * max_size); - return 1000000; /* return 1 msec on very small boxen */ - } - - while (size <= max_size) { - prev_cost = cost; - cost = measure_cost(cpu1, cpu2, cache, size); - - /* - * Update the max: - */ - if (cost > 0) { - if (max_cost < cost) { - max_cost = cost; - size_found = size; - } - } - /* - * Calculate average fluctuation, we use this to prevent - * noise from triggering an early break out of the loop: - */ - fluct = abs(cost - prev_cost); - avg_fluct = (avg_fluct + fluct)/2; - - if (migration_debug) - printk("-> [%d][%d][%7d] %3ld.%ld [%3ld.%ld] (%ld): " - "(%8Ld %8Ld)\n", - cpu1, cpu2, size, - (long)cost / 1000000, - ((long)cost / 100000) % 10, - (long)max_cost / 1000000, - ((long)max_cost / 100000) % 10, - domain_distance(cpu1, cpu2), - cost, avg_fluct); - - /* - * If we iterated at least 20% past the previous maximum, - * and the cost has dropped by more than 20% already, - * (taking fluctuations into account) then we assume to - * have found the maximum and break out of the loop early: - */ - if (size_found && (size*100 > size_found*SIZE_THRESH)) - if (cost+avg_fluct <= 0 || - max_cost*100 > (cost+avg_fluct)*COST_THRESH) { - - if (migration_debug) - printk("-> found max.\n"); - break; - } - /* - * Increase the cachesize in 10% steps: - */ - size = size * 10 / 9; - } - - if (migration_debug) - printk("[%d][%d] working set size found: %d, cost: %Ld\n", - cpu1, cpu2, size_found, max_cost); - - vfree(cache); - - /* - * A task is considered 'cache cold' if at least 2 times - * the worst-case cost of migration has passed. - * - * (this limit is only listened to if the load-balancing - * situation is 'nice' - if there is a large imbalance we - * ignore it for the sake of CPU utilization and - * processing fairness.) - */ - return 2 * max_cost * migration_factor / MIGRATION_FACTOR_SCALE; -} - -static void calibrate_migration_costs(const cpumask_t *cpu_map) -{ - int cpu1 = -1, cpu2 = -1, cpu, orig_cpu = raw_smp_processor_id(); - unsigned long j0, j1, distance, max_distance = 0; - struct sched_domain *sd; - - j0 = jiffies; - - /* - * First pass - calculate the cacheflush times: - */ - for_each_cpu_mask(cpu1, *cpu_map) { - for_each_cpu_mask(cpu2, *cpu_map) { - if (cpu1 == cpu2) - continue; - distance = domain_distance(cpu1, cpu2); - max_distance = max(max_distance, distance); - /* - * No result cached yet? - */ - if (migration_cost[distance] == -1LL) - migration_cost[distance] = - measure_migration_cost(cpu1, cpu2); - } - } - /* - * Second pass - update the sched domain hierarchy with - * the new cache-hot-time estimations: - */ - for_each_cpu_mask(cpu, *cpu_map) { - distance = 0; - for_each_domain(cpu, sd) { - sd->cache_hot_time = migration_cost[distance]; - distance++; - } - } - /* - * Print the matrix: - */ - if (migration_debug) - printk("migration: max_cache_size: %d, cpu: %d MHz:\n", - max_cache_size, -#ifdef CONFIG_X86 - cpu_khz/1000 -#else - -1 -#endif - ); - if (system_state == SYSTEM_BOOTING && num_online_cpus() > 1) { - printk("migration_cost="); - for (distance = 0; distance <= max_distance; distance++) { - if (distance) - printk(","); - printk("%ld", (long)migration_cost[distance] / 1000); - } - printk("\n"); - } - j1 = jiffies; - if (migration_debug) - printk("migration: %ld seconds\n", (j1-j0) / HZ); - - /* - * Move back to the original CPU. NUMA-Q gets confused - * if we migrate to another quad during bootup. - */ - if (raw_smp_processor_id() != orig_cpu) { - cpumask_t mask = cpumask_of_cpu(orig_cpu), - saved_mask = current->cpus_allowed; - - set_cpus_allowed(current, mask); - set_cpus_allowed(current, saved_mask); - } -} - #ifdef CONFIG_NUMA /** @@ -6803,10 +6326,6 @@ static int build_sched_domains(const cpumask_t *cpu_map) #endif cpu_attach_domain(sd, i); } - /* - * Tune cache-hot values: - */ - calibrate_migration_costs(cpu_map); return 0; From c65cc8705256ad7524c97564b4fe3ca9782bf6d1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 236/551] sched: uninline set_task_cpu() uninline set_task_cpu(): CFS will add more code to it. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 5 +---- kernel/sched.c | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 8764cda0feca..4b912e753ca0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1633,10 +1633,7 @@ static inline unsigned int task_cpu(const struct task_struct *p) return task_thread_info(p)->cpu; } -static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) -{ - task_thread_info(p)->cpu = cpu; -} +extern void set_task_cpu(struct task_struct *p, unsigned int cpu); #else diff --git a/kernel/sched.c b/kernel/sched.c index 46b23f0fee24..d6624978feb2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1111,6 +1111,12 @@ unsigned long weighted_cpuload(const int cpu) } #ifdef CONFIG_SMP + +void set_task_cpu(struct task_struct *p, unsigned int cpu) +{ + task_thread_info(p)->cpu = cpu; +} + struct migration_req { struct list_head list; From f64f61145a38f7039e4f1c0b50dcc3fbe70ec28e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 237/551] sched: remove sched_exit() remove sched_exit(): the elaborate dance of us trying to recover timeslices given to child tasks never really worked. CFS does not need it either. Signed-off-by: Ingo Molnar --- kernel/exit.c | 1 - kernel/sched.c | 31 ------------------------------- 2 files changed, 32 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 5c8ecbaa19a5..6c7699240327 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -182,7 +182,6 @@ repeat: zap_leader = (leader->exit_signal == -1); } - sched_exit(p); write_unlock_irq(&tasklist_lock); proc_flush_task(p); release_thread(p); diff --git a/kernel/sched.c b/kernel/sched.c index d6624978feb2..7090982350d3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1831,37 +1831,6 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags) task_rq_unlock(this_rq, &flags); } -/* - * Potentially available exiting-child timeslices are - * retrieved here - this way the parent does not get - * penalized for creating too many threads. - * - * (this cannot be used to 'generate' timeslices - * artificially, because any timeslice recovered here - * was given away by the parent in the first place.) - */ -void fastcall sched_exit(struct task_struct *p) -{ - unsigned long flags; - struct rq *rq; - - /* - * If the child was a (relative-) CPU hog then decrease - * the sleep_avg of the parent as well. - */ - rq = task_rq_lock(p->parent, &flags); - if (p->first_time_slice && task_cpu(p) == task_cpu(p->parent)) { - p->parent->time_slice += p->time_slice; - if (unlikely(p->parent->time_slice > task_timeslice(p))) - p->parent->time_slice = task_timeslice(p); - } - if (p->sleep_avg < p->parent->sleep_avg) - p->parent->sleep_avg = p->parent->sleep_avg / - (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg / - (EXIT_WEIGHT + 1); - task_rq_unlock(rq, &flags); -} - /** * prepare_task_switch - prepare to switch tasks * @rq: the runqueue preparing to switch From 4da1ce6d9c7e2a6d9236bf4dcfd33cf506082794 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 238/551] sched: add in_atomic_preempt_off() add in_atomic_preempt_off() - debugging helper that will simplify schedule(). Signed-off-by: Ingo Molnar --- include/linux/hardirq.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 7803014f3a11..8d302298a161 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -78,6 +78,19 @@ # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) #endif +#ifdef CONFIG_PREEMPT +# define PREEMPT_CHECK_OFFSET 1 +#else +# define PREEMPT_CHECK_OFFSET 0 +#endif + +/* + * Check whether we were atomic before we did preempt_disable(): + * (used by the scheduler) + */ +#define in_atomic_preempt_off() \ + ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) + #ifdef CONFIG_PREEMPT # define preemptible() (preempt_count() == 0 && !irqs_disabled()) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) From 1df21055e34b6a68d62cf0c524b9e52deebd7ead Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 239/551] sched: add init_idle_bootup_task() add the init_idle_bootup_task() callback to the bootup thread, unused at the moment. (CFS will use it to switch the scheduling class of the boot thread to the idle class) Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 + init/main.c | 5 +++-- kernel/sched.c | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 4b912e753ca0..61a111fe2b7a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -195,6 +195,7 @@ struct task_struct; extern void sched_init(void); extern void sched_init_smp(void); extern void init_idle(struct task_struct *idle, int cpu); +extern void init_idle_bootup_task(struct task_struct *idle); extern cpumask_t nohz_cpu_mask; #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) diff --git a/init/main.c b/init/main.c index eb8bdbae4fc7..0eb1c7463fe4 100644 --- a/init/main.c +++ b/init/main.c @@ -436,15 +436,16 @@ static void noinline __init_refok rest_init(void) /* * The boot idle thread must execute schedule() - * at least one to get things moving: + * at least once to get things moving: */ + init_idle_bootup_task(current); preempt_enable_no_resched(); schedule(); preempt_disable(); /* Call into cpu_idle with preempt disabled */ cpu_idle(); -} +} /* Check for early params. */ static int __init do_early_param(char *param, char *val) diff --git a/kernel/sched.c b/kernel/sched.c index 7090982350d3..ac4d26241d1e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5018,6 +5018,11 @@ void show_state_filter(unsigned long state_filter) debug_show_all_locks(); } +void __cpuinit init_idle_bootup_task(struct task_struct *idle) +{ + /* nothing yet */ +} + /** * init_idle - set up an idle thread for a given CPU * @idle: task in question From 425e0968a25fa3f111f9919964cac079738140b5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 240/551] sched: move code into kernel/sched_stats.h create sched_stats.h and move sched.c schedstats code into it. This cleans up sched.c a bit. no code changes are caused by this patch. Signed-off-by: Ingo Molnar --- kernel/sched.c | 234 +----------------------------------------- kernel/sched_stats.h | 235 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 233 deletions(-) create mode 100644 kernel/sched_stats.h diff --git a/kernel/sched.c b/kernel/sched.c index ac4d26241d1e..f8b8eda4494d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -460,134 +460,6 @@ static inline void task_rq_unlock(struct rq *rq, unsigned long *flags) spin_unlock_irqrestore(&rq->lock, *flags); } -#ifdef CONFIG_SCHEDSTATS -/* - * bump this up when changing the output format or the meaning of an existing - * format, so that tools can adapt (or abort) - */ -#define SCHEDSTAT_VERSION 14 - -static int show_schedstat(struct seq_file *seq, void *v) -{ - int cpu; - - seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION); - seq_printf(seq, "timestamp %lu\n", jiffies); - for_each_online_cpu(cpu) { - struct rq *rq = cpu_rq(cpu); -#ifdef CONFIG_SMP - struct sched_domain *sd; - int dcnt = 0; -#endif - - /* runqueue-specific stats */ - seq_printf(seq, - "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", - cpu, rq->yld_both_empty, - rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt, - rq->sched_switch, rq->sched_cnt, rq->sched_goidle, - rq->ttwu_cnt, rq->ttwu_local, - rq->rq_sched_info.cpu_time, - rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt); - - seq_printf(seq, "\n"); - -#ifdef CONFIG_SMP - /* domain-specific stats */ - preempt_disable(); - for_each_domain(cpu, sd) { - enum cpu_idle_type itype; - char mask_str[NR_CPUS]; - - cpumask_scnprintf(mask_str, NR_CPUS, sd->span); - seq_printf(seq, "domain%d %s", dcnt++, mask_str); - for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES; - itype++) { - seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu " - "%lu", - sd->lb_cnt[itype], - sd->lb_balanced[itype], - sd->lb_failed[itype], - sd->lb_imbalance[itype], - sd->lb_gained[itype], - sd->lb_hot_gained[itype], - sd->lb_nobusyq[itype], - sd->lb_nobusyg[itype]); - } - seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu" - " %lu %lu %lu\n", - sd->alb_cnt, sd->alb_failed, sd->alb_pushed, - sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed, - sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed, - sd->ttwu_wake_remote, sd->ttwu_move_affine, - sd->ttwu_move_balance); - } - preempt_enable(); -#endif - } - return 0; -} - -static int schedstat_open(struct inode *inode, struct file *file) -{ - unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32); - char *buf = kmalloc(size, GFP_KERNEL); - struct seq_file *m; - int res; - - if (!buf) - return -ENOMEM; - res = single_open(file, show_schedstat, NULL); - if (!res) { - m = file->private_data; - m->buf = buf; - m->size = size; - } else - kfree(buf); - return res; -} - -const struct file_operations proc_schedstat_operations = { - .open = schedstat_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * Expects runqueue lock to be held for atomicity of update - */ -static inline void -rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies) -{ - if (rq) { - rq->rq_sched_info.run_delay += delta_jiffies; - rq->rq_sched_info.pcnt++; - } -} - -/* - * Expects runqueue lock to be held for atomicity of update - */ -static inline void -rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies) -{ - if (rq) - rq->rq_sched_info.cpu_time += delta_jiffies; -} -# define schedstat_inc(rq, field) do { (rq)->field++; } while (0) -# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0) -#else /* !CONFIG_SCHEDSTATS */ -static inline void -rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies) -{} -static inline void -rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies) -{} -# define schedstat_inc(rq, field) do { } while (0) -# define schedstat_add(rq, field, amt) do { } while (0) -#endif - /* * this_rq_lock - lock this runqueue and disable interrupts. */ @@ -603,111 +475,7 @@ static inline struct rq *this_rq_lock(void) return rq; } -#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) -/* - * Called when a process is dequeued from the active array and given - * the cpu. We should note that with the exception of interactive - * tasks, the expired queue will become the active queue after the active - * queue is empty, without explicitly dequeuing and requeuing tasks in the - * expired queue. (Interactive tasks may be requeued directly to the - * active queue, thus delaying tasks in the expired queue from running; - * see scheduler_tick()). - * - * This function is only called from sched_info_arrive(), rather than - * dequeue_task(). Even though a task may be queued and dequeued multiple - * times as it is shuffled about, we're really interested in knowing how - * long it was from the *first* time it was queued to the time that it - * finally hit a cpu. - */ -static inline void sched_info_dequeued(struct task_struct *t) -{ - t->sched_info.last_queued = 0; -} - -/* - * Called when a task finally hits the cpu. We can now calculate how - * long it was waiting to run. We also note when it began so that we - * can keep stats on how long its timeslice is. - */ -static void sched_info_arrive(struct task_struct *t) -{ - unsigned long now = jiffies, delta_jiffies = 0; - - if (t->sched_info.last_queued) - delta_jiffies = now - t->sched_info.last_queued; - sched_info_dequeued(t); - t->sched_info.run_delay += delta_jiffies; - t->sched_info.last_arrival = now; - t->sched_info.pcnt++; - - rq_sched_info_arrive(task_rq(t), delta_jiffies); -} - -/* - * Called when a process is queued into either the active or expired - * array. The time is noted and later used to determine how long we - * had to wait for us to reach the cpu. Since the expired queue will - * become the active queue after active queue is empty, without dequeuing - * and requeuing any tasks, we are interested in queuing to either. It - * is unusual but not impossible for tasks to be dequeued and immediately - * requeued in the same or another array: this can happen in sched_yield(), - * set_user_nice(), and even load_balance() as it moves tasks from runqueue - * to runqueue. - * - * This function is only called from enqueue_task(), but also only updates - * the timestamp if it is already not set. It's assumed that - * sched_info_dequeued() will clear that stamp when appropriate. - */ -static inline void sched_info_queued(struct task_struct *t) -{ - if (unlikely(sched_info_on())) - if (!t->sched_info.last_queued) - t->sched_info.last_queued = jiffies; -} - -/* - * Called when a process ceases being the active-running process, either - * voluntarily or involuntarily. Now we can calculate how long we ran. - */ -static inline void sched_info_depart(struct task_struct *t) -{ - unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival; - - t->sched_info.cpu_time += delta_jiffies; - rq_sched_info_depart(task_rq(t), delta_jiffies); -} - -/* - * Called when tasks are switched involuntarily due, typically, to expiring - * their time slice. (This may also be called when switching to or from - * the idle task.) We are only called when prev != next. - */ -static inline void -__sched_info_switch(struct task_struct *prev, struct task_struct *next) -{ - struct rq *rq = task_rq(prev); - - /* - * prev now departs the cpu. It's not interesting to record - * stats about how efficient we were at scheduling the idle - * process, however. - */ - if (prev != rq->idle) - sched_info_depart(prev); - - if (next != rq->idle) - sched_info_arrive(next); -} -static inline void -sched_info_switch(struct task_struct *prev, struct task_struct *next) -{ - if (unlikely(sched_info_on())) - __sched_info_switch(prev, next); -} -#else -#define sched_info_queued(t) do { } while (0) -#define sched_info_switch(t, next) do { } while (0) -#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */ +#include "sched_stats.h" /* * Adding/removing a task to/from a priority array: diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h new file mode 100644 index 000000000000..cd82c6078904 --- /dev/null +++ b/kernel/sched_stats.h @@ -0,0 +1,235 @@ + +#ifdef CONFIG_SCHEDSTATS +/* + * bump this up when changing the output format or the meaning of an existing + * format, so that tools can adapt (or abort) + */ +#define SCHEDSTAT_VERSION 14 + +static int show_schedstat(struct seq_file *seq, void *v) +{ + int cpu; + + seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION); + seq_printf(seq, "timestamp %lu\n", jiffies); + for_each_online_cpu(cpu) { + struct rq *rq = cpu_rq(cpu); +#ifdef CONFIG_SMP + struct sched_domain *sd; + int dcnt = 0; +#endif + + /* runqueue-specific stats */ + seq_printf(seq, + "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + cpu, rq->yld_both_empty, + rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt, + rq->sched_switch, rq->sched_cnt, rq->sched_goidle, + rq->ttwu_cnt, rq->ttwu_local, + rq->rq_sched_info.cpu_time, + rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt); + + seq_printf(seq, "\n"); + +#ifdef CONFIG_SMP + /* domain-specific stats */ + preempt_disable(); + for_each_domain(cpu, sd) { + enum cpu_idle_type itype; + char mask_str[NR_CPUS]; + + cpumask_scnprintf(mask_str, NR_CPUS, sd->span); + seq_printf(seq, "domain%d %s", dcnt++, mask_str); + for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES; + itype++) { + seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu " + "%lu", + sd->lb_cnt[itype], + sd->lb_balanced[itype], + sd->lb_failed[itype], + sd->lb_imbalance[itype], + sd->lb_gained[itype], + sd->lb_hot_gained[itype], + sd->lb_nobusyq[itype], + sd->lb_nobusyg[itype]); + } + seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu" + " %lu %lu %lu\n", + sd->alb_cnt, sd->alb_failed, sd->alb_pushed, + sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed, + sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed, + sd->ttwu_wake_remote, sd->ttwu_move_affine, + sd->ttwu_move_balance); + } + preempt_enable(); +#endif + } + return 0; +} + +static int schedstat_open(struct inode *inode, struct file *file) +{ + unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32); + char *buf = kmalloc(size, GFP_KERNEL); + struct seq_file *m; + int res; + + if (!buf) + return -ENOMEM; + res = single_open(file, show_schedstat, NULL); + if (!res) { + m = file->private_data; + m->buf = buf; + m->size = size; + } else + kfree(buf); + return res; +} + +const struct file_operations proc_schedstat_operations = { + .open = schedstat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Expects runqueue lock to be held for atomicity of update + */ +static inline void +rq_sched_info_arrive(struct rq *rq, unsigned long long delta) +{ + if (rq) { + rq->rq_sched_info.run_delay += delta; + rq->rq_sched_info.pcnt++; + } +} + +/* + * Expects runqueue lock to be held for atomicity of update + */ +static inline void +rq_sched_info_depart(struct rq *rq, unsigned long long delta) +{ + if (rq) + rq->rq_sched_info.cpu_time += delta; +} +# define schedstat_inc(rq, field) do { (rq)->field++; } while (0) +# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0) +#else /* !CONFIG_SCHEDSTATS */ +static inline void +rq_sched_info_arrive(struct rq *rq, unsigned long long delta) +{} +static inline void +rq_sched_info_depart(struct rq *rq, unsigned long long delta) +{} +# define schedstat_inc(rq, field) do { } while (0) +# define schedstat_add(rq, field, amt) do { } while (0) +#endif + +#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) +/* + * Called when a process is dequeued from the active array and given + * the cpu. We should note that with the exception of interactive + * tasks, the expired queue will become the active queue after the active + * queue is empty, without explicitly dequeuing and requeuing tasks in the + * expired queue. (Interactive tasks may be requeued directly to the + * active queue, thus delaying tasks in the expired queue from running; + * see scheduler_tick()). + * + * This function is only called from sched_info_arrive(), rather than + * dequeue_task(). Even though a task may be queued and dequeued multiple + * times as it is shuffled about, we're really interested in knowing how + * long it was from the *first* time it was queued to the time that it + * finally hit a cpu. + */ +static inline void sched_info_dequeued(struct task_struct *t) +{ + t->sched_info.last_queued = 0; +} + +/* + * Called when a task finally hits the cpu. We can now calculate how + * long it was waiting to run. We also note when it began so that we + * can keep stats on how long its timeslice is. + */ +static void sched_info_arrive(struct task_struct *t) +{ + unsigned long long now = sched_clock(), delta = 0; + + if (t->sched_info.last_queued) + delta = now - t->sched_info.last_queued; + sched_info_dequeued(t); + t->sched_info.run_delay += delta; + t->sched_info.last_arrival = now; + t->sched_info.pcnt++; + + rq_sched_info_arrive(task_rq(t), delta); +} + +/* + * Called when a process is queued into either the active or expired + * array. The time is noted and later used to determine how long we + * had to wait for us to reach the cpu. Since the expired queue will + * become the active queue after active queue is empty, without dequeuing + * and requeuing any tasks, we are interested in queuing to either. It + * is unusual but not impossible for tasks to be dequeued and immediately + * requeued in the same or another array: this can happen in sched_yield(), + * set_user_nice(), and even load_balance() as it moves tasks from runqueue + * to runqueue. + * + * This function is only called from enqueue_task(), but also only updates + * the timestamp if it is already not set. It's assumed that + * sched_info_dequeued() will clear that stamp when appropriate. + */ +static inline void sched_info_queued(struct task_struct *t) +{ + if (unlikely(sched_info_on())) + if (!t->sched_info.last_queued) + t->sched_info.last_queued = sched_clock(); +} + +/* + * Called when a process ceases being the active-running process, either + * voluntarily or involuntarily. Now we can calculate how long we ran. + */ +static inline void sched_info_depart(struct task_struct *t) +{ + unsigned long long delta = sched_clock() - t->sched_info.last_arrival; + + t->sched_info.cpu_time += delta; + rq_sched_info_depart(task_rq(t), delta); +} + +/* + * Called when tasks are switched involuntarily due, typically, to expiring + * their time slice. (This may also be called when switching to or from + * the idle task.) We are only called when prev != next. + */ +static inline void +__sched_info_switch(struct task_struct *prev, struct task_struct *next) +{ + struct rq *rq = task_rq(prev); + + /* + * prev now departs the cpu. It's not interesting to record + * stats about how efficient we were at scheduling the idle + * process, however. + */ + if (prev != rq->idle) + sched_info_depart(prev); + + if (next != rq->idle) + sched_info_arrive(next); +} +static inline void +sched_info_switch(struct task_struct *prev, struct task_struct *next) +{ + if (unlikely(sched_info_on())) + __sched_info_switch(prev, next); +} +#else +#define sched_info_queued(t) do { } while (0) +#define sched_info_switch(t, next) do { } while (0) +#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */ + From 9aa7b369819940cb1f3c74ba210516739a32ad95 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 241/551] sched: increase the resolution of smpnice increase SMP-nice's resolution. This is needed by CFS to implement SCHED_IDLE and cleaned up nice level support. no behavioral changes. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 61a111fe2b7a..d5084e7c48cf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -652,7 +652,14 @@ enum cpu_idle_type { /* * sched-domains (multiprocessor balancing) declarations: */ -#define SCHED_LOAD_SCALE 128UL /* increase resolution of load */ + +/* + * Increase resolution of nice-level calculations: + */ +#define SCHED_LOAD_SHIFT 10 +#define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) + +#define SCHED_LOAD_SCALE_FUZZ (SCHED_LOAD_SCALE >> 5) #ifdef CONFIG_SMP #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ From bf0f6f24a1ece8988b243aefe84ee613099a9245 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 242/551] sched: cfs core, kernel/sched_fair.c add kernel/sched_fair.c - which implements the bulk of CFS's behavioral changes for SCHED_OTHER tasks. see Documentation/sched-design-CFS.txt about details. Authors: Ingo Molnar Dmitry Adamushko Srivatsa Vaddagiri Mike Galbraith Signed-off-by: Ingo Molnar Signed-off-by: Mike Galbraith Signed-off-by: Dmitry Adamushko Signed-off-by: Srivatsa Vaddagiri --- include/linux/sched.h | 8 + kernel/sched_fair.c | 1131 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1139 insertions(+) create mode 100644 kernel/sched_fair.c diff --git a/include/linux/sched.h b/include/linux/sched.h index d5084e7c48cf..90420321994f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1243,6 +1243,14 @@ static inline void idle_task_exit(void) {} extern void sched_idle_next(void); +extern unsigned int sysctl_sched_granularity; +extern unsigned int sysctl_sched_wakeup_granularity; +extern unsigned int sysctl_sched_batch_wakeup_granularity; +extern unsigned int sysctl_sched_stat_granularity; +extern unsigned int sysctl_sched_runtime_limit; +extern unsigned int sysctl_sched_child_runs_first; +extern unsigned int sysctl_sched_features; + #ifdef CONFIG_RT_MUTEXES extern int rt_mutex_getprio(struct task_struct *p); extern void rt_mutex_setprio(struct task_struct *p, int prio); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c new file mode 100644 index 000000000000..6971db0a7160 --- /dev/null +++ b/kernel/sched_fair.c @@ -0,0 +1,1131 @@ +/* + * Completely Fair Scheduling (CFS) Class (SCHED_NORMAL/SCHED_BATCH) + * + * Copyright (C) 2007 Red Hat, Inc., Ingo Molnar + * + * Interactivity improvements by Mike Galbraith + * (C) 2007 Mike Galbraith + * + * Various enhancements by Dmitry Adamushko. + * (C) 2007 Dmitry Adamushko + * + * Group scheduling enhancements by Srivatsa Vaddagiri + * Copyright IBM Corporation, 2007 + * Author: Srivatsa Vaddagiri + * + * Scaled math optimizations by Thomas Gleixner + * Copyright (C) 2007, Thomas Gleixner + */ + +/* + * Preemption granularity: + * (default: 2 msec, units: nanoseconds) + * + * NOTE: this granularity value is not the same as the concept of + * 'timeslice length' - timeslices in CFS will typically be somewhat + * larger than this value. (to see the precise effective timeslice + * length of your workload, run vmstat and monitor the context-switches + * field) + * + * On SMP systems the value of this is multiplied by the log2 of the + * number of CPUs. (i.e. factor 2x on 2-way systems, 3x on 4-way + * systems, 4x on 8-way systems, 5x on 16-way systems, etc.) + */ +unsigned int sysctl_sched_granularity __read_mostly = 2000000000ULL/HZ; + +/* + * SCHED_BATCH wake-up granularity. + * (default: 10 msec, units: nanoseconds) + * + * This option delays the preemption effects of decoupled workloads + * and reduces their over-scheduling. Synchronous workloads will still + * have immediate wakeup/sleep latencies. + */ +unsigned int sysctl_sched_batch_wakeup_granularity __read_mostly = + 10000000000ULL/HZ; + +/* + * SCHED_OTHER wake-up granularity. + * (default: 1 msec, units: nanoseconds) + * + * This option delays the preemption effects of decoupled workloads + * and reduces their over-scheduling. Synchronous workloads will still + * have immediate wakeup/sleep latencies. + */ +unsigned int sysctl_sched_wakeup_granularity __read_mostly = 1000000000ULL/HZ; + +unsigned int sysctl_sched_stat_granularity __read_mostly; + +/* + * Initialized in sched_init_granularity(): + */ +unsigned int sysctl_sched_runtime_limit __read_mostly; + +/* + * Debugging: various feature bits + */ +enum { + SCHED_FEAT_FAIR_SLEEPERS = 1, + SCHED_FEAT_SLEEPER_AVG = 2, + SCHED_FEAT_SLEEPER_LOAD_AVG = 4, + SCHED_FEAT_PRECISE_CPU_LOAD = 8, + SCHED_FEAT_START_DEBIT = 16, + SCHED_FEAT_SKIP_INITIAL = 32, +}; + +unsigned int sysctl_sched_features __read_mostly = + SCHED_FEAT_FAIR_SLEEPERS *1 | + SCHED_FEAT_SLEEPER_AVG *1 | + SCHED_FEAT_SLEEPER_LOAD_AVG *1 | + SCHED_FEAT_PRECISE_CPU_LOAD *1 | + SCHED_FEAT_START_DEBIT *1 | + SCHED_FEAT_SKIP_INITIAL *0; + +extern struct sched_class fair_sched_class; + +/************************************************************** + * CFS operations on generic schedulable entities: + */ + +#ifdef CONFIG_FAIR_GROUP_SCHED + +/* cpu runqueue to which this cfs_rq is attached */ +static inline struct rq *rq_of(struct cfs_rq *cfs_rq) +{ + return cfs_rq->rq; +} + +/* currently running entity (if any) on this cfs_rq */ +static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq) +{ + return cfs_rq->curr; +} + +/* An entity is a task if it doesn't "own" a runqueue */ +#define entity_is_task(se) (!se->my_q) + +static inline void +set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se) +{ + cfs_rq->curr = se; +} + +#else /* CONFIG_FAIR_GROUP_SCHED */ + +static inline struct rq *rq_of(struct cfs_rq *cfs_rq) +{ + return container_of(cfs_rq, struct rq, cfs); +} + +static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq) +{ + struct rq *rq = rq_of(cfs_rq); + + if (unlikely(rq->curr->sched_class != &fair_sched_class)) + return NULL; + + return &rq->curr->se; +} + +#define entity_is_task(se) 1 + +static inline void +set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se) { } + +#endif /* CONFIG_FAIR_GROUP_SCHED */ + +static inline struct task_struct *task_of(struct sched_entity *se) +{ + return container_of(se, struct task_struct, se); +} + + +/************************************************************** + * Scheduling class tree data structure manipulation methods: + */ + +/* + * Enqueue an entity into the rb-tree: + */ +static inline void +__enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) +{ + struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; + struct rb_node *parent = NULL; + struct sched_entity *entry; + s64 key = se->fair_key; + int leftmost = 1; + + /* + * Find the right place in the rbtree: + */ + while (*link) { + parent = *link; + entry = rb_entry(parent, struct sched_entity, run_node); + /* + * We dont care about collisions. Nodes with + * the same key stay together. + */ + if (key - entry->fair_key < 0) { + link = &parent->rb_left; + } else { + link = &parent->rb_right; + leftmost = 0; + } + } + + /* + * Maintain a cache of leftmost tree entries (it is frequently + * used): + */ + if (leftmost) + cfs_rq->rb_leftmost = &se->run_node; + + rb_link_node(&se->run_node, parent, link); + rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); + update_load_add(&cfs_rq->load, se->load.weight); + cfs_rq->nr_running++; + se->on_rq = 1; +} + +static inline void +__dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) +{ + if (cfs_rq->rb_leftmost == &se->run_node) + cfs_rq->rb_leftmost = rb_next(&se->run_node); + rb_erase(&se->run_node, &cfs_rq->tasks_timeline); + update_load_sub(&cfs_rq->load, se->load.weight); + cfs_rq->nr_running--; + se->on_rq = 0; +} + +static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq) +{ + return cfs_rq->rb_leftmost; +} + +static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) +{ + return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node); +} + +/************************************************************** + * Scheduling class statistics methods: + */ + +/* + * We rescale the rescheduling granularity of tasks according to their + * nice level, but only linearly, not exponentially: + */ +static long +niced_granularity(struct sched_entity *curr, unsigned long granularity) +{ + u64 tmp; + + /* + * Negative nice levels get the same granularity as nice-0: + */ + if (likely(curr->load.weight >= NICE_0_LOAD)) + return granularity; + /* + * Positive nice level tasks get linearly finer + * granularity: + */ + tmp = curr->load.weight * (u64)granularity; + + /* + * It will always fit into 'long': + */ + return (long) (tmp >> NICE_0_SHIFT); +} + +static inline void +limit_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se) +{ + long limit = sysctl_sched_runtime_limit; + + /* + * Niced tasks have the same history dynamic range as + * non-niced tasks: + */ + if (unlikely(se->wait_runtime > limit)) { + se->wait_runtime = limit; + schedstat_inc(se, wait_runtime_overruns); + schedstat_inc(cfs_rq, wait_runtime_overruns); + } + if (unlikely(se->wait_runtime < -limit)) { + se->wait_runtime = -limit; + schedstat_inc(se, wait_runtime_underruns); + schedstat_inc(cfs_rq, wait_runtime_underruns); + } +} + +static inline void +__add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta) +{ + se->wait_runtime += delta; + schedstat_add(se, sum_wait_runtime, delta); + limit_wait_runtime(cfs_rq, se); +} + +static void +add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta) +{ + schedstat_add(cfs_rq, wait_runtime, -se->wait_runtime); + __add_wait_runtime(cfs_rq, se, delta); + schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); +} + +/* + * Update the current task's runtime statistics. Skip current tasks that + * are not in our scheduling class. + */ +static inline void +__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now) +{ + unsigned long delta, delta_exec, delta_fair; + long delta_mine; + struct load_weight *lw = &cfs_rq->load; + unsigned long load = lw->weight; + + if (unlikely(!load)) + return; + + delta_exec = curr->delta_exec; +#ifdef CONFIG_SCHEDSTATS + if (unlikely(delta_exec > curr->exec_max)) + curr->exec_max = delta_exec; +#endif + + curr->sum_exec_runtime += delta_exec; + cfs_rq->exec_clock += delta_exec; + + delta_fair = calc_delta_fair(delta_exec, lw); + delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw); + + if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) { + delta = calc_delta_mine(cfs_rq->sleeper_bonus, + curr->load.weight, lw); + if (unlikely(delta > cfs_rq->sleeper_bonus)) + delta = cfs_rq->sleeper_bonus; + + cfs_rq->sleeper_bonus -= delta; + delta_mine -= delta; + } + + cfs_rq->fair_clock += delta_fair; + /* + * We executed delta_exec amount of time on the CPU, + * but we were only entitled to delta_mine amount of + * time during that period (if nr_running == 1 then + * the two values are equal) + * [Note: delta_mine - delta_exec is negative]: + */ + add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec); +} + +static void update_curr(struct cfs_rq *cfs_rq, u64 now) +{ + struct sched_entity *curr = cfs_rq_curr(cfs_rq); + unsigned long delta_exec; + + if (unlikely(!curr)) + return; + + /* + * Get the amount of time the current task was running + * since the last time we changed load (this cannot + * overflow on 32 bits): + */ + delta_exec = (unsigned long)(now - curr->exec_start); + + curr->delta_exec += delta_exec; + + if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) { + __update_curr(cfs_rq, curr, now); + curr->delta_exec = 0; + } + curr->exec_start = now; +} + +static inline void +update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + se->wait_start_fair = cfs_rq->fair_clock; + se->wait_start = now; +} + +/* + * We calculate fair deltas here, so protect against the random effects + * of a multiplication overflow by capping it to the runtime limit: + */ +#if BITS_PER_LONG == 32 +static inline unsigned long +calc_weighted(unsigned long delta, unsigned long weight, int shift) +{ + u64 tmp = (u64)delta * weight >> shift; + + if (unlikely(tmp > sysctl_sched_runtime_limit*2)) + return sysctl_sched_runtime_limit*2; + return tmp; +} +#else +static inline unsigned long +calc_weighted(unsigned long delta, unsigned long weight, int shift) +{ + return delta * weight >> shift; +} +#endif + +/* + * Task is being enqueued - update stats: + */ +static void +update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + s64 key; + + /* + * Are we enqueueing a waiting task? (for current tasks + * a dequeue/enqueue event is a NOP) + */ + if (se != cfs_rq_curr(cfs_rq)) + update_stats_wait_start(cfs_rq, se, now); + /* + * Update the key: + */ + key = cfs_rq->fair_clock; + + /* + * Optimize the common nice 0 case: + */ + if (likely(se->load.weight == NICE_0_LOAD)) { + key -= se->wait_runtime; + } else { + u64 tmp; + + if (se->wait_runtime < 0) { + tmp = -se->wait_runtime; + key += (tmp * se->load.inv_weight) >> + (WMULT_SHIFT - NICE_0_SHIFT); + } else { + tmp = se->wait_runtime; + key -= (tmp * se->load.weight) >> NICE_0_SHIFT; + } + } + + se->fair_key = key; +} + +/* + * Note: must be called with a freshly updated rq->fair_clock. + */ +static inline void +__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + unsigned long delta_fair = se->delta_fair_run; + +#ifdef CONFIG_SCHEDSTATS + { + s64 delta_wait = now - se->wait_start; + if (unlikely(delta_wait > se->wait_max)) + se->wait_max = delta_wait; + } +#endif + + if (unlikely(se->load.weight != NICE_0_LOAD)) + delta_fair = calc_weighted(delta_fair, se->load.weight, + NICE_0_SHIFT); + + add_wait_runtime(cfs_rq, se, delta_fair); +} + +static void +update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + unsigned long delta_fair; + + delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit), + (u64)(cfs_rq->fair_clock - se->wait_start_fair)); + + se->delta_fair_run += delta_fair; + if (unlikely(abs(se->delta_fair_run) >= + sysctl_sched_stat_granularity)) { + __update_stats_wait_end(cfs_rq, se, now); + se->delta_fair_run = 0; + } + + se->wait_start_fair = 0; + se->wait_start = 0; +} + +static inline void +update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + update_curr(cfs_rq, now); + /* + * Mark the end of the wait period if dequeueing a + * waiting task: + */ + if (se != cfs_rq_curr(cfs_rq)) + update_stats_wait_end(cfs_rq, se, now); +} + +/* + * We are picking a new current task - update its stats: + */ +static inline void +update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + /* + * We are starting a new run period: + */ + se->exec_start = now; +} + +/* + * We are descheduling a task - update its stats: + */ +static inline void +update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + se->exec_start = 0; +} + +/************************************************** + * Scheduling class queueing methods: + */ + +static void +__enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + unsigned long load = cfs_rq->load.weight, delta_fair; + long prev_runtime; + + if (sysctl_sched_features & SCHED_FEAT_SLEEPER_LOAD_AVG) + load = rq_of(cfs_rq)->cpu_load[2]; + + delta_fair = se->delta_fair_sleep; + + /* + * Fix up delta_fair with the effect of us running + * during the whole sleep period: + */ + if (sysctl_sched_features & SCHED_FEAT_SLEEPER_AVG) + delta_fair = div64_likely32((u64)delta_fair * load, + load + se->load.weight); + + if (unlikely(se->load.weight != NICE_0_LOAD)) + delta_fair = calc_weighted(delta_fair, se->load.weight, + NICE_0_SHIFT); + + prev_runtime = se->wait_runtime; + __add_wait_runtime(cfs_rq, se, delta_fair); + delta_fair = se->wait_runtime - prev_runtime; + + /* + * Track the amount of bonus we've given to sleepers: + */ + cfs_rq->sleeper_bonus += delta_fair; + + schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); +} + +static void +enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + struct task_struct *tsk = task_of(se); + unsigned long delta_fair; + + if ((entity_is_task(se) && tsk->policy == SCHED_BATCH) || + !(sysctl_sched_features & SCHED_FEAT_FAIR_SLEEPERS)) + return; + + delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit), + (u64)(cfs_rq->fair_clock - se->sleep_start_fair)); + + se->delta_fair_sleep += delta_fair; + if (unlikely(abs(se->delta_fair_sleep) >= + sysctl_sched_stat_granularity)) { + __enqueue_sleeper(cfs_rq, se, now); + se->delta_fair_sleep = 0; + } + + se->sleep_start_fair = 0; + +#ifdef CONFIG_SCHEDSTATS + if (se->sleep_start) { + u64 delta = now - se->sleep_start; + + if ((s64)delta < 0) + delta = 0; + + if (unlikely(delta > se->sleep_max)) + se->sleep_max = delta; + + se->sleep_start = 0; + se->sum_sleep_runtime += delta; + } + if (se->block_start) { + u64 delta = now - se->block_start; + + if ((s64)delta < 0) + delta = 0; + + if (unlikely(delta > se->block_max)) + se->block_max = delta; + + se->block_start = 0; + se->sum_sleep_runtime += delta; + } +#endif +} + +static void +enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, + int wakeup, u64 now) +{ + /* + * Update the fair clock. + */ + update_curr(cfs_rq, now); + + if (wakeup) + enqueue_sleeper(cfs_rq, se, now); + + update_stats_enqueue(cfs_rq, se, now); + __enqueue_entity(cfs_rq, se); +} + +static void +dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, + int sleep, u64 now) +{ + update_stats_dequeue(cfs_rq, se, now); + if (sleep) { + se->sleep_start_fair = cfs_rq->fair_clock; +#ifdef CONFIG_SCHEDSTATS + if (entity_is_task(se)) { + struct task_struct *tsk = task_of(se); + + if (tsk->state & TASK_INTERRUPTIBLE) + se->sleep_start = now; + if (tsk->state & TASK_UNINTERRUPTIBLE) + se->block_start = now; + } + cfs_rq->wait_runtime -= se->wait_runtime; +#endif + } + __dequeue_entity(cfs_rq, se); +} + +/* + * Preempt the current task with a newly woken task if needed: + */ +static void +__check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se, + struct sched_entity *curr, unsigned long granularity) +{ + s64 __delta = curr->fair_key - se->fair_key; + + /* + * Take scheduling granularity into account - do not + * preempt the current task unless the best task has + * a larger than sched_granularity fairness advantage: + */ + if (__delta > niced_granularity(curr, granularity)) + resched_task(rq_of(cfs_rq)->curr); +} + +static inline void +set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) +{ + /* + * Any task has to be enqueued before it get to execute on + * a CPU. So account for the time it spent waiting on the + * runqueue. (note, here we rely on pick_next_task() having + * done a put_prev_task_fair() shortly before this, which + * updated rq->fair_clock - used by update_stats_wait_end()) + */ + update_stats_wait_end(cfs_rq, se, now); + update_stats_curr_start(cfs_rq, se, now); + set_cfs_rq_curr(cfs_rq, se); +} + +static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now) +{ + struct sched_entity *se = __pick_next_entity(cfs_rq); + + set_next_entity(cfs_rq, se, now); + + return se; +} + +static void +put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now) +{ + /* + * If still on the runqueue then deactivate_task() + * was not called and update_curr() has to be done: + */ + if (prev->on_rq) + update_curr(cfs_rq, now); + + update_stats_curr_end(cfs_rq, prev, now); + + if (prev->on_rq) + update_stats_wait_start(cfs_rq, prev, now); + set_cfs_rq_curr(cfs_rq, NULL); +} + +static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) +{ + struct rq *rq = rq_of(cfs_rq); + struct sched_entity *next; + u64 now = __rq_clock(rq); + + /* + * Dequeue and enqueue the task to update its + * position within the tree: + */ + dequeue_entity(cfs_rq, curr, 0, now); + enqueue_entity(cfs_rq, curr, 0, now); + + /* + * Reschedule if another task tops the current one. + */ + next = __pick_next_entity(cfs_rq); + if (next == curr) + return; + + __check_preempt_curr_fair(cfs_rq, next, curr, sysctl_sched_granularity); +} + +/************************************************** + * CFS operations on tasks: + */ + +#ifdef CONFIG_FAIR_GROUP_SCHED + +/* Walk up scheduling entities hierarchy */ +#define for_each_sched_entity(se) \ + for (; se; se = se->parent) + +static inline struct cfs_rq *task_cfs_rq(struct task_struct *p) +{ + return p->se.cfs_rq; +} + +/* runqueue on which this entity is (to be) queued */ +static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se) +{ + return se->cfs_rq; +} + +/* runqueue "owned" by this group */ +static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) +{ + return grp->my_q; +} + +/* Given a group's cfs_rq on one cpu, return its corresponding cfs_rq on + * another cpu ('this_cpu') + */ +static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu) +{ + /* A later patch will take group into account */ + return &cpu_rq(this_cpu)->cfs; +} + +/* Iterate thr' all leaf cfs_rq's on a runqueue */ +#define for_each_leaf_cfs_rq(rq, cfs_rq) \ + list_for_each_entry(cfs_rq, &rq->leaf_cfs_rq_list, leaf_cfs_rq_list) + +/* Do the two (enqueued) tasks belong to the same group ? */ +static inline int is_same_group(struct task_struct *curr, struct task_struct *p) +{ + if (curr->se.cfs_rq == p->se.cfs_rq) + return 1; + + return 0; +} + +#else /* CONFIG_FAIR_GROUP_SCHED */ + +#define for_each_sched_entity(se) \ + for (; se; se = NULL) + +static inline struct cfs_rq *task_cfs_rq(struct task_struct *p) +{ + return &task_rq(p)->cfs; +} + +static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se) +{ + struct task_struct *p = task_of(se); + struct rq *rq = task_rq(p); + + return &rq->cfs; +} + +/* runqueue "owned" by this group */ +static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) +{ + return NULL; +} + +static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu) +{ + return &cpu_rq(this_cpu)->cfs; +} + +#define for_each_leaf_cfs_rq(rq, cfs_rq) \ + for (cfs_rq = &rq->cfs; cfs_rq; cfs_rq = NULL) + +static inline int is_same_group(struct task_struct *curr, struct task_struct *p) +{ + return 1; +} + +#endif /* CONFIG_FAIR_GROUP_SCHED */ + +/* + * The enqueue_task method is called before nr_running is + * increased. Here we update the fair scheduling stats and + * then put the task into the rbtree: + */ +static void +enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now) +{ + struct cfs_rq *cfs_rq; + struct sched_entity *se = &p->se; + + for_each_sched_entity(se) { + if (se->on_rq) + break; + cfs_rq = cfs_rq_of(se); + enqueue_entity(cfs_rq, se, wakeup, now); + } +} + +/* + * The dequeue_task method is called before nr_running is + * decreased. We remove the task from the rbtree and + * update the fair scheduling stats: + */ +static void +dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now) +{ + struct cfs_rq *cfs_rq; + struct sched_entity *se = &p->se; + + for_each_sched_entity(se) { + cfs_rq = cfs_rq_of(se); + dequeue_entity(cfs_rq, se, sleep, now); + /* Don't dequeue parent if it has other entities besides us */ + if (cfs_rq->load.weight) + break; + } +} + +/* + * sched_yield() support is very simple - we dequeue and enqueue + */ +static void yield_task_fair(struct rq *rq, struct task_struct *p) +{ + struct cfs_rq *cfs_rq = task_cfs_rq(p); + u64 now = __rq_clock(rq); + + /* + * Dequeue and enqueue the task to update its + * position within the tree: + */ + dequeue_entity(cfs_rq, &p->se, 0, now); + enqueue_entity(cfs_rq, &p->se, 0, now); +} + +/* + * Preempt the current task with a newly woken task if needed: + */ +static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p) +{ + struct task_struct *curr = rq->curr; + struct cfs_rq *cfs_rq = task_cfs_rq(curr); + unsigned long gran; + + if (unlikely(rt_prio(p->prio))) { + update_curr(cfs_rq, rq_clock(rq)); + resched_task(curr); + return; + } + + gran = sysctl_sched_wakeup_granularity; + /* + * Batch tasks prefer throughput over latency: + */ + if (unlikely(p->policy == SCHED_BATCH)) + gran = sysctl_sched_batch_wakeup_granularity; + + if (is_same_group(curr, p)) + __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran); +} + +static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now) +{ + struct cfs_rq *cfs_rq = &rq->cfs; + struct sched_entity *se; + + if (unlikely(!cfs_rq->nr_running)) + return NULL; + + do { + se = pick_next_entity(cfs_rq, now); + cfs_rq = group_cfs_rq(se); + } while (cfs_rq); + + return task_of(se); +} + +/* + * Account for a descheduled task: + */ +static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now) +{ + struct sched_entity *se = &prev->se; + struct cfs_rq *cfs_rq; + + for_each_sched_entity(se) { + cfs_rq = cfs_rq_of(se); + put_prev_entity(cfs_rq, se, now); + } +} + +/************************************************** + * Fair scheduling class load-balancing methods: + */ + +/* + * Load-balancing iterator. Note: while the runqueue stays locked + * during the whole iteration, the current task might be + * dequeued so the iterator has to be dequeue-safe. Here we + * achieve that by always pre-iterating before returning + * the current task: + */ +static inline struct task_struct * +__load_balance_iterator(struct cfs_rq *cfs_rq, struct rb_node *curr) +{ + struct task_struct *p; + + if (!curr) + return NULL; + + p = rb_entry(curr, struct task_struct, se.run_node); + cfs_rq->rb_load_balance_curr = rb_next(curr); + + return p; +} + +static struct task_struct *load_balance_start_fair(void *arg) +{ + struct cfs_rq *cfs_rq = arg; + + return __load_balance_iterator(cfs_rq, first_fair(cfs_rq)); +} + +static struct task_struct *load_balance_next_fair(void *arg) +{ + struct cfs_rq *cfs_rq = arg; + + return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); +} + +static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) +{ + struct sched_entity *curr; + struct task_struct *p; + + if (!cfs_rq->nr_running) + return MAX_PRIO; + + curr = __pick_next_entity(cfs_rq); + p = task_of(curr); + + return p->prio; +} + +static int +load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *total_load_moved) +{ + struct cfs_rq *busy_cfs_rq; + unsigned long load_moved, total_nr_moved = 0, nr_moved; + long rem_load_move = max_load_move; + struct rq_iterator cfs_rq_iterator; + + cfs_rq_iterator.start = load_balance_start_fair; + cfs_rq_iterator.next = load_balance_next_fair; + + for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { + struct cfs_rq *this_cfs_rq; + long imbalance; + unsigned long maxload; + int this_best_prio, best_prio, best_prio_seen = 0; + + this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); + + imbalance = busy_cfs_rq->load.weight - + this_cfs_rq->load.weight; + /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ + if (imbalance <= 0) + continue; + + /* Don't pull more than imbalance/2 */ + imbalance /= 2; + maxload = min(rem_load_move, imbalance); + + this_best_prio = cfs_rq_best_prio(this_cfs_rq); + best_prio = cfs_rq_best_prio(busy_cfs_rq); + + /* + * Enable handling of the case where there is more than one task + * with the best priority. If the current running task is one + * of those with prio==best_prio we know it won't be moved + * and therefore it's safe to override the skip (based on load) + * of any task we find with that prio. + */ + if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se) + best_prio_seen = 1; + + /* pass busy_cfs_rq argument into + * load_balance_[start|next]_fair iterators + */ + cfs_rq_iterator.arg = busy_cfs_rq; + nr_moved = balance_tasks(this_rq, this_cpu, busiest, + max_nr_move, maxload, sd, idle, all_pinned, + &load_moved, this_best_prio, best_prio, + best_prio_seen, &cfs_rq_iterator); + + total_nr_moved += nr_moved; + max_nr_move -= nr_moved; + rem_load_move -= load_moved; + + if (max_nr_move <= 0 || rem_load_move <= 0) + break; + } + + *total_load_moved = max_load_move - rem_load_move; + + return total_nr_moved; +} + +/* + * scheduler tick hitting a task of our scheduling class: + */ +static void task_tick_fair(struct rq *rq, struct task_struct *curr) +{ + struct cfs_rq *cfs_rq; + struct sched_entity *se = &curr->se; + + for_each_sched_entity(se) { + cfs_rq = cfs_rq_of(se); + entity_tick(cfs_rq, se); + } +} + +/* + * Share the fairness runtime between parent and child, thus the + * total amount of pressure for CPU stays equal - new tasks + * get a chance to run but frequent forkers are not allowed to + * monopolize the CPU. Note: the parent runqueue is locked, + * the child is not running yet. + */ +static void task_new_fair(struct rq *rq, struct task_struct *p) +{ + struct cfs_rq *cfs_rq = task_cfs_rq(p); + struct sched_entity *se = &p->se; + u64 now = rq_clock(rq); + + sched_info_queued(p); + + update_stats_enqueue(cfs_rq, se, now); + /* + * Child runs first: we let it run before the parent + * until it reschedules once. We set up the key so that + * it will preempt the parent: + */ + p->se.fair_key = current->se.fair_key - + niced_granularity(&rq->curr->se, sysctl_sched_granularity) - 1; + /* + * The first wait is dominated by the child-runs-first logic, + * so do not credit it with that waiting time yet: + */ + if (sysctl_sched_features & SCHED_FEAT_SKIP_INITIAL) + p->se.wait_start_fair = 0; + + /* + * The statistical average of wait_runtime is about + * -granularity/2, so initialize the task with that: + */ + if (sysctl_sched_features & SCHED_FEAT_START_DEBIT) + p->se.wait_runtime = -(sysctl_sched_granularity / 2); + + __enqueue_entity(cfs_rq, se); + inc_nr_running(p, rq, now); +} + +#ifdef CONFIG_FAIR_GROUP_SCHED +/* Account for a task changing its policy or group. + * + * This routine is mostly called to set cfs_rq->curr field when a task + * migrates between groups/classes. + */ +static void set_curr_task_fair(struct rq *rq) +{ + struct task_struct *curr = rq->curr; + struct sched_entity *se = &curr->se; + u64 now = rq_clock(rq); + struct cfs_rq *cfs_rq; + + for_each_sched_entity(se) { + cfs_rq = cfs_rq_of(se); + set_next_entity(cfs_rq, se, now); + } +} +#else +static void set_curr_task_fair(struct rq *rq) +{ +} +#endif + +/* + * All the scheduling class methods: + */ +struct sched_class fair_sched_class __read_mostly = { + .enqueue_task = enqueue_task_fair, + .dequeue_task = dequeue_task_fair, + .yield_task = yield_task_fair, + + .check_preempt_curr = check_preempt_curr_fair, + + .pick_next_task = pick_next_task_fair, + .put_prev_task = put_prev_task_fair, + + .load_balance = load_balance_fair, + + .set_curr_task = set_curr_task_fair, + .task_tick = task_tick_fair, + .task_new = task_new_fair, +}; + +#ifdef CONFIG_SCHED_DEBUG +void print_cfs_stats(struct seq_file *m, int cpu, u64 now) +{ + struct rq *rq = cpu_rq(cpu); + struct cfs_rq *cfs_rq; + + for_each_leaf_cfs_rq(rq, cfs_rq) + print_cfs_rq(m, cpu, cfs_rq, now); +} +#endif From bb44e5d1c6b3b748e0facf8f516b3162009feb27 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 243/551] sched: cfs core, kernel/sched_rt.c add kernel/sched_rt.c: SCHED_FIFO/SCHED_RR support. The behavior and semantics of SCHED_FIFO/SCHED_RR tasks is unchanged. Signed-off-by: Ingo Molnar --- kernel/sched_rt.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 kernel/sched_rt.c diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c new file mode 100644 index 000000000000..1192a2741b99 --- /dev/null +++ b/kernel/sched_rt.c @@ -0,0 +1,255 @@ +/* + * Real-Time Scheduling Class (mapped to the SCHED_FIFO and SCHED_RR + * policies) + */ + +/* + * Update the current task's runtime statistics. Skip current tasks that + * are not in our scheduling class. + */ +static inline void update_curr_rt(struct rq *rq, u64 now) +{ + struct task_struct *curr = rq->curr; + u64 delta_exec; + + if (!task_has_rt_policy(curr)) + return; + + delta_exec = now - curr->se.exec_start; + if (unlikely((s64)delta_exec < 0)) + delta_exec = 0; + if (unlikely(delta_exec > curr->se.exec_max)) + curr->se.exec_max = delta_exec; + + curr->se.sum_exec_runtime += delta_exec; + curr->se.exec_start = now; +} + +static void +enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now) +{ + struct rt_prio_array *array = &rq->rt.active; + + list_add_tail(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); +} + +/* + * Adding/removing a task to/from a priority array: + */ +static void +dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep, u64 now) +{ + struct rt_prio_array *array = &rq->rt.active; + + update_curr_rt(rq, now); + + list_del(&p->run_list); + if (list_empty(array->queue + p->prio)) + __clear_bit(p->prio, array->bitmap); +} + +/* + * Put task to the end of the run list without the overhead of dequeue + * followed by enqueue. + */ +static void requeue_task_rt(struct rq *rq, struct task_struct *p) +{ + struct rt_prio_array *array = &rq->rt.active; + + list_move_tail(&p->run_list, array->queue + p->prio); +} + +static void +yield_task_rt(struct rq *rq, struct task_struct *p) +{ + requeue_task_rt(rq, p); +} + +/* + * Preempt the current task with a newly woken task if needed: + */ +static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p) +{ + if (p->prio < rq->curr->prio) + resched_task(rq->curr); +} + +static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now) +{ + struct rt_prio_array *array = &rq->rt.active; + struct task_struct *next; + struct list_head *queue; + int idx; + + idx = sched_find_first_bit(array->bitmap); + if (idx >= MAX_RT_PRIO) + return NULL; + + queue = array->queue + idx; + next = list_entry(queue->next, struct task_struct, run_list); + + next->se.exec_start = now; + + return next; +} + +static void put_prev_task_rt(struct rq *rq, struct task_struct *p, u64 now) +{ + update_curr_rt(rq, now); + p->se.exec_start = 0; +} + +/* + * Load-balancing iterator. Note: while the runqueue stays locked + * during the whole iteration, the current task might be + * dequeued so the iterator has to be dequeue-safe. Here we + * achieve that by always pre-iterating before returning + * the current task: + */ +static struct task_struct *load_balance_start_rt(void *arg) +{ + struct rq *rq = arg; + struct rt_prio_array *array = &rq->rt.active; + struct list_head *head, *curr; + struct task_struct *p; + int idx; + + idx = sched_find_first_bit(array->bitmap); + if (idx >= MAX_RT_PRIO) + return NULL; + + head = array->queue + idx; + curr = head->prev; + + p = list_entry(curr, struct task_struct, run_list); + + curr = curr->prev; + + rq->rt.rt_load_balance_idx = idx; + rq->rt.rt_load_balance_head = head; + rq->rt.rt_load_balance_curr = curr; + + return p; +} + +static struct task_struct *load_balance_next_rt(void *arg) +{ + struct rq *rq = arg; + struct rt_prio_array *array = &rq->rt.active; + struct list_head *head, *curr; + struct task_struct *p; + int idx; + + idx = rq->rt.rt_load_balance_idx; + head = rq->rt.rt_load_balance_head; + curr = rq->rt.rt_load_balance_curr; + + /* + * If we arrived back to the head again then + * iterate to the next queue (if any): + */ + if (unlikely(head == curr)) { + int next_idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx+1); + + if (next_idx >= MAX_RT_PRIO) + return NULL; + + idx = next_idx; + head = array->queue + idx; + curr = head->prev; + + rq->rt.rt_load_balance_idx = idx; + rq->rt.rt_load_balance_head = head; + } + + p = list_entry(curr, struct task_struct, run_list); + + curr = curr->prev; + + rq->rt.rt_load_balance_curr = curr; + + return p; +} + +static int +load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *load_moved) +{ + int this_best_prio, best_prio, best_prio_seen = 0; + int nr_moved; + struct rq_iterator rt_rq_iterator; + + best_prio = sched_find_first_bit(busiest->rt.active.bitmap); + this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap); + + /* + * Enable handling of the case where there is more than one task + * with the best priority. If the current running task is one + * of those with prio==best_prio we know it won't be moved + * and therefore it's safe to override the skip (based on load) + * of any task we find with that prio. + */ + if (busiest->curr->prio == best_prio) + best_prio_seen = 1; + + rt_rq_iterator.start = load_balance_start_rt; + rt_rq_iterator.next = load_balance_next_rt; + /* pass 'busiest' rq argument into + * load_balance_[start|next]_rt iterators + */ + rt_rq_iterator.arg = busiest; + + nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move, + max_load_move, sd, idle, all_pinned, load_moved, + this_best_prio, best_prio, best_prio_seen, + &rt_rq_iterator); + + return nr_moved; +} + +static void task_tick_rt(struct rq *rq, struct task_struct *p) +{ + /* + * RR tasks need a special form of timeslice management. + * FIFO tasks have no timeslices. + */ + if (p->policy != SCHED_RR) + return; + + if (--p->time_slice) + return; + + p->time_slice = static_prio_timeslice(p->static_prio); + set_tsk_need_resched(p); + + /* put it at the end of the queue: */ + requeue_task_rt(rq, p); +} + +/* + * No parent/child timeslice management necessary for RT tasks, + * just activate them: + */ +static void task_new_rt(struct rq *rq, struct task_struct *p) +{ + activate_task(rq, p, 1); +} + +static struct sched_class rt_sched_class __read_mostly = { + .enqueue_task = enqueue_task_rt, + .dequeue_task = dequeue_task_rt, + .yield_task = yield_task_rt, + + .check_preempt_curr = check_preempt_curr_rt, + + .pick_next_task = pick_next_task_rt, + .put_prev_task = put_prev_task_rt, + + .load_balance = load_balance_rt, + + .task_tick = task_tick_rt, + .task_new = task_new_rt, +}; From fa72e9e484c16f0c9aee23981917d8c8c03f0482 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 244/551] sched: cfs core, kernel/sched_idletask.c add kernel/sched_idletask.c - which implements the idle thread scheduling class. This further simplifies sched.c (under CFS), for example a number of 'if (p == rq->idle)' type of special-cases can be removed from sched.c, and schedule() gets simpler too. Signed-off-by: Ingo Molnar --- kernel/sched_idletask.c | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 kernel/sched_idletask.c diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c new file mode 100644 index 000000000000..41841e741c4a --- /dev/null +++ b/kernel/sched_idletask.c @@ -0,0 +1,71 @@ +/* + * idle-task scheduling class. + * + * (NOTE: these are not related to SCHED_IDLE tasks which are + * handled in sched_fair.c) + */ + +/* + * Idle tasks are unconditionally rescheduled: + */ +static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p) +{ + resched_task(rq->idle); +} + +static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now) +{ + schedstat_inc(rq, sched_goidle); + + return rq->idle; +} + +/* + * It is not legal to sleep in the idle task - print a warning + * message if some code attempts to do it: + */ +static void +dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now) +{ + spin_unlock_irq(&rq->lock); + printk(KERN_ERR "bad: scheduling from the idle thread!\n"); + dump_stack(); + spin_lock_irq(&rq->lock); +} + +static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, u64 now) +{ +} + +static int +load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *total_load_moved) +{ + return 0; +} + +static void task_tick_idle(struct rq *rq, struct task_struct *curr) +{ +} + +/* + * Simple, special scheduling class for the per-CPU idle tasks: + */ +static struct sched_class idle_sched_class __read_mostly = { + /* no enqueue/yield_task for idle tasks */ + + /* dequeue is not valid, we print a debug message there: */ + .dequeue_task = dequeue_task_idle, + + .check_preempt_curr = check_preempt_curr_idle, + + .pick_next_task = pick_next_task_idle, + .put_prev_task = put_prev_task_idle, + + .load_balance = load_balance_idle, + + .task_tick = task_tick_idle, + /* no .task_new for idle tasks */ +}; From 20b8a59f2461e1be911dce2cfafefab9d22e4eee Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 245/551] sched: cfs, core data types add the CFS data types to sched.h. (the old scheduler is still fully intact.) Signed-off-by: Ingo Molnar --- include/linux/sched.h | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 90420321994f..995eb407c234 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -820,6 +820,86 @@ enum sleep_type { }; struct prio_array; +struct rq; +struct sched_domain; + +struct sched_class { + struct sched_class *next; + + void (*enqueue_task) (struct rq *rq, struct task_struct *p, + int wakeup, u64 now); + void (*dequeue_task) (struct rq *rq, struct task_struct *p, + int sleep, u64 now); + void (*yield_task) (struct rq *rq, struct task_struct *p); + + void (*check_preempt_curr) (struct rq *rq, struct task_struct *p); + + struct task_struct * (*pick_next_task) (struct rq *rq, u64 now); + void (*put_prev_task) (struct rq *rq, struct task_struct *p, u64 now); + + int (*load_balance) (struct rq *this_rq, int this_cpu, + struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *total_load_moved); + + void (*set_curr_task) (struct rq *rq); + void (*task_tick) (struct rq *rq, struct task_struct *p); + void (*task_new) (struct rq *rq, struct task_struct *p); +}; + +struct load_weight { + unsigned long weight, inv_weight; +}; + +/* + * CFS stats for a schedulable entity (task, task-group etc) + * + * Current field usage histogram: + * + * 4 se->block_start + * 4 se->run_node + * 4 se->sleep_start + * 4 se->sleep_start_fair + * 6 se->load.weight + * 7 se->delta_fair + * 15 se->wait_runtime + */ +struct sched_entity { + long wait_runtime; + unsigned long delta_fair_run; + unsigned long delta_fair_sleep; + unsigned long delta_exec; + s64 fair_key; + struct load_weight load; /* for load-balancing */ + struct rb_node run_node; + unsigned int on_rq; + + u64 wait_start_fair; + u64 wait_start; + u64 exec_start; + u64 sleep_start; + u64 sleep_start_fair; + u64 block_start; + u64 sleep_max; + u64 block_max; + u64 exec_max; + u64 wait_max; + u64 last_ran; + + u64 sum_exec_runtime; + s64 sum_wait_runtime; + s64 sum_sleep_runtime; + unsigned long wait_runtime_overruns; + unsigned long wait_runtime_underruns; +#ifdef CONFIG_FAIR_GROUP_SCHED + struct sched_entity *parent; + /* rq on which this entity is (to be) queued: */ + struct cfs_rq *cfs_rq; + /* rq "owned" by this entity/group: */ + struct cfs_rq *my_q; +#endif +}; struct task_struct { volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ @@ -839,6 +919,8 @@ struct task_struct { int prio, static_prio, normal_prio; struct list_head run_list; struct prio_array *array; + struct sched_class *sched_class; + struct sched_entity se; unsigned short ioprio; #ifdef CONFIG_BLK_DEV_IO_TRACE From 6aa645ea5f7a246702e07f29edc7075d487ae4a3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 246/551] sched: cfs rq data types add the CFS rq data types to sched.c. (the old scheduler fields are still intact, they are removed by a later patch) Signed-off-by: Ingo Molnar --- kernel/sched.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index f8b8eda4494d..085418bedccd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -91,6 +91,9 @@ unsigned long long __attribute__((weak)) sched_clock(void) #define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ)) #define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ)) +#define NICE_0_LOAD SCHED_LOAD_SCALE +#define NICE_0_SHIFT SCHED_LOAD_SHIFT + /* * These are the 'tuning knobs' of the scheduler: * @@ -218,9 +221,61 @@ static inline unsigned int task_timeslice(struct task_struct *p) } /* - * These are the runqueue data structures: + * This is the priority-queue data structure of the RT scheduling class: */ +struct rt_prio_array { + DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */ + struct list_head queue[MAX_RT_PRIO]; +}; +struct load_stat { + struct load_weight load; + u64 load_update_start, load_update_last; + unsigned long delta_fair, delta_exec, delta_stat; +}; + +/* CFS-related fields in a runqueue */ +struct cfs_rq { + struct load_weight load; + unsigned long nr_running; + + s64 fair_clock; + u64 exec_clock; + s64 wait_runtime; + u64 sleeper_bonus; + unsigned long wait_runtime_overruns, wait_runtime_underruns; + + struct rb_root tasks_timeline; + struct rb_node *rb_leftmost; + struct rb_node *rb_load_balance_curr; +#ifdef CONFIG_FAIR_GROUP_SCHED + /* 'curr' points to currently running entity on this cfs_rq. + * It is set to NULL otherwise (i.e when none are currently running). + */ + struct sched_entity *curr; + struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */ + + /* leaf cfs_rqs are those that hold tasks (lowest schedulable entity in + * a hierarchy). Non-leaf lrqs hold other higher schedulable entities + * (like users, containers etc.) + * + * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This + * list is used during load balance. + */ + struct list_head leaf_cfs_rq_list; /* Better name : task_cfs_rq_list? */ +#endif +}; + +/* Real-Time classes' related field in a runqueue: */ +struct rt_rq { + struct rt_prio_array active; + int rt_load_balance_idx; + struct list_head *rt_load_balance_head, *rt_load_balance_curr; +}; + +/* + * The prio-array type of the old scheduler: + */ struct prio_array { unsigned int nr_active; DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */ @@ -235,7 +290,7 @@ struct prio_array { * acquire operations must be ordered by ascending &runqueue. */ struct rq { - spinlock_t lock; + spinlock_t lock; /* runqueue lock */ /* * nr_running and cpu_load should be in the same cacheline because @@ -243,14 +298,21 @@ struct rq { */ unsigned long nr_running; unsigned long raw_weighted_load; -#ifdef CONFIG_SMP - unsigned long cpu_load[3]; + #define CPU_LOAD_IDX_MAX 5 + unsigned long cpu_load[CPU_LOAD_IDX_MAX]; unsigned char idle_at_tick; #ifdef CONFIG_NO_HZ unsigned char in_nohz_recently; #endif + struct load_stat ls; /* capture load from *all* tasks on this cpu */ + unsigned long nr_load_updates; + u64 nr_switches; + + struct cfs_rq cfs; +#ifdef CONFIG_FAIR_GROUP_SCHED + struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */ #endif - unsigned long long nr_switches; + struct rt_rq rt; /* * This is part of a global counter where only the total sum @@ -261,13 +323,23 @@ struct rq { unsigned long nr_uninterruptible; unsigned long expired_timestamp; - /* Cached timestamp set by update_cpu_clock() */ unsigned long long most_recent_timestamp; + struct task_struct *curr, *idle; unsigned long next_balance; struct mm_struct *prev_mm; + struct prio_array *active, *expired, arrays[2]; int best_expired_prio; + + u64 clock, prev_clock_raw; + s64 clock_max_delta; + + unsigned int clock_warps, clock_overflows; + unsigned int clock_unstable_events; + + struct sched_class *load_balance_class; + atomic_t nr_iowait; #ifdef CONFIG_SMP From 20d315d42aed95423a7203e1d7e84086004b5a00 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 247/551] sched: add rq_clock()/__rq_clock() add rq_clock()/__rq_clock(), a robust wrapper around sched_clock(), used by CFS. It protects against common type of sched_clock() problems (caused by hardware): time warps forwards and backwards. Signed-off-by: Ingo Molnar --- kernel/sched.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 085418bedccd..29eb227e33f7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -388,6 +388,52 @@ static inline int cpu_of(struct rq *rq) #endif } +/* + * Per-runqueue clock, as finegrained as the platform can give us: + */ +static unsigned long long __rq_clock(struct rq *rq) +{ + u64 prev_raw = rq->prev_clock_raw; + u64 now = sched_clock(); + s64 delta = now - prev_raw; + u64 clock = rq->clock; + + /* + * Protect against sched_clock() occasionally going backwards: + */ + if (unlikely(delta < 0)) { + clock++; + rq->clock_warps++; + } else { + /* + * Catch too large forward jumps too: + */ + if (unlikely(delta > 2*TICK_NSEC)) { + clock++; + rq->clock_overflows++; + } else { + if (unlikely(delta > rq->clock_max_delta)) + rq->clock_max_delta = delta; + clock += delta; + } + } + + rq->prev_clock_raw = now; + rq->clock = clock; + + return clock; +} + +static inline unsigned long long rq_clock(struct rq *rq) +{ + int this_cpu = smp_processor_id(); + + if (this_cpu == cpu_of(rq)) + return __rq_clock(rq); + + return rq->clock; +} + /* * The domain tree (rq->sd) is protected by RCU's quiescent state transition. * See detach_destroy_domains: synchronize_sched for details. From 41b86e9c510ae66639bf29d3201e1d2384a7fde6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 248/551] sched: make posix-cpu-timers use CFS's accounting information update the posix-cpu-timers code to use CFS's CPU accounting information. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 5 +++-- kernel/posix-cpu-timers.c | 34 +++++++++++++++++----------------- kernel/sched.c | 36 +++++++++++++----------------------- 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 995eb407c234..3e7f1890e55d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -482,7 +482,8 @@ struct signal_struct { * from jiffies_to_ns(utime + stime) if sched_clock uses something * other than jiffies.) */ - unsigned long long sched_time; + unsigned long sched_time; + unsigned long long sum_sched_runtime; /* * We don't bother to synchronize most readers of this at all, @@ -1308,7 +1309,7 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) extern unsigned long long sched_clock(void); extern unsigned long long -current_sched_time(const struct task_struct *current_task); +task_sched_runtime(struct task_struct *task); /* sched_exec is called by processes performing an exec */ #ifdef CONFIG_SMP diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 1de710e18373..b53c8fcd9d82 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -161,7 +161,7 @@ static inline cputime_t virt_ticks(struct task_struct *p) } static inline unsigned long long sched_ns(struct task_struct *p) { - return (p == current) ? current_sched_time(p) : p->sched_time; + return task_sched_runtime(p); } int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) @@ -246,10 +246,10 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx, } while (t != p); break; case CPUCLOCK_SCHED: - cpu->sched = p->signal->sched_time; + cpu->sched = p->signal->sum_sched_runtime; /* Add in each other live thread. */ while ((t = next_thread(t)) != p) { - cpu->sched += t->sched_time; + cpu->sched += t->se.sum_exec_runtime; } cpu->sched += sched_ns(p); break; @@ -422,7 +422,7 @@ int posix_cpu_timer_del(struct k_itimer *timer) */ static void cleanup_timers(struct list_head *head, cputime_t utime, cputime_t stime, - unsigned long long sched_time) + unsigned long long sum_exec_runtime) { struct cpu_timer_list *timer, *next; cputime_t ptime = cputime_add(utime, stime); @@ -451,10 +451,10 @@ static void cleanup_timers(struct list_head *head, ++head; list_for_each_entry_safe(timer, next, head, entry) { list_del_init(&timer->entry); - if (timer->expires.sched < sched_time) { + if (timer->expires.sched < sum_exec_runtime) { timer->expires.sched = 0; } else { - timer->expires.sched -= sched_time; + timer->expires.sched -= sum_exec_runtime; } } } @@ -467,7 +467,7 @@ static void cleanup_timers(struct list_head *head, void posix_cpu_timers_exit(struct task_struct *tsk) { cleanup_timers(tsk->cpu_timers, - tsk->utime, tsk->stime, tsk->sched_time); + tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); } void posix_cpu_timers_exit_group(struct task_struct *tsk) @@ -475,7 +475,7 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk) cleanup_timers(tsk->signal->cpu_timers, cputime_add(tsk->utime, tsk->signal->utime), cputime_add(tsk->stime, tsk->signal->stime), - tsk->sched_time + tsk->signal->sched_time); + tsk->se.sum_exec_runtime + tsk->signal->sum_sched_runtime); } @@ -536,7 +536,7 @@ static void process_timer_rebalance(struct task_struct *p, nsleft = max_t(unsigned long long, nsleft, 1); do { if (likely(!(t->flags & PF_EXITING))) { - ns = t->sched_time + nsleft; + ns = t->se.sum_exec_runtime + nsleft; if (t->it_sched_expires == 0 || t->it_sched_expires > ns) { t->it_sched_expires = ns; @@ -1004,7 +1004,7 @@ static void check_thread_timers(struct task_struct *tsk, struct cpu_timer_list *t = list_first_entry(timers, struct cpu_timer_list, entry); - if (!--maxfire || tsk->sched_time < t->expires.sched) { + if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) { tsk->it_sched_expires = t->expires.sched; break; } @@ -1024,7 +1024,7 @@ static void check_process_timers(struct task_struct *tsk, int maxfire; struct signal_struct *const sig = tsk->signal; cputime_t utime, stime, ptime, virt_expires, prof_expires; - unsigned long long sched_time, sched_expires; + unsigned long long sum_sched_runtime, sched_expires; struct task_struct *t; struct list_head *timers = sig->cpu_timers; @@ -1044,12 +1044,12 @@ static void check_process_timers(struct task_struct *tsk, */ utime = sig->utime; stime = sig->stime; - sched_time = sig->sched_time; + sum_sched_runtime = sig->sum_sched_runtime; t = tsk; do { utime = cputime_add(utime, t->utime); stime = cputime_add(stime, t->stime); - sched_time += t->sched_time; + sum_sched_runtime += t->se.sum_exec_runtime; t = next_thread(t); } while (t != tsk); ptime = cputime_add(utime, stime); @@ -1090,7 +1090,7 @@ static void check_process_timers(struct task_struct *tsk, struct cpu_timer_list *t = list_first_entry(timers, struct cpu_timer_list, entry); - if (!--maxfire || sched_time < t->expires.sched) { + if (!--maxfire || sum_sched_runtime < t->expires.sched) { sched_expires = t->expires.sched; break; } @@ -1182,7 +1182,7 @@ static void check_process_timers(struct task_struct *tsk, virt_left = cputime_sub(virt_expires, utime); virt_left = cputime_div_non_zero(virt_left, nthreads); if (sched_expires) { - sched_left = sched_expires - sched_time; + sched_left = sched_expires - sum_sched_runtime; do_div(sched_left, nthreads); sched_left = max_t(unsigned long long, sched_left, 1); } else { @@ -1208,7 +1208,7 @@ static void check_process_timers(struct task_struct *tsk, t->it_virt_expires = ticks; } - sched = t->sched_time + sched_left; + sched = t->se.sum_exec_runtime + sched_left; if (sched_expires && (t->it_sched_expires == 0 || t->it_sched_expires > sched)) { t->it_sched_expires = sched; @@ -1300,7 +1300,7 @@ void run_posix_cpu_timers(struct task_struct *tsk) if (UNEXPIRED(prof) && UNEXPIRED(virt) && (tsk->it_sched_expires == 0 || - tsk->sched_time < tsk->it_sched_expires)) + tsk->se.sum_exec_runtime < tsk->it_sched_expires)) return; #undef UNEXPIRED diff --git a/kernel/sched.c b/kernel/sched.c index 29eb227e33f7..0333abdda85e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3156,28 +3156,23 @@ DEFINE_PER_CPU(struct kernel_stat, kstat); EXPORT_PER_CPU_SYMBOL(kstat); /* - * This is called on clock ticks and on context switches. - * Bank in p->sched_time the ns elapsed since the last tick or switch. + * Return p->sum_exec_runtime plus any more ns on the sched_clock + * that have not yet been banked in case the task is currently running. */ -static inline void -update_cpu_clock(struct task_struct *p, struct rq *rq, unsigned long long now) +unsigned long long task_sched_runtime(struct task_struct *p) { - p->sched_time += now - p->last_ran; - p->last_ran = rq->most_recent_timestamp = now; -} - -/* - * Return current->sched_time plus any more ns on the sched_clock - * that have not yet been banked. - */ -unsigned long long current_sched_time(const struct task_struct *p) -{ - unsigned long long ns; unsigned long flags; + u64 ns, delta_exec; + struct rq *rq; - local_irq_save(flags); - ns = p->sched_time + sched_clock() - p->last_ran; - local_irq_restore(flags); + rq = task_rq_lock(p, &flags); + ns = p->se.sum_exec_runtime; + if (rq->curr == p) { + delta_exec = rq_clock(rq) - p->se.exec_start; + if ((s64)delta_exec > 0) + ns += delta_exec; + } + task_rq_unlock(rq, &flags); return ns; } @@ -3360,14 +3355,11 @@ out_unlock: */ void scheduler_tick(void) { - unsigned long long now = sched_clock(); struct task_struct *p = current; int cpu = smp_processor_id(); int idle_at_tick = idle_cpu(cpu); struct rq *rq = cpu_rq(cpu); - update_cpu_clock(p, rq, now); - if (!idle_at_tick) task_running_tick(rq, p); #ifdef CONFIG_SMP @@ -3550,8 +3542,6 @@ switch_tasks: clear_tsk_need_resched(prev); rcu_qsctr_inc(task_cpu(prev)); - update_cpu_clock(prev, rq, now); - prev->sleep_avg -= run_time; if ((long)prev->sleep_avg <= 0) prev->sleep_avg = 0; From 138a8aeb5b9e5c5abd5e5ec22b6d1848e7e9c50b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:58 +0200 Subject: [PATCH 249/551] sched: add cfs_rq ops add the set_task_cfs_rq() abstraction needed by CONFIG_FAIR_GROUP_SCHED. (not activated yet) Signed-off-by: Ingo Molnar --- kernel/sched.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 0333abdda85e..d9ed9274bf0a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -449,6 +449,18 @@ static inline unsigned long long rq_clock(struct rq *rq) #define task_rq(p) cpu_rq(task_cpu(p)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) +#ifdef CONFIG_FAIR_GROUP_SCHED +/* Change a task's ->cfs_rq if it moves across CPUs */ +static inline void set_task_cfs_rq(struct task_struct *p) +{ + p->se.cfs_rq = &task_rq(p)->cfs; +} +#else +static inline void set_task_cfs_rq(struct task_struct *p) +{ +} +#endif + #ifndef prepare_arch_switch # define prepare_arch_switch(next) do { } while (0) #endif From e05606d3301525aa67b081ad9fccade2b31ab35a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 250/551] sched: clean up the rt priority macros clean up the rt priority macros, pointed out by Andrew Morton. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 61 +++++++++++++++++++++++++------------------ kernel/exit.c | 2 +- kernel/sched.c | 22 ++++++++++++---- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 3e7f1890e55d..4dcc61cca00a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -525,31 +525,6 @@ struct signal_struct { #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ - -/* - * Priority of a process goes from 0..MAX_PRIO-1, valid RT - * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH - * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority - * values are inverted: lower p->prio value means higher priority. - * - * The MAX_USER_RT_PRIO value allows the actual maximum - * RT priority to be separate from the value exported to - * user-space. This allows kernel threads to set their - * priority to a value higher than any user task. Note: - * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. - */ - -#define MAX_USER_RT_PRIO 100 -#define MAX_RT_PRIO MAX_USER_RT_PRIO - -#define MAX_PRIO (MAX_RT_PRIO + 40) - -#define rt_prio(prio) unlikely((prio) < MAX_RT_PRIO) -#define rt_task(p) rt_prio((p)->prio) -#define batch_task(p) (unlikely((p)->policy == SCHED_BATCH)) -#define is_rt_policy(p) ((p) != SCHED_NORMAL && (p) != SCHED_BATCH) -#define has_rt_policy(p) unlikely(is_rt_policy((p)->policy)) - /* * Some day this will be a full-fledged user tracking system.. */ @@ -1164,6 +1139,42 @@ struct task_struct { #endif }; +/* + * Priority of a process goes from 0..MAX_PRIO-1, valid RT + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH + * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority + * values are inverted: lower p->prio value means higher priority. + * + * The MAX_USER_RT_PRIO value allows the actual maximum + * RT priority to be separate from the value exported to + * user-space. This allows kernel threads to set their + * priority to a value higher than any user task. Note: + * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. + */ + +#define MAX_USER_RT_PRIO 100 +#define MAX_RT_PRIO MAX_USER_RT_PRIO + +#define MAX_PRIO (MAX_RT_PRIO + 40) +#define DEFAULT_PRIO (MAX_RT_PRIO + 20) + +static inline int rt_prio(int prio) +{ + if (unlikely(prio < MAX_RT_PRIO)) + return 1; + return 0; +} + +static inline int rt_task(struct task_struct *p) +{ + return rt_prio(p->prio); +} + +static inline int batch_task(struct task_struct *p) +{ + return p->policy == SCHED_BATCH; +} + static inline pid_t process_group(struct task_struct *tsk) { return tsk->signal->pgrp; diff --git a/kernel/exit.c b/kernel/exit.c index 6c7699240327..8fd7acd7bbd0 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -290,7 +290,7 @@ static void reparent_to_kthreadd(void) /* Set the exit signal to SIGCHLD so we signal init on exit */ current->exit_signal = SIGCHLD; - if (!has_rt_policy(current) && (task_nice(current) < 0)) + if (task_nice(current) < 0) set_user_nice(current, 0); /* cpus_allowed? */ /* rt_priority? */ diff --git a/kernel/sched.c b/kernel/sched.c index d9ed9274bf0a..53c0ee742f69 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -220,6 +220,18 @@ static inline unsigned int task_timeslice(struct task_struct *p) return static_prio_timeslice(p->static_prio); } +static inline int rt_policy(int policy) +{ + if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR)) + return 1; + return 0; +} + +static inline int task_has_rt_policy(struct task_struct *p) +{ + return rt_policy(p->policy); +} + /* * This is the priority-queue data structure of the RT scheduling class: */ @@ -698,7 +710,7 @@ static inline int __normal_prio(struct task_struct *p) static void set_load_weight(struct task_struct *p) { - if (has_rt_policy(p)) { + if (task_has_rt_policy(p)) { #ifdef CONFIG_SMP if (p == task_rq(p)->migration_thread) /* @@ -749,7 +761,7 @@ static inline int normal_prio(struct task_struct *p) { int prio; - if (has_rt_policy(p)) + if (task_has_rt_policy(p)) prio = MAX_RT_PRIO-1 - p->rt_priority; else prio = __normal_prio(p); @@ -4051,7 +4063,7 @@ void set_user_nice(struct task_struct *p, long nice) * it wont have any effect on scheduling until the task is * not SCHED_NORMAL/SCHED_BATCH: */ - if (has_rt_policy(p)) { + if (task_has_rt_policy(p)) { p->static_prio = NICE_TO_PRIO(nice); goto out_unlock; } @@ -4240,14 +4252,14 @@ recheck: (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) || (!p->mm && param->sched_priority > MAX_RT_PRIO-1)) return -EINVAL; - if (is_rt_policy(policy) != (param->sched_priority != 0)) + if (rt_policy(policy) != (param->sched_priority != 0)) return -EINVAL; /* * Allow unprivileged RT tasks to decrease priority: */ if (!capable(CAP_SYS_NICE)) { - if (is_rt_policy(policy)) { + if (rt_policy(policy)) { unsigned long rlim_rtprio; unsigned long flags; From 62480d13d5d1812176e969a47e2db78a5398d02e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 251/551] sched: remove the SleepAVG field remove the SleepAVG field from /proc//status, as with the removal of the sleep-average code this value no longer makes sense. Signed-off-by: Ingo Molnar --- fs/proc/array.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index 74f30e0c0381..3df644313f9b 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -165,7 +165,6 @@ static inline char * task_state(struct task_struct *p, char *buffer) rcu_read_lock(); buffer += sprintf(buffer, "State:\t%s\n" - "SleepAVG:\t%lu%%\n" "Tgid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" @@ -173,7 +172,6 @@ static inline char * task_state(struct task_struct *p, char *buffer) "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), - (p->sleep_avg/1024)*100/(1020000000/1024), p->tgid, p->pid, pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, From c24d20dbef948487cd14f15dbf04644142e9f886 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 252/551] sched: move around resched_task() move resched_task()/resched_cpu() into the 'public interfaces' section of sched.c, for use by kernel/sched_fair/rt/idletask.c Signed-off-by: Ingo Molnar --- kernel/sched.c | 104 ++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 53c0ee742f69..e642bfa61fe3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -617,6 +617,58 @@ static inline struct rq *this_rq_lock(void) return rq; } +/* + * resched_task - mark a task 'to be rescheduled now'. + * + * On UP this means the setting of the need_resched flag, on SMP it + * might also involve a cross-CPU call to trigger the scheduler on + * the target CPU. + */ +#ifdef CONFIG_SMP + +#ifndef tsk_is_polling +#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) +#endif + +static void resched_task(struct task_struct *p) +{ + int cpu; + + assert_spin_locked(&task_rq(p)->lock); + + if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED))) + return; + + set_tsk_thread_flag(p, TIF_NEED_RESCHED); + + cpu = task_cpu(p); + if (cpu == smp_processor_id()) + return; + + /* NEED_RESCHED must be visible before we test polling */ + smp_mb(); + if (!tsk_is_polling(p)) + smp_send_reschedule(cpu); +} + +static void resched_cpu(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + unsigned long flags; + + if (!spin_trylock_irqsave(&rq->lock, flags)) + return; + resched_task(cpu_curr(cpu)); + spin_unlock_irqrestore(&rq->lock, flags); +} +#else +static inline void resched_task(struct task_struct *p) +{ + assert_spin_locked(&task_rq(p)->lock); + set_tsk_need_resched(p); +} +#endif + #include "sched_stats.h" /* @@ -953,58 +1005,6 @@ static void deactivate_task(struct task_struct *p, struct rq *rq) p->array = NULL; } -/* - * resched_task - mark a task 'to be rescheduled now'. - * - * On UP this means the setting of the need_resched flag, on SMP it - * might also involve a cross-CPU call to trigger the scheduler on - * the target CPU. - */ -#ifdef CONFIG_SMP - -#ifndef tsk_is_polling -#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) -#endif - -static void resched_task(struct task_struct *p) -{ - int cpu; - - assert_spin_locked(&task_rq(p)->lock); - - if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED))) - return; - - set_tsk_thread_flag(p, TIF_NEED_RESCHED); - - cpu = task_cpu(p); - if (cpu == smp_processor_id()) - return; - - /* NEED_RESCHED must be visible before we test polling */ - smp_mb(); - if (!tsk_is_polling(p)) - smp_send_reschedule(cpu); -} - -static void resched_cpu(int cpu) -{ - struct rq *rq = cpu_rq(cpu); - unsigned long flags; - - if (!spin_trylock_irqsave(&rq->lock, flags)) - return; - resched_task(cpu_curr(cpu)); - spin_unlock_irqrestore(&rq->lock, flags); -} -#else -static inline void resched_task(struct task_struct *p) -{ - assert_spin_locked(&task_rq(p)->lock); - set_tsk_need_resched(p); -} -#endif - /** * task_curr - is this task currently executing on a CPU? * @p: the task in question. From 71f8bd4600521fecb08644072052b85853a5a615 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 253/551] sched: cleanup: move dequeue/enqueue_task() cleanup: move dequeue/enqueue_task() to a more logical place, to not split up __normal_prio()/normal_prio(). Signed-off-by: Ingo Molnar --- kernel/sched.c | 76 +++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index e642bfa61fe3..683d2a524e61 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -671,44 +671,6 @@ static inline void resched_task(struct task_struct *p) #include "sched_stats.h" -/* - * Adding/removing a task to/from a priority array: - */ -static void dequeue_task(struct task_struct *p, struct prio_array *array) -{ - array->nr_active--; - list_del(&p->run_list); - if (list_empty(array->queue + p->prio)) - __clear_bit(p->prio, array->bitmap); -} - -static void enqueue_task(struct task_struct *p, struct prio_array *array) -{ - sched_info_queued(p); - list_add_tail(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); - array->nr_active++; - p->array = array; -} - -/* - * Put task to the end of the run list without the overhead of dequeue - * followed by enqueue. - */ -static void requeue_task(struct task_struct *p, struct prio_array *array) -{ - list_move_tail(&p->run_list, array->queue + p->prio); -} - -static inline void -enqueue_task_head(struct task_struct *p, struct prio_array *array) -{ - list_add(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); - array->nr_active++; - p->array = array; -} - /* * __normal_prio - return the priority that is based on the static * priority but is modified by bonuses/penalties. @@ -802,6 +764,44 @@ static inline void dec_nr_running(struct task_struct *p, struct rq *rq) dec_raw_weighted_load(rq, p); } +/* + * Adding/removing a task to/from a priority array: + */ +static void dequeue_task(struct task_struct *p, struct prio_array *array) +{ + array->nr_active--; + list_del(&p->run_list); + if (list_empty(array->queue + p->prio)) + __clear_bit(p->prio, array->bitmap); +} + +static void enqueue_task(struct task_struct *p, struct prio_array *array) +{ + sched_info_queued(p); + list_add_tail(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); + array->nr_active++; + p->array = array; +} + +/* + * Put task to the end of the run list without the overhead of dequeue + * followed by enqueue. + */ +static void requeue_task(struct task_struct *p, struct prio_array *array) +{ + list_move_tail(&p->run_list, array->queue + p->prio); +} + +static inline void +enqueue_task_head(struct task_struct *p, struct prio_array *array) +{ + list_add(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); + array->nr_active++; + p->array = array; +} + /* * Calculate the expected normal priority: i.e. priority * without taking RT-inheritance into account. Might be From 14531189f0a1071b928586e9e1a89eceac91d95f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 254/551] sched: clean up __normal_prio() position clean up: move __normal_prio() in head of normal_prio(). no code changed. Signed-off-by: Ingo Molnar --- kernel/sched.c | 58 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 683d2a524e61..5cd069b77fd7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -671,35 +671,6 @@ static inline void resched_task(struct task_struct *p) #include "sched_stats.h" -/* - * __normal_prio - return the priority that is based on the static - * priority but is modified by bonuses/penalties. - * - * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] - * into the -5 ... 0 ... +5 bonus/penalty range. - * - * We use 25% of the full 0...39 priority range so that: - * - * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. - * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. - * - * Both properties are important to certain workloads. - */ - -static inline int __normal_prio(struct task_struct *p) -{ - int bonus, prio; - - bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; - - prio = p->static_prio - bonus; - if (prio < MAX_RT_PRIO) - prio = MAX_RT_PRIO; - if (prio > MAX_PRIO-1) - prio = MAX_PRIO-1; - return prio; -} - /* * To aid in avoiding the subversion of "niceness" due to uneven distribution * of tasks with abnormal "nice" values across CPUs the contribution that @@ -802,6 +773,35 @@ enqueue_task_head(struct task_struct *p, struct prio_array *array) p->array = array; } +/* + * __normal_prio - return the priority that is based on the static + * priority but is modified by bonuses/penalties. + * + * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] + * into the -5 ... 0 ... +5 bonus/penalty range. + * + * We use 25% of the full 0...39 priority range so that: + * + * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. + * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. + * + * Both properties are important to certain workloads. + */ + +static inline int __normal_prio(struct task_struct *p) +{ + int bonus, prio; + + bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; + + prio = p->static_prio - bonus; + if (prio < MAX_RT_PRIO) + prio = MAX_RT_PRIO; + if (prio > MAX_PRIO-1) + prio = MAX_PRIO-1; + return prio; +} + /* * Calculate the expected normal priority: i.e. priority * without taking RT-inheritance into account. Might be From 45bf76df4814a4cd1c57226ae001c464467cb656 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 255/551] sched: cfs, add load-calculation methods add the new load-calculation methods of CFS. Signed-off-by: Ingo Molnar --- kernel/sched.c | 138 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 18 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 5cd069b77fd7..6e5a89ba4f76 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -671,6 +671,108 @@ static inline void resched_task(struct task_struct *p) #include "sched_stats.h" +static u64 div64_likely32(u64 divident, unsigned long divisor) +{ +#if BITS_PER_LONG == 32 + if (likely(divident <= 0xffffffffULL)) + return (u32)divident / divisor; + do_div(divident, divisor); + + return divident; +#else + return divident / divisor; +#endif +} + +#if BITS_PER_LONG == 32 +# define WMULT_CONST (~0UL) +#else +# define WMULT_CONST (1UL << 32) +#endif + +#define WMULT_SHIFT 32 + +static inline unsigned long +calc_delta_mine(unsigned long delta_exec, unsigned long weight, + struct load_weight *lw) +{ + u64 tmp; + + if (unlikely(!lw->inv_weight)) + lw->inv_weight = WMULT_CONST / lw->weight; + + tmp = (u64)delta_exec * weight; + /* + * Check whether we'd overflow the 64-bit multiplication: + */ + if (unlikely(tmp > WMULT_CONST)) { + tmp = ((tmp >> WMULT_SHIFT/2) * lw->inv_weight) + >> (WMULT_SHIFT/2); + } else { + tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT; + } + + return (unsigned long)min(tmp, (u64)sysctl_sched_runtime_limit); +} + +static inline unsigned long +calc_delta_fair(unsigned long delta_exec, struct load_weight *lw) +{ + return calc_delta_mine(delta_exec, NICE_0_LOAD, lw); +} + +static void update_load_add(struct load_weight *lw, unsigned long inc) +{ + lw->weight += inc; + lw->inv_weight = 0; +} + +static void update_load_sub(struct load_weight *lw, unsigned long dec) +{ + lw->weight -= dec; + lw->inv_weight = 0; +} + +static void __update_curr_load(struct rq *rq, struct load_stat *ls) +{ + if (rq->curr != rq->idle && ls->load.weight) { + ls->delta_exec += ls->delta_stat; + ls->delta_fair += calc_delta_fair(ls->delta_stat, &ls->load); + ls->delta_stat = 0; + } +} + +/* + * Update delta_exec, delta_fair fields for rq. + * + * delta_fair clock advances at a rate inversely proportional to + * total load (rq->ls.load.weight) on the runqueue, while + * delta_exec advances at the same rate as wall-clock (provided + * cpu is not idle). + * + * delta_exec / delta_fair is a measure of the (smoothened) load on this + * runqueue over any given interval. This (smoothened) load is used + * during load balance. + * + * This function is called /before/ updating rq->ls.load + * and when switching tasks. + */ +static void update_curr_load(struct rq *rq, u64 now) +{ + struct load_stat *ls = &rq->ls; + u64 start; + + start = ls->load_update_start; + ls->load_update_start = now; + ls->delta_stat += now - start; + /* + * Stagger updates to ls->delta_fair. Very frequent updates + * can be expensive. + */ + if (ls->delta_stat >= sysctl_sched_stat_granularity) + __update_curr_load(rq, ls); +} + /* * To aid in avoiding the subversion of "niceness" due to uneven distribution * of tasks with abnormal "nice" values across CPUs the contribution that @@ -693,24 +795,6 @@ static inline void resched_task(struct task_struct *p) #define RTPRIO_TO_LOAD_WEIGHT(rp) \ (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + LOAD_WEIGHT(rp)) -static void set_load_weight(struct task_struct *p) -{ - if (task_has_rt_policy(p)) { -#ifdef CONFIG_SMP - if (p == task_rq(p)->migration_thread) - /* - * The migration thread does the actual balancing. - * Giving its load any weight will skew balancing - * adversely. - */ - p->load_weight = 0; - else -#endif - p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority); - } else - p->load_weight = PRIO_TO_LOAD_WEIGHT(p->static_prio); -} - static inline void inc_raw_weighted_load(struct rq *rq, const struct task_struct *p) { @@ -735,6 +819,24 @@ static inline void dec_nr_running(struct task_struct *p, struct rq *rq) dec_raw_weighted_load(rq, p); } +static void set_load_weight(struct task_struct *p) +{ + if (task_has_rt_policy(p)) { +#ifdef CONFIG_SMP + if (p == task_rq(p)->migration_thread) + /* + * The migration thread does the actual balancing. + * Giving its load any weight will skew balancing + * adversely. + */ + p->load_weight = 0; + else +#endif + p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority); + } else + p->load_weight = PRIO_TO_LOAD_WEIGHT(p->static_prio); +} + /* * Adding/removing a task to/from a priority array: */ From f2ac58ee617fd9f6cd9922fbcd291b661d7c9954 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 256/551] sched: remove sleep_type remove the sleep_type heuristics from the core scheduler - scheduling policy is implemented in the scheduling-policy modules. (and CFS does not use this type of sleep-type heuristics) Signed-off-by: Ingo Molnar --- include/linux/sched.h | 8 ---- kernel/sched.c | 91 +------------------------------------------ 2 files changed, 2 insertions(+), 97 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 4dcc61cca00a..be2460e6f55b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -788,13 +788,6 @@ struct mempolicy; struct pipe_inode_info; struct uts_namespace; -enum sleep_type { - SLEEP_NORMAL, - SLEEP_NONINTERACTIVE, - SLEEP_INTERACTIVE, - SLEEP_INTERRUPTED, -}; - struct prio_array; struct rq; struct sched_domain; @@ -905,7 +898,6 @@ struct task_struct { unsigned long sleep_avg; unsigned long long timestamp, last_ran; unsigned long long sched_time; /* sched_clock time spent running */ - enum sleep_type sleep_type; unsigned int policy; cpumask_t cpus_allowed; diff --git a/kernel/sched.c b/kernel/sched.c index 6e5a89ba4f76..26795adab3ad 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -990,32 +990,7 @@ static int recalc_task_prio(struct task_struct *p, unsigned long long now) * with one single large enough sleep. */ p->sleep_avg = ceiling; - /* - * Using INTERACTIVE_SLEEP() as a ceiling places a - * nice(0) task 1ms sleep away from promotion, and - * gives it 700ms to round-robin with no chance of - * being demoted. This is more than generous, so - * mark this sleep as non-interactive to prevent the - * on-runqueue bonus logic from intervening should - * this task not receive cpu immediately. - */ - p->sleep_type = SLEEP_NONINTERACTIVE; } else { - /* - * Tasks waking from uninterruptible sleep are - * limited in their sleep_avg rise as they - * are likely to be waiting on I/O - */ - if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) { - if (p->sleep_avg >= ceiling) - sleep_time = 0; - else if (p->sleep_avg + sleep_time >= - ceiling) { - p->sleep_avg = ceiling; - sleep_time = 0; - } - } - /* * This code gives a bonus to interactive tasks. * @@ -1069,29 +1044,6 @@ static void activate_task(struct task_struct *p, struct rq *rq, int local) } p->prio = recalc_task_prio(p, now); - - /* - * This checks to make sure it's not an uninterruptible task - * that is now waking up. - */ - if (p->sleep_type == SLEEP_NORMAL) { - /* - * Tasks which were woken up by interrupts (ie. hw events) - * are most likely of interactive nature. So we give them - * the credit of extending their sleep time to the period - * of time they spend on the runqueue, waiting for execution - * on a CPU, first time around: - */ - if (in_interrupt()) - p->sleep_type = SLEEP_INTERRUPTED; - else { - /* - * Normal first-time wakeups get a credit too for - * on-runqueue time, but it will be weighted down: - */ - p->sleep_type = SLEEP_INTERACTIVE; - } - } p->timestamp = now; out: __activate_task(p, rq); @@ -1641,23 +1593,8 @@ out_set_cpu: out_activate: #endif /* CONFIG_SMP */ - if (old_state == TASK_UNINTERRUPTIBLE) { + if (old_state == TASK_UNINTERRUPTIBLE) rq->nr_uninterruptible--; - /* - * Tasks on involuntary sleep don't earn - * sleep_avg beyond just interactive state. - */ - p->sleep_type = SLEEP_NONINTERACTIVE; - } else - - /* - * Tasks that have marked their sleep as noninteractive get - * woken up with their sleep average not weighted in an - * interactive way. - */ - if (old_state & TASK_NONINTERACTIVE) - p->sleep_type = SLEEP_NONINTERACTIVE; - activate_task(p, rq, cpu == this_cpu); /* @@ -3533,12 +3470,6 @@ EXPORT_SYMBOL(sub_preempt_count); #endif -static inline int interactive_sleep(enum sleep_type sleep_type) -{ - return (sleep_type == SLEEP_INTERACTIVE || - sleep_type == SLEEP_INTERRUPTED); -} - /* * schedule() is the main scheduler function. */ @@ -3549,7 +3480,7 @@ asmlinkage void __sched schedule(void) struct list_head *queue; unsigned long long now; unsigned long run_time; - int cpu, idx, new_prio; + int cpu, idx; long *switch_count; struct rq *rq; @@ -3642,24 +3573,6 @@ need_resched_nonpreemptible: queue = array->queue + idx; next = list_entry(queue->next, struct task_struct, run_list); - if (!rt_task(next) && interactive_sleep(next->sleep_type)) { - unsigned long long delta = now - next->timestamp; - if (unlikely((long long)(now - next->timestamp) < 0)) - delta = 0; - - if (next->sleep_type == SLEEP_INTERACTIVE) - delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; - - array = next->array; - new_prio = recalc_task_prio(next, next->timestamp + delta); - - if (unlikely(next->prio != new_prio)) { - dequeue_task(next, array); - next->prio = new_prio; - enqueue_task(next, array); - } - } - next->sleep_type = SLEEP_NORMAL; switch_tasks: if (next == rq->idle) schedstat_inc(rq, sched_goidle); From c18a17329b3389315e8a138d998b217077509c13 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 257/551] sched: remove expired_starving() remove the expired_starving() heuristics from the core scheduler. CFS does not need it, and this did not really work well in practice anyway, due to the rq->nr_running multiplier to STARVATION_LIMIT. Signed-off-by: Ingo Molnar --- kernel/sched.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 26795adab3ad..8e44da609c9b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3240,27 +3240,6 @@ unsigned long long task_sched_runtime(struct task_struct *p) return ns; } -/* - * We place interactive tasks back into the active array, if possible. - * - * To guarantee that this does not starve expired tasks we ignore the - * interactivity of a task if the first expired task had to wait more - * than a 'reasonable' amount of time. This deadline timeout is - * load-dependent, as the frequency of array switched decreases with - * increasing number of running tasks. We also ignore the interactivity - * if a better static_prio task has expired: - */ -static inline int expired_starving(struct rq *rq) -{ - if (rq->curr->static_prio > rq->best_expired_prio) - return 1; - if (!STARVATION_LIMIT || !rq->expired_timestamp) - return 0; - if (jiffies - rq->expired_timestamp > STARVATION_LIMIT * rq->nr_running) - return 1; - return 0; -} - /* * Account user cpu time to a process. * @p: the process that the cpu time gets accounted to @@ -3373,7 +3352,7 @@ static void task_running_tick(struct rq *rq, struct task_struct *p) if (!rq->expired_timestamp) rq->expired_timestamp = jiffies; - if (!TASK_INTERACTIVE(p) || expired_starving(rq)) { + if (!TASK_INTERACTIVE(p)) { enqueue_task(p, rq->expired); if (p->static_prio < rq->best_expired_prio) rq->best_expired_prio = p->static_prio; From f3479f10c5d667e591f4417a0bba78e221924206 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 258/551] sched: remove the sleep-bonus interactivity code remove the sleep-bonus interactivity code from the core scheduler. scheduling policy is implemented in the policy modules, and CFS does not need such type of heuristics. Signed-off-by: Ingo Molnar --- kernel/sched.c | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 8e44da609c9b..f5a204b46655 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -894,7 +894,7 @@ static inline int __normal_prio(struct task_struct *p) { int bonus, prio; - bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; + bonus = 0; prio = p->static_prio - bonus; if (prio < MAX_RT_PRIO) @@ -970,42 +970,6 @@ static inline void __activate_idle_task(struct task_struct *p, struct rq *rq) */ static int recalc_task_prio(struct task_struct *p, unsigned long long now) { - /* Caller must always ensure 'now >= p->timestamp' */ - unsigned long sleep_time = now - p->timestamp; - - if (batch_task(p)) - sleep_time = 0; - - if (likely(sleep_time > 0)) { - /* - * This ceiling is set to the lowest priority that would allow - * a task to be reinserted into the active array on timeslice - * completion. - */ - unsigned long ceiling = INTERACTIVE_SLEEP(p); - - if (p->mm && sleep_time > ceiling && p->sleep_avg < ceiling) { - /* - * Prevents user tasks from achieving best priority - * with one single large enough sleep. - */ - p->sleep_avg = ceiling; - } else { - /* - * This code gives a bonus to interactive tasks. - * - * The boost works by updating the 'average sleep time' - * value here, based on ->timestamp. The more time a - * task spends sleeping, the higher the average gets - - * and the higher the priority boost gets as well. - */ - p->sleep_avg += sleep_time; - - } - if (p->sleep_avg > NS_MAX_SLEEP_AVG) - p->sleep_avg = NS_MAX_SLEEP_AVG; - } - return effective_prio(p); } @@ -3560,9 +3524,6 @@ switch_tasks: clear_tsk_need_resched(prev); rcu_qsctr_inc(task_cpu(prev)); - prev->sleep_avg -= run_time; - if ((long)prev->sleep_avg <= 0) - prev->sleep_avg = 0; prev->timestamp = prev->last_ran = now; sched_info_switch(prev, next); @@ -4204,11 +4165,6 @@ static void __setscheduler(struct task_struct *p, int policy, int prio) p->normal_prio = normal_prio(p); /* we are holding p->pi_lock already */ p->prio = rt_mutex_getprio(p); - /* - * SCHED_BATCH tasks are treated as perpetual CPU hogs: - */ - if (policy == SCHED_BATCH) - p->sleep_avg = 0; set_load_weight(p); } @@ -4931,7 +4887,6 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) unsigned long flags; idle->timestamp = sched_clock(); - idle->sleep_avg = 0; idle->array = NULL; idle->prio = idle->normal_prio = MAX_PRIO; idle->state = TASK_RUNNING; From dd41f596cda0d7d6e4a8b139ffdfabcefdd46528 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 259/551] sched: cfs core code apply the CFS core code. this change switches over the scheduler core to CFS's modular design and makes use of kernel/sched_fair/rt/idletask.c to implement Linux's scheduling policies. thanks to Andrew Morton and Thomas Gleixner for lots of detailed review feedback and for fixlets. Signed-off-by: Ingo Molnar Signed-off-by: Mike Galbraith Signed-off-by: Dmitry Adamushko Signed-off-by: Srivatsa Vaddagiri --- kernel/sched.c | 1604 ++++++++++++++++++++++++------------------------ 1 file changed, 794 insertions(+), 810 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index f5a204b46655..01ba4b1848a0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -391,6 +391,11 @@ struct rq { static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp; static DEFINE_MUTEX(sched_hotcpu_mutex); +static inline void check_preempt_curr(struct rq *rq, struct task_struct *p) +{ + rq->curr->sched_class->check_preempt_curr(rq, p); +} + static inline int cpu_of(struct rq *rq) { #ifdef CONFIG_SMP @@ -669,8 +674,6 @@ static inline void resched_task(struct task_struct *p) } #endif -#include "sched_stats.h" - static u64 div64_likely32(u64 divident, unsigned long divisor) { #if BITS_PER_LONG == 32 @@ -788,120 +791,146 @@ static void update_curr_load(struct rq *rq, u64 now) * this code will need modification */ #define TIME_SLICE_NICE_ZERO DEF_TIMESLICE -#define LOAD_WEIGHT(lp) \ +#define load_weight(lp) \ (((lp) * SCHED_LOAD_SCALE) / TIME_SLICE_NICE_ZERO) #define PRIO_TO_LOAD_WEIGHT(prio) \ - LOAD_WEIGHT(static_prio_timeslice(prio)) + load_weight(static_prio_timeslice(prio)) #define RTPRIO_TO_LOAD_WEIGHT(rp) \ - (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + LOAD_WEIGHT(rp)) + (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + load_weight(rp)) + +#define WEIGHT_IDLEPRIO 2 +#define WMULT_IDLEPRIO (1 << 31) + +/* + * Nice levels are multiplicative, with a gentle 10% change for every + * nice level changed. I.e. when a CPU-bound task goes from nice 0 to + * nice 1, it will get ~10% less CPU time than another CPU-bound task + * that remained on nice 0. + * + * The "10% effect" is relative and cumulative: from _any_ nice level, + * if you go up 1 level, it's -10% CPU usage, if you go down 1 level + * it's +10% CPU usage. + */ +static const int prio_to_weight[40] = { +/* -20 */ 88818, 71054, 56843, 45475, 36380, 29104, 23283, 18626, 14901, 11921, +/* -10 */ 9537, 7629, 6103, 4883, 3906, 3125, 2500, 2000, 1600, 1280, +/* 0 */ NICE_0_LOAD /* 1024 */, +/* 1 */ 819, 655, 524, 419, 336, 268, 215, 172, 137, +/* 10 */ 110, 87, 70, 56, 45, 36, 29, 23, 18, 15, +}; + +static const u32 prio_to_wmult[40] = { + 48356, 60446, 75558, 94446, 118058, 147573, + 184467, 230589, 288233, 360285, 450347, + 562979, 703746, 879575, 1099582, 1374389, + 717986, 2147483, 2684354, 3355443, 4194304, + 244160, 6557201, 8196502, 10250518, 12782640, + 16025997, 19976592, 24970740, 31350126, 39045157, + 49367440, 61356675, 76695844, 95443717, 119304647, + 148102320, 186737708, 238609294, 286331153, +}; static inline void -inc_raw_weighted_load(struct rq *rq, const struct task_struct *p) +inc_load(struct rq *rq, const struct task_struct *p, u64 now) { - rq->raw_weighted_load += p->load_weight; + update_curr_load(rq, now); + update_load_add(&rq->ls.load, p->se.load.weight); } static inline void -dec_raw_weighted_load(struct rq *rq, const struct task_struct *p) +dec_load(struct rq *rq, const struct task_struct *p, u64 now) { - rq->raw_weighted_load -= p->load_weight; + update_curr_load(rq, now); + update_load_sub(&rq->ls.load, p->se.load.weight); } -static inline void inc_nr_running(struct task_struct *p, struct rq *rq) +static inline void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now) { rq->nr_running++; - inc_raw_weighted_load(rq, p); + inc_load(rq, p, now); } -static inline void dec_nr_running(struct task_struct *p, struct rq *rq) +static inline void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now) { rq->nr_running--; - dec_raw_weighted_load(rq, p); + dec_load(rq, p, now); } +static void activate_task(struct rq *rq, struct task_struct *p, int wakeup); + +/* + * runqueue iterator, to support SMP load-balancing between different + * scheduling classes, without having to expose their internal data + * structures to the load-balancing proper: + */ +struct rq_iterator { + void *arg; + struct task_struct *(*start)(void *); + struct task_struct *(*next)(void *); +}; + +static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *load_moved, + int this_best_prio, int best_prio, int best_prio_seen, + struct rq_iterator *iterator); + +#include "sched_stats.h" +#include "sched_rt.c" +#include "sched_fair.c" +#include "sched_idletask.c" +#ifdef CONFIG_SCHED_DEBUG +# include "sched_debug.c" +#endif + +#define sched_class_highest (&rt_sched_class) + static void set_load_weight(struct task_struct *p) { + task_rq(p)->cfs.wait_runtime -= p->se.wait_runtime; + p->se.wait_runtime = 0; + if (task_has_rt_policy(p)) { -#ifdef CONFIG_SMP - if (p == task_rq(p)->migration_thread) - /* - * The migration thread does the actual balancing. - * Giving its load any weight will skew balancing - * adversely. - */ - p->load_weight = 0; - else -#endif - p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority); - } else - p->load_weight = PRIO_TO_LOAD_WEIGHT(p->static_prio); + p->se.load.weight = prio_to_weight[0] * 2; + p->se.load.inv_weight = prio_to_wmult[0] >> 1; + return; + } + + /* + * SCHED_IDLE tasks get minimal weight: + */ + if (p->policy == SCHED_IDLE) { + p->se.load.weight = WEIGHT_IDLEPRIO; + p->se.load.inv_weight = WMULT_IDLEPRIO; + return; + } + + p->se.load.weight = prio_to_weight[p->static_prio - MAX_RT_PRIO]; + p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO]; } -/* - * Adding/removing a task to/from a priority array: - */ -static void dequeue_task(struct task_struct *p, struct prio_array *array) -{ - array->nr_active--; - list_del(&p->run_list); - if (list_empty(array->queue + p->prio)) - __clear_bit(p->prio, array->bitmap); -} - -static void enqueue_task(struct task_struct *p, struct prio_array *array) +static void +enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now) { sched_info_queued(p); - list_add_tail(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); - array->nr_active++; - p->array = array; + p->sched_class->enqueue_task(rq, p, wakeup, now); + p->se.on_rq = 1; +} + +static void +dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now) +{ + p->sched_class->dequeue_task(rq, p, sleep, now); + p->se.on_rq = 0; } /* - * Put task to the end of the run list without the overhead of dequeue - * followed by enqueue. + * __normal_prio - return the priority that is based on the static prio */ -static void requeue_task(struct task_struct *p, struct prio_array *array) -{ - list_move_tail(&p->run_list, array->queue + p->prio); -} - -static inline void -enqueue_task_head(struct task_struct *p, struct prio_array *array) -{ - list_add(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); - array->nr_active++; - p->array = array; -} - -/* - * __normal_prio - return the priority that is based on the static - * priority but is modified by bonuses/penalties. - * - * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] - * into the -5 ... 0 ... +5 bonus/penalty range. - * - * We use 25% of the full 0...39 priority range so that: - * - * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. - * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. - * - * Both properties are important to certain workloads. - */ - static inline int __normal_prio(struct task_struct *p) { - int bonus, prio; - - bonus = 0; - - prio = p->static_prio - bonus; - if (prio < MAX_RT_PRIO) - prio = MAX_RT_PRIO; - if (prio > MAX_PRIO-1) - prio = MAX_PRIO-1; - return prio; + return p->static_prio; } /* @@ -943,84 +972,45 @@ static int effective_prio(struct task_struct *p) } /* - * __activate_task - move a task to the runqueue. + * activate_task - move a task to the runqueue. */ -static void __activate_task(struct task_struct *p, struct rq *rq) +static void activate_task(struct rq *rq, struct task_struct *p, int wakeup) { - struct prio_array *target = rq->active; + u64 now = rq_clock(rq); - if (batch_task(p)) - target = rq->expired; - enqueue_task(p, target); - inc_nr_running(p, rq); + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible--; + + enqueue_task(rq, p, wakeup, now); + inc_nr_running(p, rq, now); } /* - * __activate_idle_task - move idle task to the _front_ of runqueue. + * activate_idle_task - move idle task to the _front_ of runqueue. */ -static inline void __activate_idle_task(struct task_struct *p, struct rq *rq) +static inline void activate_idle_task(struct task_struct *p, struct rq *rq) { - enqueue_task_head(p, rq->active); - inc_nr_running(p, rq); -} + u64 now = rq_clock(rq); -/* - * Recalculate p->normal_prio and p->prio after having slept, - * updating the sleep-average too: - */ -static int recalc_task_prio(struct task_struct *p, unsigned long long now) -{ - return effective_prio(p); -} + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible--; -/* - * activate_task - move a task to the runqueue and do priority recalculation - * - * Update all the scheduling statistics stuff. (sleep average - * calculation, priority modifiers, etc.) - */ -static void activate_task(struct task_struct *p, struct rq *rq, int local) -{ - unsigned long long now; - - if (rt_task(p)) - goto out; - - now = sched_clock(); -#ifdef CONFIG_SMP - if (!local) { - /* Compensate for drifting sched_clock */ - struct rq *this_rq = this_rq(); - now = (now - this_rq->most_recent_timestamp) - + rq->most_recent_timestamp; - } -#endif - - /* - * Sleep time is in units of nanosecs, so shift by 20 to get a - * milliseconds-range estimation of the amount of time that the task - * spent sleeping: - */ - if (unlikely(prof_on == SLEEP_PROFILING)) { - if (p->state == TASK_UNINTERRUPTIBLE) - profile_hits(SLEEP_PROFILING, (void *)get_wchan(p), - (now - p->timestamp) >> 20); - } - - p->prio = recalc_task_prio(p, now); - p->timestamp = now; -out: - __activate_task(p, rq); + enqueue_task(rq, p, 0, now); + inc_nr_running(p, rq, now); } /* * deactivate_task - remove a task from the runqueue. */ -static void deactivate_task(struct task_struct *p, struct rq *rq) +static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) { - dec_nr_running(p, rq); - dequeue_task(p, p->array); - p->array = NULL; + u64 now = rq_clock(rq); + + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible++; + + dequeue_task(rq, p, sleep, now); + dec_nr_running(p, rq, now); } /** @@ -1035,14 +1025,40 @@ inline int task_curr(const struct task_struct *p) /* Used instead of source_load when we know the type == 0 */ unsigned long weighted_cpuload(const int cpu) { - return cpu_rq(cpu)->raw_weighted_load; + return cpu_rq(cpu)->ls.load.weight; +} + +static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) +{ +#ifdef CONFIG_SMP + task_thread_info(p)->cpu = cpu; + set_task_cfs_rq(p); +#endif } #ifdef CONFIG_SMP -void set_task_cpu(struct task_struct *p, unsigned int cpu) +void set_task_cpu(struct task_struct *p, unsigned int new_cpu) { - task_thread_info(p)->cpu = cpu; + int old_cpu = task_cpu(p); + struct rq *old_rq = cpu_rq(old_cpu), *new_rq = cpu_rq(new_cpu); + u64 clock_offset, fair_clock_offset; + + clock_offset = old_rq->clock - new_rq->clock; + fair_clock_offset = old_rq->cfs.fair_clock - + new_rq->cfs.fair_clock; + if (p->se.wait_start) + p->se.wait_start -= clock_offset; + if (p->se.wait_start_fair) + p->se.wait_start_fair -= fair_clock_offset; + if (p->se.sleep_start) + p->se.sleep_start -= clock_offset; + if (p->se.block_start) + p->se.block_start -= clock_offset; + if (p->se.sleep_start_fair) + p->se.sleep_start_fair -= fair_clock_offset; + + __set_task_cpu(p, new_cpu); } struct migration_req { @@ -1067,7 +1083,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) * If the task is not on a runqueue (and not running), then * it is sufficient to simply update the task's cpu field. */ - if (!p->array && !task_running(rq, p)) { + if (!p->se.on_rq && !task_running(rq, p)) { set_task_cpu(p, dest_cpu); return 0; } @@ -1092,9 +1108,8 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) void wait_task_inactive(struct task_struct *p) { unsigned long flags; + int running, on_rq; struct rq *rq; - struct prio_array *array; - int running; repeat: /* @@ -1126,7 +1141,7 @@ repeat: */ rq = task_rq_lock(p, &flags); running = task_running(rq, p); - array = p->array; + on_rq = p->se.on_rq; task_rq_unlock(rq, &flags); /* @@ -1149,7 +1164,7 @@ repeat: * running right now), it's preempted, and we should * yield - it could be a while. */ - if (unlikely(array)) { + if (unlikely(on_rq)) { yield(); goto repeat; } @@ -1195,11 +1210,12 @@ void kick_process(struct task_struct *p) static inline unsigned long source_load(int cpu, int type) { struct rq *rq = cpu_rq(cpu); + unsigned long total = weighted_cpuload(cpu); if (type == 0) - return rq->raw_weighted_load; + return total; - return min(rq->cpu_load[type-1], rq->raw_weighted_load); + return min(rq->cpu_load[type-1], total); } /* @@ -1209,11 +1225,12 @@ static inline unsigned long source_load(int cpu, int type) static inline unsigned long target_load(int cpu, int type) { struct rq *rq = cpu_rq(cpu); + unsigned long total = weighted_cpuload(cpu); if (type == 0) - return rq->raw_weighted_load; + return total; - return max(rq->cpu_load[type-1], rq->raw_weighted_load); + return max(rq->cpu_load[type-1], total); } /* @@ -1222,9 +1239,10 @@ static inline unsigned long target_load(int cpu, int type) static inline unsigned long cpu_avg_load_per_task(int cpu) { struct rq *rq = cpu_rq(cpu); + unsigned long total = weighted_cpuload(cpu); unsigned long n = rq->nr_running; - return n ? rq->raw_weighted_load / n : SCHED_LOAD_SCALE; + return n ? total / n : SCHED_LOAD_SCALE; } /* @@ -1455,7 +1473,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) if (!(old_state & state)) goto out; - if (p->array) + if (p->se.on_rq) goto out_running; cpu = task_cpu(p); @@ -1510,11 +1528,11 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) * of the current CPU: */ if (sync) - tl -= current->load_weight; + tl -= current->se.load.weight; if ((tl <= load && tl + target_load(cpu, idx) <= tl_per_task) || - 100*(tl + p->load_weight) <= imbalance*load) { + 100*(tl + p->se.load.weight) <= imbalance*load) { /* * This domain has SD_WAKE_AFFINE and * p is cache cold in this domain, and @@ -1548,7 +1566,7 @@ out_set_cpu: old_state = p->state; if (!(old_state & state)) goto out; - if (p->array) + if (p->se.on_rq) goto out_running; this_cpu = smp_processor_id(); @@ -1557,10 +1575,7 @@ out_set_cpu: out_activate: #endif /* CONFIG_SMP */ - if (old_state == TASK_UNINTERRUPTIBLE) - rq->nr_uninterruptible--; - - activate_task(p, rq, cpu == this_cpu); + activate_task(rq, p, 1); /* * Sync wakeups (i.e. those types of wakeups where the waker * has indicated that it will leave the CPU in short order) @@ -1569,10 +1584,8 @@ out_activate: * the waker guarantees that the freshly woken up task is going * to be considered on this CPU.) */ - if (!sync || cpu != this_cpu) { - if (TASK_PREEMPTS_CURR(p, rq)) - resched_task(rq->curr); - } + if (!sync || cpu != this_cpu) + check_preempt_curr(rq, p); success = 1; out_running: @@ -1595,19 +1608,36 @@ int fastcall wake_up_state(struct task_struct *p, unsigned int state) return try_to_wake_up(p, state, 0); } -static void task_running_tick(struct rq *rq, struct task_struct *p); /* * Perform scheduler related setup for a newly forked process p. * p is forked by current. + * + * __sched_fork() is basic setup used by init_idle() too: */ -void fastcall sched_fork(struct task_struct *p, int clone_flags) +static void __sched_fork(struct task_struct *p) { - int cpu = get_cpu(); + p->se.wait_start_fair = 0; + p->se.wait_start = 0; + p->se.exec_start = 0; + p->se.sum_exec_runtime = 0; + p->se.delta_exec = 0; + p->se.delta_fair_run = 0; + p->se.delta_fair_sleep = 0; + p->se.wait_runtime = 0; + p->se.sum_wait_runtime = 0; + p->se.sum_sleep_runtime = 0; + p->se.sleep_start = 0; + p->se.sleep_start_fair = 0; + p->se.block_start = 0; + p->se.sleep_max = 0; + p->se.block_max = 0; + p->se.exec_max = 0; + p->se.wait_max = 0; + p->se.wait_runtime_overruns = 0; + p->se.wait_runtime_underruns = 0; -#ifdef CONFIG_SMP - cpu = sched_balance_self(cpu, SD_BALANCE_FORK); -#endif - set_task_cpu(p, cpu); + INIT_LIST_HEAD(&p->run_list); + p->se.on_rq = 0; /* * We mark the process as running here, but have not actually @@ -1616,16 +1646,29 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags) * event cannot wake it up and insert it on the runqueue either. */ p->state = TASK_RUNNING; +} + +/* + * fork()/clone()-time setup: + */ +void sched_fork(struct task_struct *p, int clone_flags) +{ + int cpu = get_cpu(); + + __sched_fork(p); + +#ifdef CONFIG_SMP + cpu = sched_balance_self(cpu, SD_BALANCE_FORK); +#endif + __set_task_cpu(p, cpu); /* * Make sure we do not leak PI boosting priority to the child: */ p->prio = current->normal_prio; - INIT_LIST_HEAD(&p->run_list); - p->array = NULL; #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) - if (unlikely(sched_info_on())) + if (likely(sched_info_on())) memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) @@ -1635,33 +1678,15 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags) /* Want to start with kernel preemption disabled. */ task_thread_info(p)->preempt_count = 1; #endif - /* - * Share the timeslice between parent and child, thus the - * total amount of pending timeslices in the system doesn't change, - * resulting in more scheduling fairness. - */ - local_irq_disable(); - p->time_slice = (current->time_slice + 1) >> 1; - /* - * The remainder of the first timeslice might be recovered by - * the parent if the child exits early enough. - */ - p->first_time_slice = 1; - current->time_slice >>= 1; - p->timestamp = sched_clock(); - if (unlikely(!current->time_slice)) { - /* - * This case is rare, it happens when the parent has only - * a single jiffy left from its timeslice. Taking the - * runqueue lock is not a problem. - */ - current->time_slice = 1; - task_running_tick(cpu_rq(cpu), current); - } - local_irq_enable(); put_cpu(); } +/* + * After fork, child runs first. (default) If set to 0 then + * parent will (try to) run first. + */ +unsigned int __read_mostly sysctl_sched_child_runs_first = 1; + /* * wake_up_new_task - wake up a newly created task for the first time. * @@ -1671,77 +1696,28 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags) */ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags) { - struct rq *rq, *this_rq; unsigned long flags; - int this_cpu, cpu; + struct rq *rq; + int this_cpu; rq = task_rq_lock(p, &flags); BUG_ON(p->state != TASK_RUNNING); - this_cpu = smp_processor_id(); - cpu = task_cpu(p); - - /* - * We decrease the sleep average of forking parents - * and children as well, to keep max-interactive tasks - * from forking tasks that are max-interactive. The parent - * (current) is done further down, under its lock. - */ - p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) * - CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); + this_cpu = smp_processor_id(); /* parent's CPU */ p->prio = effective_prio(p); - if (likely(cpu == this_cpu)) { - if (!(clone_flags & CLONE_VM)) { - /* - * The VM isn't cloned, so we're in a good position to - * do child-runs-first in anticipation of an exec. This - * usually avoids a lot of COW overhead. - */ - if (unlikely(!current->array)) - __activate_task(p, rq); - else { - p->prio = current->prio; - p->normal_prio = current->normal_prio; - list_add_tail(&p->run_list, ¤t->run_list); - p->array = current->array; - p->array->nr_active++; - inc_nr_running(p, rq); - } - set_need_resched(); - } else - /* Run child last */ - __activate_task(p, rq); - /* - * We skip the following code due to cpu == this_cpu - * - * task_rq_unlock(rq, &flags); - * this_rq = task_rq_lock(current, &flags); - */ - this_rq = rq; + if (!sysctl_sched_child_runs_first || (clone_flags & CLONE_VM) || + task_cpu(p) != this_cpu || !current->se.on_rq) { + activate_task(rq, p, 0); } else { - this_rq = cpu_rq(this_cpu); - /* - * Not the local CPU - must adjust timestamp. This should - * get optimised away in the !CONFIG_SMP case. + * Let the scheduling class do new task startup + * management (if any): */ - p->timestamp = (p->timestamp - this_rq->most_recent_timestamp) - + rq->most_recent_timestamp; - __activate_task(p, rq); - if (TASK_PREEMPTS_CURR(p, rq)) - resched_task(rq->curr); - - /* - * Parent and child are on different CPUs, now get the - * parent runqueue to update the parent's ->sleep_avg: - */ - task_rq_unlock(rq, &flags); - this_rq = task_rq_lock(current, &flags); + p->sched_class->task_new(rq, p); } - current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) * - PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); - task_rq_unlock(this_rq, &flags); + check_preempt_curr(rq, p); + task_rq_unlock(rq, &flags); } /** @@ -1833,13 +1809,15 @@ asmlinkage void schedule_tail(struct task_struct *prev) * context_switch - switch to the new MM and the new * thread's register state. */ -static inline struct task_struct * +static inline void context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) { - struct mm_struct *mm = next->mm; - struct mm_struct *oldmm = prev->active_mm; + struct mm_struct *mm, *oldmm; + prepare_task_switch(rq, next); + mm = next->mm; + oldmm = prev->active_mm; /* * For paravirt, this is coupled with an exit in switch_to to * combine the page table reload and the switch backend into @@ -1847,16 +1825,15 @@ context_switch(struct rq *rq, struct task_struct *prev, */ arch_enter_lazy_cpu_mode(); - if (!mm) { + if (unlikely(!mm)) { next->active_mm = oldmm; atomic_inc(&oldmm->mm_count); enter_lazy_tlb(oldmm, next); } else switch_mm(oldmm, mm, next); - if (!prev->mm) { + if (unlikely(!prev->mm)) { prev->active_mm = NULL; - WARN_ON(rq->prev_mm); rq->prev_mm = oldmm; } /* @@ -1872,7 +1849,13 @@ context_switch(struct rq *rq, struct task_struct *prev, /* Here we just switch the register state and the stack. */ switch_to(prev, next, prev); - return prev; + barrier(); + /* + * this_rq must be evaluated again because prev may have moved + * CPUs since it called schedule(), thus the 'rq' on its stack + * frame will be invalid. + */ + finish_task_switch(this_rq(), prev); } /* @@ -1945,17 +1928,65 @@ unsigned long nr_active(void) return running + uninterruptible; } -#ifdef CONFIG_SMP - /* - * Is this task likely cache-hot: + * Update rq->cpu_load[] statistics. This function is usually called every + * scheduler tick (TICK_NSEC). */ -static inline int -task_hot(struct task_struct *p, unsigned long long now, struct sched_domain *sd) +static void update_cpu_load(struct rq *this_rq) { - return (long long)(now - p->last_ran) < (long long)sd->cache_hot_time; + u64 fair_delta64, exec_delta64, idle_delta64, sample_interval64, tmp64; + unsigned long total_load = this_rq->ls.load.weight; + unsigned long this_load = total_load; + struct load_stat *ls = &this_rq->ls; + u64 now = __rq_clock(this_rq); + int i, scale; + + this_rq->nr_load_updates++; + if (unlikely(!(sysctl_sched_features & SCHED_FEAT_PRECISE_CPU_LOAD))) + goto do_avg; + + /* Update delta_fair/delta_exec fields first */ + update_curr_load(this_rq, now); + + fair_delta64 = ls->delta_fair + 1; + ls->delta_fair = 0; + + exec_delta64 = ls->delta_exec + 1; + ls->delta_exec = 0; + + sample_interval64 = now - ls->load_update_last; + ls->load_update_last = now; + + if ((s64)sample_interval64 < (s64)TICK_NSEC) + sample_interval64 = TICK_NSEC; + + if (exec_delta64 > sample_interval64) + exec_delta64 = sample_interval64; + + idle_delta64 = sample_interval64 - exec_delta64; + + tmp64 = div64_64(SCHED_LOAD_SCALE * exec_delta64, fair_delta64); + tmp64 = div64_64(tmp64 * exec_delta64, sample_interval64); + + this_load = (unsigned long)tmp64; + +do_avg: + + /* Update our load: */ + for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) { + unsigned long old_load, new_load; + + /* scale is effectively 1 << i now, and >> i divides by scale */ + + old_load = this_rq->cpu_load[i]; + new_load = this_load; + + this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i; + } } +#ifdef CONFIG_SMP + /* * double_rq_lock - safely lock two runqueues * @@ -2072,23 +2103,17 @@ void sched_exec(void) * pull_task - move a task from a remote runqueue to the local runqueue. * Both runqueues must be locked. */ -static void pull_task(struct rq *src_rq, struct prio_array *src_array, - struct task_struct *p, struct rq *this_rq, - struct prio_array *this_array, int this_cpu) +static void pull_task(struct rq *src_rq, struct task_struct *p, + struct rq *this_rq, int this_cpu) { - dequeue_task(p, src_array); - dec_nr_running(p, src_rq); + deactivate_task(src_rq, p, 0); set_task_cpu(p, this_cpu); - inc_nr_running(p, this_rq); - enqueue_task(p, this_array); - p->timestamp = (p->timestamp - src_rq->most_recent_timestamp) - + this_rq->most_recent_timestamp; + activate_task(this_rq, p, 0); /* * Note that idle threads have a prio of MAX_PRIO, for this test * to be always true for them. */ - if (TASK_PREEMPTS_CURR(p, this_rq)) - resched_task(this_rq->curr); + check_preempt_curr(this_rq, p); } /* @@ -2113,25 +2138,81 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, return 0; /* - * Aggressive migration if: - * 1) task is cache cold, or - * 2) too many balance attempts have failed. + * Aggressive migration if too many balance attempts have failed: */ - - if (sd->nr_balance_failed > sd->cache_nice_tries) { -#ifdef CONFIG_SCHEDSTATS - if (task_hot(p, rq->most_recent_timestamp, sd)) - schedstat_inc(sd, lb_hot_gained[idle]); -#endif + if (sd->nr_balance_failed > sd->cache_nice_tries) return 1; - } - if (task_hot(p, rq->most_recent_timestamp, sd)) - return 0; return 1; } -#define rq_best_prio(rq) min((rq)->curr->prio, (rq)->best_expired_prio) +static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *load_moved, + int this_best_prio, int best_prio, int best_prio_seen, + struct rq_iterator *iterator) +{ + int pulled = 0, pinned = 0, skip_for_load; + struct task_struct *p; + long rem_load_move = max_load_move; + + if (max_nr_move == 0 || max_load_move == 0) + goto out; + + pinned = 1; + + /* + * Start the load-balancing iterator: + */ + p = iterator->start(iterator->arg); +next: + if (!p) + goto out; + /* + * To help distribute high priority tasks accross CPUs we don't + * skip a task if it will be the highest priority task (i.e. smallest + * prio value) on its new queue regardless of its load weight + */ + skip_for_load = (p->se.load.weight >> 1) > rem_load_move + + SCHED_LOAD_SCALE_FUZZ; + if (skip_for_load && p->prio < this_best_prio) + skip_for_load = !best_prio_seen && p->prio == best_prio; + if (skip_for_load || + !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) { + + best_prio_seen |= p->prio == best_prio; + p = iterator->next(iterator->arg); + goto next; + } + + pull_task(busiest, p, this_rq, this_cpu); + pulled++; + rem_load_move -= p->se.load.weight; + + /* + * We only want to steal up to the prescribed number of tasks + * and the prescribed amount of weighted load. + */ + if (pulled < max_nr_move && rem_load_move > 0) { + if (p->prio < this_best_prio) + this_best_prio = p->prio; + p = iterator->next(iterator->arg); + goto next; + } +out: + /* + * Right now, this is the only place pull_task() is called, + * so we can safely collect pull_task() stats here rather than + * inside pull_task(). + */ + schedstat_add(sd, lb_gained[idle], pulled); + + if (all_pinned) + *all_pinned = pinned; + *load_moved = max_load_move - rem_load_move; + return pulled; +} /* * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted @@ -2145,112 +2226,21 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, struct sched_domain *sd, enum cpu_idle_type idle, int *all_pinned) { - int idx, pulled = 0, pinned = 0, this_best_prio, best_prio, - best_prio_seen, skip_for_load; - struct prio_array *array, *dst_array; - struct list_head *head, *curr; - struct task_struct *tmp; - long rem_load_move; + struct sched_class *class = sched_class_highest; + unsigned long load_moved, total_nr_moved = 0, nr_moved; + long rem_load_move = max_load_move; - if (max_nr_move == 0 || max_load_move == 0) - goto out; + do { + nr_moved = class->load_balance(this_rq, this_cpu, busiest, + max_nr_move, (unsigned long)rem_load_move, + sd, idle, all_pinned, &load_moved); + total_nr_moved += nr_moved; + max_nr_move -= nr_moved; + rem_load_move -= load_moved; + class = class->next; + } while (class && max_nr_move && rem_load_move > 0); - rem_load_move = max_load_move; - pinned = 1; - this_best_prio = rq_best_prio(this_rq); - best_prio = rq_best_prio(busiest); - /* - * Enable handling of the case where there is more than one task - * with the best priority. If the current running task is one - * of those with prio==best_prio we know it won't be moved - * and therefore it's safe to override the skip (based on load) of - * any task we find with that prio. - */ - best_prio_seen = best_prio == busiest->curr->prio; - - /* - * We first consider expired tasks. Those will likely not be - * executed in the near future, and they are most likely to - * be cache-cold, thus switching CPUs has the least effect - * on them. - */ - if (busiest->expired->nr_active) { - array = busiest->expired; - dst_array = this_rq->expired; - } else { - array = busiest->active; - dst_array = this_rq->active; - } - -new_array: - /* Start searching at priority 0: */ - idx = 0; -skip_bitmap: - if (!idx) - idx = sched_find_first_bit(array->bitmap); - else - idx = find_next_bit(array->bitmap, MAX_PRIO, idx); - if (idx >= MAX_PRIO) { - if (array == busiest->expired && busiest->active->nr_active) { - array = busiest->active; - dst_array = this_rq->active; - goto new_array; - } - goto out; - } - - head = array->queue + idx; - curr = head->prev; -skip_queue: - tmp = list_entry(curr, struct task_struct, run_list); - - curr = curr->prev; - - /* - * To help distribute high priority tasks accross CPUs we don't - * skip a task if it will be the highest priority task (i.e. smallest - * prio value) on its new queue regardless of its load weight - */ - skip_for_load = tmp->load_weight > rem_load_move; - if (skip_for_load && idx < this_best_prio) - skip_for_load = !best_prio_seen && idx == best_prio; - if (skip_for_load || - !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) { - - best_prio_seen |= idx == best_prio; - if (curr != head) - goto skip_queue; - idx++; - goto skip_bitmap; - } - - pull_task(busiest, array, tmp, this_rq, dst_array, this_cpu); - pulled++; - rem_load_move -= tmp->load_weight; - - /* - * We only want to steal up to the prescribed number of tasks - * and the prescribed amount of weighted load. - */ - if (pulled < max_nr_move && rem_load_move > 0) { - if (idx < this_best_prio) - this_best_prio = idx; - if (curr != head) - goto skip_queue; - idx++; - goto skip_bitmap; - } -out: - /* - * Right now, this is the only place pull_task() is called, - * so we can safely collect pull_task() stats here rather than - * inside pull_task(). - */ - schedstat_add(sd, lb_gained[idle], pulled); - - if (all_pinned) - *all_pinned = pinned; - return pulled; + return total_nr_moved; } /* @@ -2260,8 +2250,8 @@ out: */ static struct sched_group * find_busiest_group(struct sched_domain *sd, int this_cpu, - unsigned long *imbalance, enum cpu_idle_type idle, int *sd_idle, - cpumask_t *cpus, int *balance) + unsigned long *imbalance, enum cpu_idle_type idle, + int *sd_idle, cpumask_t *cpus, int *balance) { struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups; unsigned long max_load, avg_load, total_load, this_load, total_pwr; @@ -2325,7 +2315,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, avg_load += load; sum_nr_running += rq->nr_running; - sum_weighted_load += rq->raw_weighted_load; + sum_weighted_load += weighted_cpuload(i); } /* @@ -2365,8 +2355,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, * Busy processors will not participate in power savings * balance. */ - if (idle == CPU_NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) - goto group_next; + if (idle == CPU_NOT_IDLE || + !(sd->flags & SD_POWERSAVINGS_BALANCE)) + goto group_next; /* * If the local group is idle or completely loaded @@ -2376,42 +2367,42 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, !this_nr_running)) power_savings_balance = 0; - /* + /* * If a group is already running at full capacity or idle, * don't include that group in power savings calculations - */ - if (!power_savings_balance || sum_nr_running >= group_capacity + */ + if (!power_savings_balance || sum_nr_running >= group_capacity || !sum_nr_running) - goto group_next; + goto group_next; - /* + /* * Calculate the group which has the least non-idle load. - * This is the group from where we need to pick up the load - * for saving power - */ - if ((sum_nr_running < min_nr_running) || - (sum_nr_running == min_nr_running && + * This is the group from where we need to pick up the load + * for saving power + */ + if ((sum_nr_running < min_nr_running) || + (sum_nr_running == min_nr_running && first_cpu(group->cpumask) < first_cpu(group_min->cpumask))) { - group_min = group; - min_nr_running = sum_nr_running; + group_min = group; + min_nr_running = sum_nr_running; min_load_per_task = sum_weighted_load / sum_nr_running; - } + } - /* + /* * Calculate the group which is almost near its - * capacity but still has some space to pick up some load - * from other group and save more power - */ - if (sum_nr_running <= group_capacity - 1) { - if (sum_nr_running > leader_nr_running || - (sum_nr_running == leader_nr_running && - first_cpu(group->cpumask) > - first_cpu(group_leader->cpumask))) { - group_leader = group; - leader_nr_running = sum_nr_running; - } + * capacity but still has some space to pick up some load + * from other group and save more power + */ + if (sum_nr_running <= group_capacity - 1) { + if (sum_nr_running > leader_nr_running || + (sum_nr_running == leader_nr_running && + first_cpu(group->cpumask) > + first_cpu(group_leader->cpumask))) { + group_leader = group; + leader_nr_running = sum_nr_running; + } } group_next: #endif @@ -2466,7 +2457,7 @@ group_next: * a think about bumping its value to force at least one task to be * moved */ - if (*imbalance < busiest_load_per_task) { + if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task/2) { unsigned long tmp, pwr_now, pwr_move; unsigned int imbn; @@ -2480,7 +2471,8 @@ small_imbalance: } else this_load_per_task = SCHED_LOAD_SCALE; - if (max_load - this_load >= busiest_load_per_task * imbn) { + if (max_load - this_load + SCHED_LOAD_SCALE_FUZZ >= + busiest_load_per_task * imbn) { *imbalance = busiest_load_per_task; return busiest; } @@ -2552,17 +2544,19 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle, int i; for_each_cpu_mask(i, group->cpumask) { + unsigned long wl; if (!cpu_isset(i, *cpus)) continue; rq = cpu_rq(i); + wl = weighted_cpuload(i); - if (rq->nr_running == 1 && rq->raw_weighted_load > imbalance) + if (rq->nr_running == 1 && wl > imbalance) continue; - if (rq->raw_weighted_load > max_load) { - max_load = rq->raw_weighted_load; + if (wl > max_load) { + max_load = wl; busiest = rq; } } @@ -2599,7 +2593,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, /* * When power savings policy is enabled for the parent domain, idle * sibling can pick up load irrespective of busy siblings. In this case, - * let the state of idle sibling percolate up as IDLE, instead of + * let the state of idle sibling percolate up as CPU_IDLE, instead of * portraying it as CPU_NOT_IDLE. */ if (idle != CPU_NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && @@ -2822,8 +2816,8 @@ out_balanced: static void idle_balance(int this_cpu, struct rq *this_rq) { struct sched_domain *sd; - int pulled_task = 0; - unsigned long next_balance = jiffies + 60 * HZ; + int pulled_task = -1; + unsigned long next_balance = jiffies + HZ; for_each_domain(this_cpu, sd) { unsigned long interval; @@ -2842,12 +2836,13 @@ static void idle_balance(int this_cpu, struct rq *this_rq) if (pulled_task) break; } - if (!pulled_task) + if (pulled_task || time_after(jiffies, this_rq->next_balance)) { /* * We are going idle. next_balance may be set based on * a busy processor. So reset next_balance. */ this_rq->next_balance = next_balance; + } } /* @@ -2900,32 +2895,6 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu) spin_unlock(&target_rq->lock); } -static void update_load(struct rq *this_rq) -{ - unsigned long this_load; - unsigned int i, scale; - - this_load = this_rq->raw_weighted_load; - - /* Update our load: */ - for (i = 0, scale = 1; i < 3; i++, scale += scale) { - unsigned long old_load, new_load; - - /* scale is effectively 1 << i now, and >> i divides by scale */ - - old_load = this_rq->cpu_load[i]; - new_load = this_load; - /* - * Round up the averaging division if load is increasing. This - * prevents us from getting stuck on 9 if the load is 10, for - * example. - */ - if (new_load > old_load) - new_load += scale-1; - this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i; - } -} - #ifdef CONFIG_NO_HZ static struct { atomic_t load_balancer; @@ -3029,6 +2998,9 @@ static inline void rebalance_domains(int cpu, enum cpu_idle_type idle) interval = msecs_to_jiffies(interval); if (unlikely(!interval)) interval = 1; + if (interval > HZ*NR_CPUS/10) + interval = HZ*NR_CPUS/10; + if (sd->flags & SD_SERIALIZE) { if (!spin_trylock(&balancing)) @@ -3070,11 +3042,12 @@ out: */ static void run_rebalance_domains(struct softirq_action *h) { - int local_cpu = smp_processor_id(); - struct rq *local_rq = cpu_rq(local_cpu); - enum cpu_idle_type idle = local_rq->idle_at_tick ? CPU_IDLE : CPU_NOT_IDLE; + int this_cpu = smp_processor_id(); + struct rq *this_rq = cpu_rq(this_cpu); + enum cpu_idle_type idle = this_rq->idle_at_tick ? + CPU_IDLE : CPU_NOT_IDLE; - rebalance_domains(local_cpu, idle); + rebalance_domains(this_cpu, idle); #ifdef CONFIG_NO_HZ /* @@ -3082,13 +3055,13 @@ static void run_rebalance_domains(struct softirq_action *h) * balancing on behalf of the other idle cpus whose ticks are * stopped. */ - if (local_rq->idle_at_tick && - atomic_read(&nohz.load_balancer) == local_cpu) { + if (this_rq->idle_at_tick && + atomic_read(&nohz.load_balancer) == this_cpu) { cpumask_t cpus = nohz.cpu_mask; struct rq *rq; int balance_cpu; - cpu_clear(local_cpu, cpus); + cpu_clear(this_cpu, cpus); for_each_cpu_mask(balance_cpu, cpus) { /* * If this cpu gets work to do, stop the load balancing @@ -3098,11 +3071,11 @@ static void run_rebalance_domains(struct softirq_action *h) if (need_resched()) break; - rebalance_domains(balance_cpu, CPU_IDLE); + rebalance_domains(balance_cpu, SCHED_IDLE); rq = cpu_rq(balance_cpu); - if (time_after(local_rq->next_balance, rq->next_balance)) - local_rq->next_balance = rq->next_balance; + if (time_after(this_rq->next_balance, rq->next_balance)) + this_rq->next_balance = rq->next_balance; } } #endif @@ -3115,9 +3088,8 @@ static void run_rebalance_domains(struct softirq_action *h) * idle load balancing owner or decide to stop the periodic load balancing, * if the whole system is idle. */ -static inline void trigger_load_balance(int cpu) +static inline void trigger_load_balance(struct rq *rq, int cpu) { - struct rq *rq = cpu_rq(cpu); #ifdef CONFIG_NO_HZ /* * If we were in the nohz mode recently and busy at the current @@ -3169,13 +3141,29 @@ static inline void trigger_load_balance(int cpu) if (time_after_eq(jiffies, rq->next_balance)) raise_softirq(SCHED_SOFTIRQ); } -#else + +#else /* CONFIG_SMP */ + /* * on UP we do not need to balance between CPUs: */ static inline void idle_balance(int cpu, struct rq *rq) { } + +/* Avoid "used but not defined" warning on UP */ +static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_nr_move, unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, unsigned long *load_moved, + int this_best_prio, int best_prio, int best_prio_seen, + struct rq_iterator *iterator) +{ + *load_moved = 0; + + return 0; +} + #endif DEFINE_PER_CPU(struct kernel_stat, kstat); @@ -3277,81 +3265,6 @@ void account_steal_time(struct task_struct *p, cputime_t steal) cpustat->steal = cputime64_add(cpustat->steal, tmp); } -static void task_running_tick(struct rq *rq, struct task_struct *p) -{ - if (p->array != rq->active) { - /* Task has expired but was not scheduled yet */ - set_tsk_need_resched(p); - return; - } - spin_lock(&rq->lock); - /* - * The task was running during this tick - update the - * time slice counter. Note: we do not update a thread's - * priority until it either goes to sleep or uses up its - * timeslice. This makes it possible for interactive tasks - * to use up their timeslices at their highest priority levels. - */ - if (rt_task(p)) { - /* - * RR tasks need a special form of timeslice management. - * FIFO tasks have no timeslices. - */ - if ((p->policy == SCHED_RR) && !--p->time_slice) { - p->time_slice = task_timeslice(p); - p->first_time_slice = 0; - set_tsk_need_resched(p); - - /* put it at the end of the queue: */ - requeue_task(p, rq->active); - } - goto out_unlock; - } - if (!--p->time_slice) { - dequeue_task(p, rq->active); - set_tsk_need_resched(p); - p->prio = effective_prio(p); - p->time_slice = task_timeslice(p); - p->first_time_slice = 0; - - if (!rq->expired_timestamp) - rq->expired_timestamp = jiffies; - if (!TASK_INTERACTIVE(p)) { - enqueue_task(p, rq->expired); - if (p->static_prio < rq->best_expired_prio) - rq->best_expired_prio = p->static_prio; - } else - enqueue_task(p, rq->active); - } else { - /* - * Prevent a too long timeslice allowing a task to monopolize - * the CPU. We do this by splitting up the timeslice into - * smaller pieces. - * - * Note: this does not mean the task's timeslices expire or - * get lost in any way, they just might be preempted by - * another task of equal priority. (one with higher - * priority would have preempted this task already.) We - * requeue this task to the end of the list on this priority - * level, which is in essence a round-robin of tasks with - * equal priority. - * - * This only applies to tasks in the interactive - * delta range with at least TIMESLICE_GRANULARITY to requeue. - */ - if (TASK_INTERACTIVE(p) && !((task_timeslice(p) - - p->time_slice) % TIMESLICE_GRANULARITY(p)) && - (p->time_slice >= TIMESLICE_GRANULARITY(p)) && - (p->array == rq->active)) { - - requeue_task(p, rq->active); - set_tsk_need_resched(p); - } - } -out_unlock: - spin_unlock(&rq->lock); -} - /* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. @@ -3361,17 +3274,19 @@ out_unlock: */ void scheduler_tick(void) { - struct task_struct *p = current; int cpu = smp_processor_id(); - int idle_at_tick = idle_cpu(cpu); struct rq *rq = cpu_rq(cpu); + struct task_struct *curr = rq->curr; + + spin_lock(&rq->lock); + if (curr != rq->idle) /* FIXME: needed? */ + curr->sched_class->task_tick(rq, curr); + update_cpu_load(rq); + spin_unlock(&rq->lock); - if (!idle_at_tick) - task_running_tick(rq, p); #ifdef CONFIG_SMP - update_load(rq); - rq->idle_at_tick = idle_at_tick; - trigger_load_balance(cpu); + rq->idle_at_tick = idle_cpu(cpu); + trigger_load_balance(rq, cpu); #endif } @@ -3414,140 +3329,128 @@ EXPORT_SYMBOL(sub_preempt_count); #endif /* - * schedule() is the main scheduler function. + * Print scheduling while atomic bug: */ -asmlinkage void __sched schedule(void) +static noinline void __schedule_bug(struct task_struct *prev) { - struct task_struct *prev, *next; - struct prio_array *array; - struct list_head *queue; - unsigned long long now; - unsigned long run_time; - int cpu, idx; - long *switch_count; - struct rq *rq; + printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n", + prev->comm, preempt_count(), prev->pid); + debug_show_held_locks(prev); + if (irqs_disabled()) + print_irqtrace_events(prev); + dump_stack(); +} +/* + * Various schedule()-time debugging checks and statistics: + */ +static inline void schedule_debug(struct task_struct *prev) +{ /* * Test if we are atomic. Since do_exit() needs to call into * schedule() atomically, we ignore that path for now. * Otherwise, whine if we are scheduling when we should not be. */ - if (unlikely(in_atomic() && !current->exit_state)) { - printk(KERN_ERR "BUG: scheduling while atomic: " - "%s/0x%08x/%d\n", - current->comm, preempt_count(), current->pid); - debug_show_held_locks(current); - if (irqs_disabled()) - print_irqtrace_events(current); - dump_stack(); - } + if (unlikely(in_atomic_preempt_off()) && unlikely(!prev->exit_state)) + __schedule_bug(prev); + profile_hit(SCHED_PROFILING, __builtin_return_address(0)); + schedstat_inc(this_rq(), sched_cnt); +} + +/* + * Pick up the highest-prio task: + */ +static inline struct task_struct * +pick_next_task(struct rq *rq, struct task_struct *prev, u64 now) +{ + struct sched_class *class; + struct task_struct *p; + + /* + * Optimization: we know that if all tasks are in + * the fair class we can call that function directly: + */ + if (likely(rq->nr_running == rq->cfs.nr_running)) { + p = fair_sched_class.pick_next_task(rq, now); + if (likely(p)) + return p; + } + + class = sched_class_highest; + for ( ; ; ) { + p = class->pick_next_task(rq, now); + if (p) + return p; + /* + * Will never be NULL as the idle class always + * returns a non-NULL p: + */ + class = class->next; + } +} + +/* + * schedule() is the main scheduler function. + */ +asmlinkage void __sched schedule(void) +{ + struct task_struct *prev, *next; + long *switch_count; + struct rq *rq; + u64 now; + int cpu; + need_resched: preempt_disable(); - prev = current; + cpu = smp_processor_id(); + rq = cpu_rq(cpu); + rcu_qsctr_inc(cpu); + prev = rq->curr; + switch_count = &prev->nivcsw; + release_kernel_lock(prev); need_resched_nonpreemptible: - rq = this_rq(); - /* - * The idle thread is not allowed to schedule! - * Remove this check after it has been exercised a bit. - */ - if (unlikely(prev == rq->idle) && prev->state != TASK_RUNNING) { - printk(KERN_ERR "bad: scheduling from the idle thread!\n"); - dump_stack(); - } - - schedstat_inc(rq, sched_cnt); - now = sched_clock(); - if (likely((long long)(now - prev->timestamp) < NS_MAX_SLEEP_AVG)) { - run_time = now - prev->timestamp; - if (unlikely((long long)(now - prev->timestamp) < 0)) - run_time = 0; - } else - run_time = NS_MAX_SLEEP_AVG; - - /* - * Tasks charged proportionately less run_time at high sleep_avg to - * delay them losing their interactive status - */ - run_time /= (CURRENT_BONUS(prev) ? : 1); + schedule_debug(prev); spin_lock_irq(&rq->lock); - - switch_count = &prev->nivcsw; - if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { - switch_count = &prev->nvcsw; - if (unlikely((prev->state & TASK_INTERRUPTIBLE) && - unlikely(signal_pending(prev)))) - prev->state = TASK_RUNNING; - else { - if (prev->state == TASK_UNINTERRUPTIBLE) - rq->nr_uninterruptible++; - deactivate_task(prev, rq); - } - } - - cpu = smp_processor_id(); - if (unlikely(!rq->nr_running)) { - idle_balance(cpu, rq); - if (!rq->nr_running) { - next = rq->idle; - rq->expired_timestamp = 0; - goto switch_tasks; - } - } - - array = rq->active; - if (unlikely(!array->nr_active)) { - /* - * Switch the active and expired arrays. - */ - schedstat_inc(rq, sched_switch); - rq->active = rq->expired; - rq->expired = array; - array = rq->active; - rq->expired_timestamp = 0; - rq->best_expired_prio = MAX_PRIO; - } - - idx = sched_find_first_bit(array->bitmap); - queue = array->queue + idx; - next = list_entry(queue->next, struct task_struct, run_list); - -switch_tasks: - if (next == rq->idle) - schedstat_inc(rq, sched_goidle); - prefetch(next); - prefetch_stack(next); clear_tsk_need_resched(prev); - rcu_qsctr_inc(task_cpu(prev)); - prev->timestamp = prev->last_ran = now; + if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { + if (unlikely((prev->state & TASK_INTERRUPTIBLE) && + unlikely(signal_pending(prev)))) { + prev->state = TASK_RUNNING; + } else { + deactivate_task(rq, prev, 1); + } + switch_count = &prev->nvcsw; + } + + if (unlikely(!rq->nr_running)) + idle_balance(cpu, rq); + + now = __rq_clock(rq); + prev->sched_class->put_prev_task(rq, prev, now); + next = pick_next_task(rq, prev, now); sched_info_switch(prev, next); + if (likely(prev != next)) { - next->timestamp = next->last_ran = now; rq->nr_switches++; rq->curr = next; ++*switch_count; - prepare_task_switch(rq, next); - prev = context_switch(rq, prev, next); - barrier(); - /* - * this_rq must be evaluated again because prev may have moved - * CPUs since it called schedule(), thus the 'rq' on its stack - * frame will be invalid. - */ - finish_task_switch(this_rq(), prev); + context_switch(rq, prev, next); /* unlocks the rq */ } else spin_unlock_irq(&rq->lock); - prev = current; - if (unlikely(reacquire_kernel_lock(prev) < 0)) + if (unlikely(reacquire_kernel_lock(current) < 0)) { + cpu = smp_processor_id(); + rq = cpu_rq(cpu); goto need_resched_nonpreemptible; + } preempt_enable_no_resched(); if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) goto need_resched; @@ -3959,29 +3862,30 @@ EXPORT_SYMBOL(sleep_on_timeout); */ void rt_mutex_setprio(struct task_struct *p, int prio) { - struct prio_array *array; unsigned long flags; + int oldprio, on_rq; struct rq *rq; - int oldprio; + u64 now; BUG_ON(prio < 0 || prio > MAX_PRIO); rq = task_rq_lock(p, &flags); + now = rq_clock(rq); oldprio = p->prio; - array = p->array; - if (array) - dequeue_task(p, array); + on_rq = p->se.on_rq; + if (on_rq) + dequeue_task(rq, p, 0, now); + + if (rt_prio(prio)) + p->sched_class = &rt_sched_class; + else + p->sched_class = &fair_sched_class; + p->prio = prio; - if (array) { - /* - * If changing to an RT priority then queue it - * in the active array! - */ - if (rt_task(p)) - array = rq->active; - enqueue_task(p, array); + if (on_rq) { + enqueue_task(rq, p, 0, now); /* * Reschedule if we are currently running on this runqueue and * our priority decreased, or if we are not currently running on @@ -3990,8 +3894,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio) if (task_running(rq, p)) { if (p->prio > oldprio) resched_task(rq->curr); - } else if (TASK_PREEMPTS_CURR(p, rq)) - resched_task(rq->curr); + } else { + check_preempt_curr(rq, p); + } } task_rq_unlock(rq, &flags); } @@ -4000,10 +3905,10 @@ void rt_mutex_setprio(struct task_struct *p, int prio) void set_user_nice(struct task_struct *p, long nice) { - struct prio_array *array; - int old_prio, delta; + int old_prio, delta, on_rq; unsigned long flags; struct rq *rq; + u64 now; if (TASK_NICE(p) == nice || nice < -20 || nice > 19) return; @@ -4012,20 +3917,21 @@ void set_user_nice(struct task_struct *p, long nice) * the task might be in the middle of scheduling on another CPU. */ rq = task_rq_lock(p, &flags); + now = rq_clock(rq); /* * The RT priorities are set via sched_setscheduler(), but we still * allow the 'normal' nice value to be set - but as expected * it wont have any effect on scheduling until the task is - * not SCHED_NORMAL/SCHED_BATCH: + * SCHED_FIFO/SCHED_RR: */ if (task_has_rt_policy(p)) { p->static_prio = NICE_TO_PRIO(nice); goto out_unlock; } - array = p->array; - if (array) { - dequeue_task(p, array); - dec_raw_weighted_load(rq, p); + on_rq = p->se.on_rq; + if (on_rq) { + dequeue_task(rq, p, 0, now); + dec_load(rq, p, now); } p->static_prio = NICE_TO_PRIO(nice); @@ -4034,9 +3940,9 @@ void set_user_nice(struct task_struct *p, long nice) p->prio = effective_prio(p); delta = p->prio - old_prio; - if (array) { - enqueue_task(p, array); - inc_raw_weighted_load(rq, p); + if (on_rq) { + enqueue_task(rq, p, 0, now); + inc_load(rq, p, now); /* * If the task increased its priority or is running and * lowered its priority, then reschedule its CPU: @@ -4156,11 +4062,24 @@ static inline struct task_struct *find_process_by_pid(pid_t pid) } /* Actually do priority change: must hold rq lock. */ -static void __setscheduler(struct task_struct *p, int policy, int prio) +static void +__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) { - BUG_ON(p->array); + BUG_ON(p->se.on_rq); p->policy = policy; + switch (p->policy) { + case SCHED_NORMAL: + case SCHED_BATCH: + case SCHED_IDLE: + p->sched_class = &fair_sched_class; + break; + case SCHED_FIFO: + case SCHED_RR: + p->sched_class = &rt_sched_class; + break; + } + p->rt_priority = prio; p->normal_prio = normal_prio(p); /* we are holding p->pi_lock already */ @@ -4179,8 +4098,7 @@ static void __setscheduler(struct task_struct *p, int policy, int prio) int sched_setscheduler(struct task_struct *p, int policy, struct sched_param *param) { - int retval, oldprio, oldpolicy = -1; - struct prio_array *array; + int retval, oldprio, oldpolicy = -1, on_rq; unsigned long flags; struct rq *rq; @@ -4191,12 +4109,13 @@ recheck: if (policy < 0) policy = oldpolicy = p->policy; else if (policy != SCHED_FIFO && policy != SCHED_RR && - policy != SCHED_NORMAL && policy != SCHED_BATCH) + policy != SCHED_NORMAL && policy != SCHED_BATCH && + policy != SCHED_IDLE) return -EINVAL; /* * Valid priorities for SCHED_FIFO and SCHED_RR are - * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL and - * SCHED_BATCH is 0. + * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, + * SCHED_BATCH and SCHED_IDLE is 0. */ if (param->sched_priority < 0 || (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) || @@ -4211,7 +4130,6 @@ recheck: if (!capable(CAP_SYS_NICE)) { if (rt_policy(policy)) { unsigned long rlim_rtprio; - unsigned long flags; if (!lock_task_sighand(p, &flags)) return -ESRCH; @@ -4227,6 +4145,12 @@ recheck: param->sched_priority > rlim_rtprio) return -EPERM; } + /* + * Like positive nice levels, dont allow tasks to + * move out of SCHED_IDLE either: + */ + if (p->policy == SCHED_IDLE && policy != SCHED_IDLE) + return -EPERM; /* can't change other user's priorities */ if ((current->euid != p->euid) && @@ -4254,13 +4178,13 @@ recheck: spin_unlock_irqrestore(&p->pi_lock, flags); goto recheck; } - array = p->array; - if (array) - deactivate_task(p, rq); + on_rq = p->se.on_rq; + if (on_rq) + deactivate_task(rq, p, 0); oldprio = p->prio; - __setscheduler(p, policy, param->sched_priority); - if (array) { - __activate_task(p, rq); + __setscheduler(rq, p, policy, param->sched_priority); + if (on_rq) { + activate_task(rq, p, 0); /* * Reschedule if we are currently running on this runqueue and * our priority decreased, or if we are not currently running on @@ -4269,8 +4193,9 @@ recheck: if (task_running(rq, p)) { if (p->prio > oldprio) resched_task(rq->curr); - } else if (TASK_PREEMPTS_CURR(p, rq)) - resched_task(rq->curr); + } else { + check_preempt_curr(rq, p); + } } __task_rq_unlock(rq); spin_unlock_irqrestore(&p->pi_lock, flags); @@ -4542,41 +4467,18 @@ asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, /** * sys_sched_yield - yield the current processor to other threads. * - * This function yields the current CPU by moving the calling thread - * to the expired array. If there are no other threads running on this - * CPU then this function will return. + * This function yields the current CPU to other tasks. If there are no + * other threads running on this CPU then this function will return. */ asmlinkage long sys_sched_yield(void) { struct rq *rq = this_rq_lock(); - struct prio_array *array = current->array, *target = rq->expired; schedstat_inc(rq, yld_cnt); - /* - * We implement yielding by moving the task into the expired - * queue. - * - * (special rule: RT tasks will just roundrobin in the active - * array.) - */ - if (rt_task(current)) - target = rq->active; - - if (array->nr_active == 1) { + if (unlikely(rq->nr_running == 1)) schedstat_inc(rq, yld_act_empty); - if (!rq->expired->nr_active) - schedstat_inc(rq, yld_both_empty); - } else if (!rq->expired->nr_active) - schedstat_inc(rq, yld_exp_empty); - - if (array != target) { - dequeue_task(current, array); - enqueue_task(current, target); - } else - /* - * requeue_task is cheaper so perform that if possible. - */ - requeue_task(current, array); + else + current->sched_class->yield_task(rq, current); /* * Since we are going to call schedule() anyway, there's @@ -4727,6 +4629,7 @@ asmlinkage long sys_sched_get_priority_max(int policy) break; case SCHED_NORMAL: case SCHED_BATCH: + case SCHED_IDLE: ret = 0; break; } @@ -4751,6 +4654,7 @@ asmlinkage long sys_sched_get_priority_min(int policy) break; case SCHED_NORMAL: case SCHED_BATCH: + case SCHED_IDLE: ret = 0; } return ret; @@ -4785,7 +4689,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) goto out_unlock; jiffies_to_timespec(p->policy == SCHED_FIFO ? - 0 : task_timeslice(p), &t); + 0 : static_prio_timeslice(p->static_prio), &t); read_unlock(&tasklist_lock); retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0; out_nounlock: @@ -4860,6 +4764,9 @@ void show_state_filter(unsigned long state_filter) touch_all_softlockup_watchdogs(); +#ifdef CONFIG_SCHED_DEBUG + sysrq_sched_debug_show(); +#endif read_unlock(&tasklist_lock); /* * Only show locks if all tasks are dumped: @@ -4870,7 +4777,7 @@ void show_state_filter(unsigned long state_filter) void __cpuinit init_idle_bootup_task(struct task_struct *idle) { - /* nothing yet */ + idle->sched_class = &idle_sched_class; } /** @@ -4886,12 +4793,12 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) struct rq *rq = cpu_rq(cpu); unsigned long flags; - idle->timestamp = sched_clock(); - idle->array = NULL; + __sched_fork(idle); + idle->se.exec_start = sched_clock(); + idle->prio = idle->normal_prio = MAX_PRIO; - idle->state = TASK_RUNNING; idle->cpus_allowed = cpumask_of_cpu(cpu); - set_task_cpu(idle, cpu); + __set_task_cpu(idle, cpu); spin_lock_irqsave(&rq->lock, flags); rq->curr = rq->idle = idle; @@ -4906,6 +4813,10 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) #else task_thread_info(idle)->preempt_count = 0; #endif + /* + * The idle tasks have their own, simple scheduling class: + */ + idle->sched_class = &idle_sched_class; } /* @@ -4917,6 +4828,28 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) */ cpumask_t nohz_cpu_mask = CPU_MASK_NONE; +/* + * Increase the granularity value when there are more CPUs, + * because with more CPUs the 'effective latency' as visible + * to users decreases. But the relationship is not linear, + * so pick a second-best guess by going with the log2 of the + * number of CPUs. + * + * This idea comes from the SD scheduler of Con Kolivas: + */ +static inline void sched_init_granularity(void) +{ + unsigned int factor = 1 + ilog2(num_online_cpus()); + const unsigned long gran_limit = 10000000; + + sysctl_sched_granularity *= factor; + if (sysctl_sched_granularity > gran_limit) + sysctl_sched_granularity = gran_limit; + + sysctl_sched_runtime_limit = sysctl_sched_granularity * 4; + sysctl_sched_wakeup_granularity = sysctl_sched_granularity / 2; +} + #ifdef CONFIG_SMP /* * This is how migration works: @@ -4990,7 +4923,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed); static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) { struct rq *rq_dest, *rq_src; - int ret = 0; + int ret = 0, on_rq; if (unlikely(cpu_is_offline(dest_cpu))) return ret; @@ -5006,20 +4939,13 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) if (!cpu_isset(dest_cpu, p->cpus_allowed)) goto out; + on_rq = p->se.on_rq; + if (on_rq) + deactivate_task(rq_src, p, 0); set_task_cpu(p, dest_cpu); - if (p->array) { - /* - * Sync timestamp with rq_dest's before activating. - * The same thing could be achieved by doing this step - * afterwards, and pretending it was a local activate. - * This way is cleaner and logically correct. - */ - p->timestamp = p->timestamp - rq_src->most_recent_timestamp - + rq_dest->most_recent_timestamp; - deactivate_task(p, rq_src); - __activate_task(p, rq_dest); - if (TASK_PREEMPTS_CURR(p, rq_dest)) - resched_task(rq_dest->curr); + if (on_rq) { + activate_task(rq_dest, p, 0); + check_preempt_curr(rq_dest, p); } ret = 1; out: @@ -5171,7 +5097,8 @@ static void migrate_live_tasks(int src_cpu) write_unlock_irq(&tasklist_lock); } -/* Schedules idle task to be the next runnable task on current CPU. +/* + * Schedules idle task to be the next runnable task on current CPU. * It does so by boosting its priority to highest possible and adding it to * the _front_ of the runqueue. Used by CPU offline code. */ @@ -5191,10 +5118,10 @@ void sched_idle_next(void) */ spin_lock_irqsave(&rq->lock, flags); - __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1); + __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); /* Add idle task to the _front_ of its priority queue: */ - __activate_idle_task(p, rq); + activate_idle_task(p, rq); spin_unlock_irqrestore(&rq->lock, flags); } @@ -5244,16 +5171,15 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) static void migrate_dead_tasks(unsigned int dead_cpu) { struct rq *rq = cpu_rq(dead_cpu); - unsigned int arr, i; + struct task_struct *next; - for (arr = 0; arr < 2; arr++) { - for (i = 0; i < MAX_PRIO; i++) { - struct list_head *list = &rq->arrays[arr].queue[i]; - - while (!list_empty(list)) - migrate_dead(dead_cpu, list_entry(list->next, - struct task_struct, run_list)); - } + for ( ; ; ) { + if (!rq->nr_running) + break; + next = pick_next_task(rq, rq->curr, rq_clock(rq)); + if (!next) + break; + migrate_dead(dead_cpu, next); } } #endif /* CONFIG_HOTPLUG_CPU */ @@ -5277,14 +5203,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: - p = kthread_create(migration_thread, hcpu, "migration/%d",cpu); + p = kthread_create(migration_thread, hcpu, "migration/%d", cpu); if (IS_ERR(p)) return NOTIFY_BAD; p->flags |= PF_NOFREEZE; kthread_bind(p, cpu); /* Must be high prio: stop_machine expects to yield to it. */ rq = task_rq_lock(p, &flags); - __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1); + __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); task_rq_unlock(rq, &flags); cpu_rq(cpu)->migration_thread = p; break; @@ -5315,9 +5241,10 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) rq->migration_thread = NULL; /* Idle task back to normal (off runqueue, low prio) */ rq = task_rq_lock(rq->idle, &flags); - deactivate_task(rq->idle, rq); + deactivate_task(rq, rq->idle, 0); rq->idle->static_prio = MAX_PRIO; - __setscheduler(rq->idle, SCHED_NORMAL, 0); + __setscheduler(rq, rq->idle, SCHED_NORMAL, 0); + rq->idle->sched_class = &idle_sched_class; migrate_dead_tasks(cpu); task_rq_unlock(rq, &flags); migrate_nr_uninterruptible(rq); @@ -5926,7 +5853,6 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd) static int build_sched_domains(const cpumask_t *cpu_map) { int i; - struct sched_domain *sd; #ifdef CONFIG_NUMA struct sched_group **sched_group_nodes = NULL; int sd_allnodes = 0; @@ -5934,7 +5860,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) /* * Allocate the per-node list of sched groups */ - sched_group_nodes = kzalloc(sizeof(struct sched_group*)*MAX_NUMNODES, + sched_group_nodes = kzalloc(sizeof(struct sched_group *)*MAX_NUMNODES, GFP_KERNEL); if (!sched_group_nodes) { printk(KERN_WARNING "Can not alloc sched group node list\n"); @@ -5953,8 +5879,8 @@ static int build_sched_domains(const cpumask_t *cpu_map) cpus_and(nodemask, nodemask, *cpu_map); #ifdef CONFIG_NUMA - if (cpus_weight(*cpu_map) - > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { + if (cpus_weight(*cpu_map) > + SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { sd = &per_cpu(allnodes_domains, i); *sd = SD_ALLNODES_INIT; sd->span = *cpu_map; @@ -6013,7 +5939,8 @@ static int build_sched_domains(const cpumask_t *cpu_map) if (i != first_cpu(this_sibling_map)) continue; - init_sched_build_groups(this_sibling_map, cpu_map, &cpu_to_cpu_group); + init_sched_build_groups(this_sibling_map, cpu_map, + &cpu_to_cpu_group); } #endif @@ -6024,11 +5951,11 @@ static int build_sched_domains(const cpumask_t *cpu_map) cpus_and(this_core_map, this_core_map, *cpu_map); if (i != first_cpu(this_core_map)) continue; - init_sched_build_groups(this_core_map, cpu_map, &cpu_to_core_group); + init_sched_build_groups(this_core_map, cpu_map, + &cpu_to_core_group); } #endif - /* Set up physical groups */ for (i = 0; i < MAX_NUMNODES; i++) { cpumask_t nodemask = node_to_cpumask(i); @@ -6043,7 +5970,8 @@ static int build_sched_domains(const cpumask_t *cpu_map) #ifdef CONFIG_NUMA /* Set up node groups */ if (sd_allnodes) - init_sched_build_groups(*cpu_map, cpu_map, &cpu_to_allnodes_group); + init_sched_build_groups(*cpu_map, cpu_map, + &cpu_to_allnodes_group); for (i = 0; i < MAX_NUMNODES; i++) { /* Set up node groups */ @@ -6115,19 +6043,22 @@ static int build_sched_domains(const cpumask_t *cpu_map) /* Calculate CPU power for physical packages and nodes */ #ifdef CONFIG_SCHED_SMT for_each_cpu_mask(i, *cpu_map) { - sd = &per_cpu(cpu_domains, i); + struct sched_domain *sd = &per_cpu(cpu_domains, i); + init_sched_groups_power(i, sd); } #endif #ifdef CONFIG_SCHED_MC for_each_cpu_mask(i, *cpu_map) { - sd = &per_cpu(core_domains, i); + struct sched_domain *sd = &per_cpu(core_domains, i); + init_sched_groups_power(i, sd); } #endif for_each_cpu_mask(i, *cpu_map) { - sd = &per_cpu(phys_domains, i); + struct sched_domain *sd = &per_cpu(phys_domains, i); + init_sched_groups_power(i, sd); } @@ -6361,10 +6292,12 @@ void __init sched_init_smp(void) /* Move init over to a non-isolated CPU */ if (set_cpus_allowed(current, non_isolated_cpus) < 0) BUG(); + sched_init_granularity(); } #else void __init sched_init_smp(void) { + sched_init_granularity(); } #endif /* CONFIG_SMP */ @@ -6378,28 +6311,51 @@ int in_sched_functions(unsigned long addr) && addr < (unsigned long)__sched_text_end); } +static inline void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) +{ + cfs_rq->tasks_timeline = RB_ROOT; + cfs_rq->fair_clock = 1; +#ifdef CONFIG_FAIR_GROUP_SCHED + cfs_rq->rq = rq; +#endif +} + void __init sched_init(void) { - int i, j, k; + u64 now = sched_clock(); int highest_cpu = 0; + int i, j; + + /* + * Link up the scheduling class hierarchy: + */ + rt_sched_class.next = &fair_sched_class; + fair_sched_class.next = &idle_sched_class; + idle_sched_class.next = NULL; for_each_possible_cpu(i) { - struct prio_array *array; + struct rt_prio_array *array; struct rq *rq; rq = cpu_rq(i); spin_lock_init(&rq->lock); lockdep_set_class(&rq->lock, &rq->rq_lock_key); rq->nr_running = 0; - rq->active = rq->arrays; - rq->expired = rq->arrays + 1; - rq->best_expired_prio = MAX_PRIO; + rq->clock = 1; + init_cfs_rq(&rq->cfs, rq); +#ifdef CONFIG_FAIR_GROUP_SCHED + INIT_LIST_HEAD(&rq->leaf_cfs_rq_list); + list_add(&rq->cfs.leaf_cfs_rq_list, &rq->leaf_cfs_rq_list); +#endif + rq->ls.load_update_last = now; + rq->ls.load_update_start = now; + for (j = 0; j < CPU_LOAD_IDX_MAX; j++) + rq->cpu_load[j] = 0; #ifdef CONFIG_SMP rq->sd = NULL; - for (j = 1; j < 3; j++) - rq->cpu_load[j] = 0; rq->active_balance = 0; + rq->next_balance = jiffies; rq->push_cpu = 0; rq->cpu = i; rq->migration_thread = NULL; @@ -6407,16 +6363,14 @@ void __init sched_init(void) #endif atomic_set(&rq->nr_iowait, 0); - for (j = 0; j < 2; j++) { - array = rq->arrays + j; - for (k = 0; k < MAX_PRIO; k++) { - INIT_LIST_HEAD(array->queue + k); - __clear_bit(k, array->bitmap); - } - // delimiter for bitsearch - __set_bit(MAX_PRIO, array->bitmap); + array = &rq->rt.active; + for (j = 0; j < MAX_RT_PRIO; j++) { + INIT_LIST_HEAD(array->queue + j); + __clear_bit(j, array->bitmap); } highest_cpu = i; + /* delimiter for bitsearch: */ + __set_bit(MAX_RT_PRIO, array->bitmap); } set_load_weight(&init_task); @@ -6443,6 +6397,10 @@ void __init sched_init(void) * when this runqueue becomes "idle". */ init_idle(current, smp_processor_id()); + /* + * During early bootup we pretend to be a normal task: + */ + current->sched_class = &fair_sched_class; } #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP @@ -6473,29 +6431,55 @@ EXPORT_SYMBOL(__might_sleep); #ifdef CONFIG_MAGIC_SYSRQ void normalize_rt_tasks(void) { - struct prio_array *array; struct task_struct *g, *p; unsigned long flags; struct rq *rq; + int on_rq; read_lock_irq(&tasklist_lock); - do_each_thread(g, p) { - if (!rt_task(p)) + p->se.fair_key = 0; + p->se.wait_runtime = 0; + p->se.wait_start_fair = 0; + p->se.wait_start = 0; + p->se.exec_start = 0; + p->se.sleep_start = 0; + p->se.sleep_start_fair = 0; + p->se.block_start = 0; + task_rq(p)->cfs.fair_clock = 0; + task_rq(p)->clock = 0; + + if (!rt_task(p)) { + /* + * Renice negative nice level userspace + * tasks back to 0: + */ + if (TASK_NICE(p) < 0 && p->mm) + set_user_nice(p, 0); continue; + } spin_lock_irqsave(&p->pi_lock, flags); rq = __task_rq_lock(p); +#ifdef CONFIG_SMP + /* + * Do not touch the migration thread: + */ + if (p == rq->migration_thread) + goto out_unlock; +#endif - array = p->array; - if (array) - deactivate_task(p, task_rq(p)); - __setscheduler(p, SCHED_NORMAL, 0); - if (array) { - __activate_task(p, task_rq(p)); + on_rq = p->se.on_rq; + if (on_rq) + deactivate_task(task_rq(p), p, 0); + __setscheduler(rq, p, SCHED_NORMAL, 0); + if (on_rq) { + activate_task(task_rq(p), p, 0); resched_task(rq->curr); } - +#ifdef CONFIG_SMP + out_unlock: +#endif __task_rq_unlock(rq); spin_unlock_irqrestore(&p->pi_lock, flags); } while_each_thread(g, p); From bb29ab26863c022743143f27956cc0ca362f258c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 260/551] sched: x86, track TSC-unstable events track TSC-unstable events and propagate it to the scheduler code. Also allow sched_clock() to be used when the TSC is unstable, the rq_clock() wrapper creates a reliable clock out of it. Signed-off-by: Ingo Molnar --- arch/i386/kernel/tsc.c | 9 ++++++++- include/linux/sched.h | 2 ++ kernel/sched.c | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index f64b81f3033b..ea63a30ca3e8 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -4,6 +4,7 @@ * See comments there for proper credits. */ +#include #include #include #include @@ -106,8 +107,13 @@ unsigned long long sched_clock(void) /* * Fall back to jiffies if there's no TSC available: + * ( But note that we still use it if the TSC is marked + * unstable. We do this because unlike Time Of Day, + * the scheduler clock tolerates small errors and it's + * very important for it to be as fast as the platform + * can achive it. ) */ - if (unlikely(!tsc_enabled)) + if (unlikely(!tsc_enabled && !tsc_unstable)) /* No locking but a rare wrong value is not a big deal: */ return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); @@ -277,6 +283,7 @@ static struct clocksource clocksource_tsc = { void mark_tsc_unstable(char *reason) { + sched_clock_unstable_event(); if (!tsc_unstable) { tsc_unstable = 1; tsc_enabled = 0; diff --git a/include/linux/sched.h b/include/linux/sched.h index be2460e6f55b..fa895b309da0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1321,6 +1321,8 @@ extern void sched_exec(void); #define sched_exec() {} #endif +extern void sched_clock_unstable_event(void); + #ifdef CONFIG_HOTPLUG_CPU extern void idle_task_exit(void); #else diff --git a/kernel/sched.c b/kernel/sched.c index 01ba4b1848a0..6150cd70f448 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -67,6 +67,13 @@ unsigned long long __attribute__((weak)) sched_clock(void) return (unsigned long long)jiffies * (1000000000 / HZ); } +/* + * CPU frequency is/was unstable - start new by setting prev_clock_raw: + */ +void sched_clock_unstable_event(void) +{ +} + /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], From 1b9f19c2125dd1021b9327111dc40b14b557ee12 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 261/551] sched: turn on the use of unstable events make use of sched-clock-unstable events. Signed-off-by: Ingo Molnar --- kernel/sched.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 6150cd70f448..2d23450e7614 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -67,13 +67,6 @@ unsigned long long __attribute__((weak)) sched_clock(void) return (unsigned long long)jiffies * (1000000000 / HZ); } -/* - * CPU frequency is/was unstable - start new by setting prev_clock_raw: - */ -void sched_clock_unstable_event(void) -{ -} - /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], @@ -629,6 +622,20 @@ static inline struct rq *this_rq_lock(void) return rq; } +/* + * CPU frequency is/was unstable - start new by setting prev_clock_raw: + */ +void sched_clock_unstable_event(void) +{ + unsigned long flags; + struct rq *rq; + + rq = task_rq_lock(current, &flags); + rq->prev_clock_raw = sched_clock(); + rq->clock_unstable_events++; + task_rq_unlock(rq, &flags); +} + /* * resched_task - mark a task 'to be rescheduled now'. * From b27f03d4bdc145a09fb7b0c0e004b29f1ee555fa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:51:59 +0200 Subject: [PATCH 262/551] sched: make use of precise accounting for /proc task stats make use of CFS's precise accounting to drive /proc//stat statistics. this code was co-authored by: Balbir Singh Dmitry Adamushko Ingo Molnar Signed-off-by: Ingo Molnar Signed-off-by: Dmitry Adamushko --- fs/proc/array.c | 57 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index 3df644313f9b..98e78e2f18d6 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -310,6 +310,41 @@ int proc_pid_status(struct task_struct *task, char * buffer) return buffer - orig; } +static clock_t task_utime(struct task_struct *p) +{ + clock_t utime = cputime_to_clock_t(p->utime), + total = utime + cputime_to_clock_t(p->stime); + u64 temp; + + /* + * Use CFS's precise accounting: + */ + temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime); + + if (total) { + temp *= utime; + do_div(temp, total); + } + utime = (clock_t)temp; + + return utime; +} + +static clock_t task_stime(struct task_struct *p) +{ + clock_t stime = cputime_to_clock_t(p->stime); + + /* + * Use CFS's precise accounting. (we subtract utime from + * the total, to make sure the total observed by userspace + * grows monotonically - apps rely on that): + */ + stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p); + + return stime; +} + + static int do_task_stat(struct task_struct *task, char * buffer, int whole) { unsigned long vsize, eip, esp, wchan = ~0UL; @@ -324,7 +359,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) unsigned long long start_time; unsigned long cmin_flt = 0, cmaj_flt = 0; unsigned long min_flt = 0, maj_flt = 0; - cputime_t cutime, cstime, utime, stime; + cputime_t cutime, cstime; + clock_t utime, stime; unsigned long rsslim = 0; char tcomm[sizeof(task->comm)]; unsigned long flags; @@ -342,7 +378,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) sigemptyset(&sigign); sigemptyset(&sigcatch); - cutime = cstime = utime = stime = cputime_zero; + cutime = cstime = cputime_zero; + utime = stime = 0; rcu_read_lock(); if (lock_task_sighand(task, &flags)) { @@ -368,15 +405,15 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) do { min_flt += t->min_flt; maj_flt += t->maj_flt; - utime = cputime_add(utime, t->utime); - stime = cputime_add(stime, t->stime); + utime += task_utime(t); + stime += task_stime(t); t = next_thread(t); } while (t != task); min_flt += sig->min_flt; maj_flt += sig->maj_flt; - utime = cputime_add(utime, sig->utime); - stime = cputime_add(stime, sig->stime); + utime += cputime_to_clock_t(sig->utime); + stime += cputime_to_clock_t(sig->stime); } sid = signal_session(sig); @@ -392,8 +429,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) if (!whole) { min_flt = task->min_flt; maj_flt = task->maj_flt; - utime = task->utime; - stime = task->stime; + utime = task_utime(task); + stime = task_stime(task); } /* scale priority and nice values from timeslices to -20..20 */ @@ -424,8 +461,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) cmin_flt, maj_flt, cmaj_flt, - cputime_to_clock_t(utime), - cputime_to_clock_t(stime), + utime, + stime, cputime_to_clock_t(cutime), cputime_to_clock_t(cstime), priority, From 172ba844a8851c3edd13c0a979cdf46bd5e3cc1a Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 263/551] sched: update delay-accounting to use CFS's precise stats update delay-accounting to use CFS's precise stats. Signed-off-by: Ingo Molnar --- fs/proc/base.c | 2 +- include/linux/sched.h | 10 +++++----- kernel/delayacct.c | 10 +++++----- kernel/exit.c | 2 +- kernel/fork.c | 4 ++-- kernel/sched_stats.h | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index a5fa1fdafc4e..0f40e820c7fd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -296,7 +296,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer) */ static int proc_pid_schedstat(struct task_struct *task, char *buffer) { - return sprintf(buffer, "%lu %lu %lu\n", + return sprintf(buffer, "%llu %llu %lu\n", task->sched_info.cpu_time, task->sched_info.run_delay, task->sched_info.pcnt); diff --git a/include/linux/sched.h b/include/linux/sched.h index fa895b309da0..e64dbd4cd829 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -562,13 +562,13 @@ struct reclaim_state; #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) struct sched_info { /* cumulative counters */ - unsigned long cpu_time, /* time spent on the cpu */ - run_delay, /* time spent waiting on a runqueue */ - pcnt; /* # of timeslices run on this cpu */ + unsigned long pcnt; /* # of times run on this cpu */ + unsigned long long cpu_time, /* time spent on the cpu */ + run_delay; /* time spent waiting on a runqueue */ /* timestamps */ - unsigned long last_arrival, /* when we last ran on a cpu */ - last_queued; /* when we were last queued to run */ + unsigned long long last_arrival,/* when we last ran on a cpu */ + last_queued; /* when we were last queued to run */ }; #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ diff --git a/kernel/delayacct.c b/kernel/delayacct.c index c0148ae992c4..81e697829633 100644 --- a/kernel/delayacct.c +++ b/kernel/delayacct.c @@ -99,9 +99,10 @@ void __delayacct_blkio_end(void) int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) { s64 tmp; - struct timespec ts; - unsigned long t1,t2,t3; + unsigned long t1; + unsigned long long t2, t3; unsigned long flags; + struct timespec ts; /* Though tsk->delays accessed later, early exit avoids * unnecessary returning of other data @@ -124,11 +125,10 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) d->cpu_count += t1; - jiffies_to_timespec(t2, &ts); - tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts); + tmp = (s64)d->cpu_delay_total + t2; d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp; - tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000; + tmp = (s64)d->cpu_run_virtual_total + t3; d->cpu_run_virtual_total = (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp; diff --git a/kernel/exit.c b/kernel/exit.c index 8fd7acd7bbd0..ca6a11b73023 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -122,9 +122,9 @@ static void __exit_signal(struct task_struct *tsk) sig->maj_flt += tsk->maj_flt; sig->nvcsw += tsk->nvcsw; sig->nivcsw += tsk->nivcsw; - sig->sched_time += tsk->sched_time; sig->inblock += task_io_get_inblock(tsk); sig->oublock += task_io_get_oublock(tsk); + sig->sum_sched_runtime += tsk->se.sum_exec_runtime; sig = NULL; /* Marker for below. */ } diff --git a/kernel/fork.c b/kernel/fork.c index 73ad5cda1bcd..da3a155bba0d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -877,7 +877,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; - sig->sched_time = 0; + sig->sum_sched_runtime = 0; INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); @@ -1040,7 +1040,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->utime = cputime_zero; p->stime = cputime_zero; - p->sched_time = 0; + #ifdef CONFIG_TASK_XACCT p->rchar = 0; /* I/O counter: bytes read */ p->wchar = 0; /* I/O counter: bytes written */ diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index cd82c6078904..c63c38f6fa6e 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -21,7 +21,7 @@ static int show_schedstat(struct seq_file *seq, void *v) /* runqueue-specific stats */ seq_printf(seq, - "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu", cpu, rq->yld_both_empty, rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt, rq->sched_switch, rq->sched_cnt, rq->sched_goidle, From ad46c2c4ebcead75cd364a79b63b134393094fb9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 264/551] sched: clean up fastcall uses of sched_fork()/sched_exit() sched_fork()/sched_exit() does not need to specify fastcall anymore, as the x86 kernel defaults to regparm3, and no assembly code calls these functions. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index e64dbd4cd829..ce0c5adc9eb0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1416,8 +1416,8 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, #else static inline void kick_process(struct task_struct *tsk) { } #endif -extern void FASTCALL(sched_fork(struct task_struct * p, int clone_flags)); -extern void FASTCALL(sched_exit(struct task_struct * p)); +extern void sched_fork(struct task_struct *p, int clone_flags); +extern void sched_dead(struct task_struct *p); extern int in_group_p(gid_t); extern int in_egroup_p(gid_t); From dff06c157b6089b774514337769a3c1b7ccccf6c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 265/551] sched: clean up include files in sched.c clean up include files in sched.c, they were still old-style . Signed-off-by: Ingo Molnar --- kernel/sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 2d23450e7614..7ce959e0b69a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -53,9 +53,9 @@ #include #include #include +#include #include -#include /* * Scheduler clock - returns current time in nanosec units. From 634fa8c97cc8f4ee2ae1dea7200ff0df762405e7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 266/551] sched: remove interactivity types remove now unused interactivity-heuristics related defined and types of the old scheduler. Signed-off-by: Ingo Molnar --- kernel/sched.c | 105 +++++++------------------------------------------ 1 file changed, 14 insertions(+), 91 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 7ce959e0b69a..886531c681c1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -103,87 +103,6 @@ unsigned long long __attribute__((weak)) sched_clock(void) */ #define MIN_TIMESLICE max(5 * HZ / 1000, 1) #define DEF_TIMESLICE (100 * HZ / 1000) -#define ON_RUNQUEUE_WEIGHT 30 -#define CHILD_PENALTY 95 -#define PARENT_PENALTY 100 -#define EXIT_WEIGHT 3 -#define PRIO_BONUS_RATIO 25 -#define MAX_BONUS (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100) -#define INTERACTIVE_DELTA 2 -#define MAX_SLEEP_AVG (DEF_TIMESLICE * MAX_BONUS) -#define STARVATION_LIMIT (MAX_SLEEP_AVG) -#define NS_MAX_SLEEP_AVG (JIFFIES_TO_NS(MAX_SLEEP_AVG)) - -/* - * If a task is 'interactive' then we reinsert it in the active - * array after it has expired its current timeslice. (it will not - * continue to run immediately, it will still roundrobin with - * other interactive tasks.) - * - * This part scales the interactivity limit depending on niceness. - * - * We scale it linearly, offset by the INTERACTIVE_DELTA delta. - * Here are a few examples of different nice levels: - * - * TASK_INTERACTIVE(-20): [1,1,1,1,1,1,1,1,1,0,0] - * TASK_INTERACTIVE(-10): [1,1,1,1,1,1,1,0,0,0,0] - * TASK_INTERACTIVE( 0): [1,1,1,1,0,0,0,0,0,0,0] - * TASK_INTERACTIVE( 10): [1,1,0,0,0,0,0,0,0,0,0] - * TASK_INTERACTIVE( 19): [0,0,0,0,0,0,0,0,0,0,0] - * - * (the X axis represents the possible -5 ... 0 ... +5 dynamic - * priority range a task can explore, a value of '1' means the - * task is rated interactive.) - * - * Ie. nice +19 tasks can never get 'interactive' enough to be - * reinserted into the active array. And only heavily CPU-hog nice -20 - * tasks will be expired. Default nice 0 tasks are somewhere between, - * it takes some effort for them to get interactive, but it's not - * too hard. - */ - -#define CURRENT_BONUS(p) \ - (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \ - MAX_SLEEP_AVG) - -#define GRANULARITY (10 * HZ / 1000 ? : 1) - -#ifdef CONFIG_SMP -#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \ - (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \ - num_online_cpus()) -#else -#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \ - (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1))) -#endif - -#define SCALE(v1,v1_max,v2_max) \ - (v1) * (v2_max) / (v1_max) - -#define DELTA(p) \ - (SCALE(TASK_NICE(p) + 20, 40, MAX_BONUS) - 20 * MAX_BONUS / 40 + \ - INTERACTIVE_DELTA) - -#define TASK_INTERACTIVE(p) \ - ((p)->prio <= (p)->static_prio - DELTA(p)) - -#define INTERACTIVE_SLEEP(p) \ - (JIFFIES_TO_NS(MAX_SLEEP_AVG * \ - (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1)) - -#define TASK_PREEMPTS_CURR(p, rq) \ - ((p)->prio < (rq)->curr->prio) - -#define SCALE_PRIO(x, prio) \ - max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE) - -static unsigned int static_prio_timeslice(int static_prio) -{ - if (static_prio < NICE_TO_PRIO(0)) - return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio); - else - return SCALE_PRIO(DEF_TIMESLICE, static_prio); -} #ifdef CONFIG_SMP /* @@ -206,18 +125,22 @@ static inline void sg_inc_cpu_power(struct sched_group *sg, u32 val) } #endif -/* - * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ] - * to time slice values: [800ms ... 100ms ... 5ms] - * - * The higher a thread's priority, the bigger timeslices - * it gets during one round of execution. But even the lowest - * priority thread gets MIN_TIMESLICE worth of execution time. - */ +#define SCALE_PRIO(x, prio) \ + max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE) -static inline unsigned int task_timeslice(struct task_struct *p) +/* + * static_prio_timeslice() scales user-nice values [ -20 ... 0 ... 19 ] + * to time slice values: [800ms ... 100ms ... 5ms] + */ +static unsigned int static_prio_timeslice(int static_prio) { - return static_prio_timeslice(p->static_prio); + if (static_prio == NICE_TO_PRIO(19)) + return 1; + + if (static_prio < NICE_TO_PRIO(0)) + return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio); + else + return SCALE_PRIO(DEF_TIMESLICE, static_prio); } static inline int rt_policy(int policy) From 50e645a8a1a91f57dd5d8454620be5f1cb0fc089 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 267/551] sched: remove interactivity types from sched.h remove now-unused types/fields used by the old scheduler. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index ce0c5adc9eb0..efa3beb007ff 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -788,7 +788,6 @@ struct mempolicy; struct pipe_inode_info; struct uts_namespace; -struct prio_array; struct rq; struct sched_domain; @@ -884,10 +883,9 @@ struct task_struct { int oncpu; #endif #endif - int load_weight; /* for niceness load balancing purposes */ + int prio, static_prio, normal_prio; struct list_head run_list; - struct prio_array *array; struct sched_class *sched_class; struct sched_entity se; @@ -895,13 +893,10 @@ struct task_struct { #ifdef CONFIG_BLK_DEV_IO_TRACE unsigned int btrace_seq; #endif - unsigned long sleep_avg; - unsigned long long timestamp, last_ran; - unsigned long long sched_time; /* sched_clock time spent running */ unsigned int policy; cpumask_t cpus_allowed; - unsigned int time_slice, first_time_slice; + unsigned int time_slice; #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) struct sched_info sched_info; From 0c57d5893e4a9857ff22ec9e379f6bdbdad50850 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 268/551] sched: remove batch_task() batch_task() in sched.h is now unused - remove it. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index efa3beb007ff..aa582be8cafa 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1157,11 +1157,6 @@ static inline int rt_task(struct task_struct *p) return rt_prio(p->prio); } -static inline int batch_task(struct task_struct *p) -{ - return p->policy == SCHED_BATCH; -} - static inline pid_t process_group(struct task_struct *tsk) { return tsk->signal->pgrp; From b2cfba19f67228e78e48177187f6b07f4107c784 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 269/551] sched: remove unused rq types from sched.c remove unused rq types from sched.c, now that we switched over to CFS. Signed-off-by: Ingo Molnar --- kernel/sched.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 886531c681c1..f8cf78c6af2e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -208,15 +208,6 @@ struct rt_rq { struct list_head *rt_load_balance_head, *rt_load_balance_curr; }; -/* - * The prio-array type of the old scheduler: - */ -struct prio_array { - unsigned int nr_active; - DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */ - struct list_head queue[MAX_PRIO]; -}; - /* * This is the main, per-CPU runqueue data structure. * @@ -232,7 +223,6 @@ struct rq { * remote CPUs use both these fields when doing load calculation. */ unsigned long nr_running; - unsigned long raw_weighted_load; #define CPU_LOAD_IDX_MAX 5 unsigned long cpu_load[CPU_LOAD_IDX_MAX]; unsigned char idle_at_tick; @@ -257,16 +247,10 @@ struct rq { */ unsigned long nr_uninterruptible; - unsigned long expired_timestamp; - unsigned long long most_recent_timestamp; - struct task_struct *curr, *idle; unsigned long next_balance; struct mm_struct *prev_mm; - struct prio_array *active, *expired, arrays[2]; - int best_expired_prio; - u64 clock, prev_clock_raw; s64 clock_max_delta; From 7dd593608df3f9d4e4531cfe29f28c3a3766a0ee Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 270/551] sched: remove old cpu accounting field remove the old cpu-accounting field from signal_struct, now that the code is using CFS's stats. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index aa582be8cafa..c9d65738bb7a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -482,7 +482,6 @@ struct signal_struct { * from jiffies_to_ns(utime + stime) if sched_clock uses something * other than jiffies.) */ - unsigned long sched_time; unsigned long long sum_sched_runtime; /* From 77e54a1f88a1cb0746c7694fa40052bd02df1123 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 271/551] sched: add CFS debug sysctls add CFS debug sysctls: only tweakable if SCHED_DEBUG is enabled. This allows for faster debugging of scheduler problems. Signed-off-by: Ingo Molnar --- kernel/sysctl.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 30ee462ee79f..51f5dac42a00 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -206,7 +206,87 @@ static ctl_table root_table[] = { { .ctl_name = 0 } }; +#ifdef CONFIG_SCHED_DEBUG +static unsigned long min_sched_granularity_ns = 100000; /* 100 usecs */ +static unsigned long max_sched_granularity_ns = 1000000000; /* 1 second */ +static unsigned long min_wakeup_granularity_ns; /* 0 usecs */ +static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */ +#endif + static ctl_table kern_table[] = { +#ifdef CONFIG_SCHED_DEBUG + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_granularity_ns", + .data = &sysctl_sched_granularity, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_sched_granularity_ns, + .extra2 = &max_sched_granularity_ns, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_wakeup_granularity_ns", + .data = &sysctl_sched_wakeup_granularity, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_wakeup_granularity_ns, + .extra2 = &max_wakeup_granularity_ns, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_batch_wakeup_granularity_ns", + .data = &sysctl_sched_batch_wakeup_granularity, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_wakeup_granularity_ns, + .extra2 = &max_wakeup_granularity_ns, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_stat_granularity_ns", + .data = &sysctl_sched_stat_granularity, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_wakeup_granularity_ns, + .extra2 = &max_wakeup_granularity_ns, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_runtime_limit_ns", + .data = &sysctl_sched_runtime_limit, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &min_sched_granularity_ns, + .extra2 = &max_sched_granularity_ns, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_child_runs_first", + .data = &sysctl_sched_child_runs_first, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "sched_features", + .data = &sysctl_sched_features, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif { .ctl_name = KERN_PANIC, .procname = "panic", From 43ae34cb4cd650d1eb4460a8253a8e747ba052ac Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 272/551] sched: scheduler debugging, core scheduler debugging core: implement /proc/sched_debug and /proc//sched files for scheduler debugging. Signed-off-by: Ingo Molnar --- fs/proc/base.c | 69 +++++++++++ include/linux/sched.h | 20 +++ kernel/sched_debug.c | 275 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 kernel/sched_debug.c diff --git a/fs/proc/base.c b/fs/proc/base.c index 0f40e820c7fd..46ea5d56e1bb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -929,6 +929,69 @@ static const struct file_operations proc_fault_inject_operations = { }; #endif +#ifdef CONFIG_SCHED_DEBUG +/* + * Print out various scheduling related per-task fields: + */ +static int sched_show(struct seq_file *m, void *v) +{ + struct inode *inode = m->private; + struct task_struct *p; + + WARN_ON(!inode); + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + proc_sched_show_task(p, m); + + put_task_struct(p); + + return 0; +} + +static ssize_t +sched_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + struct inode *inode = file->f_path.dentry->d_inode; + struct task_struct *p; + + WARN_ON(!inode); + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + proc_sched_set_task(p); + + put_task_struct(p); + + return count; +} + +static int sched_open(struct inode *inode, struct file *filp) +{ + int ret; + + ret = single_open(filp, sched_show, NULL); + if (!ret) { + struct seq_file *m = filp->private_data; + + m->private = inode; + } + return ret; +} + +static const struct file_operations proc_pid_sched_operations = { + .open = sched_open, + .read = seq_read, + .write = sched_write, + .llseek = seq_lseek, + .release = seq_release, +}; + +#endif + static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; @@ -1963,6 +2026,9 @@ static const struct pid_entry tgid_base_stuff[] = { INF("environ", S_IRUSR, pid_environ), INF("auxv", S_IRUSR, pid_auxv), INF("status", S_IRUGO, pid_status), +#ifdef CONFIG_SCHED_DEBUG + REG("sched", S_IRUGO|S_IWUSR, pid_sched), +#endif INF("cmdline", S_IRUGO, pid_cmdline), INF("stat", S_IRUGO, tgid_stat), INF("statm", S_IRUGO, pid_statm), @@ -2247,6 +2313,9 @@ static const struct pid_entry tid_base_stuff[] = { INF("environ", S_IRUSR, pid_environ), INF("auxv", S_IRUSR, pid_auxv), INF("status", S_IRUGO, pid_status), +#ifdef CONFIG_SCHED_DEBUG + REG("sched", S_IRUGO|S_IWUSR, pid_sched), +#endif INF("cmdline", S_IRUGO, pid_cmdline), INF("stat", S_IRUGO, tid_stat), INF("statm", S_IRUGO, pid_statm), diff --git a/include/linux/sched.h b/include/linux/sched.h index c9d65738bb7a..785ec8465bd3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -132,6 +132,26 @@ extern unsigned long nr_active(void); extern unsigned long nr_iowait(void); extern unsigned long weighted_cpuload(const int cpu); +struct seq_file; +struct cfs_rq; +#ifdef CONFIG_SCHED_DEBUG +extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); +extern void proc_sched_set_task(struct task_struct *p); +extern void +print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now); +#else +static inline void +proc_sched_show_task(struct task_struct *p, struct seq_file *m) +{ +} +static inline void proc_sched_set_task(struct task_struct *p) +{ +} +static inline void +print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now) +{ +} +#endif /* * Task state bitmask. NOTE! These bits are also diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c new file mode 100644 index 000000000000..1baf87cceb7c --- /dev/null +++ b/kernel/sched_debug.c @@ -0,0 +1,275 @@ +/* + * kernel/time/sched_debug.c + * + * Print the CFS rbtree + * + * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +/* + * This allows printing both to /proc/sched_debug and + * to the console + */ +#define SEQ_printf(m, x...) \ + do { \ + if (m) \ + seq_printf(m, x); \ + else \ + printk(x); \ + } while (0) + +static void +print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now) +{ + if (rq->curr == p) + SEQ_printf(m, "R"); + else + SEQ_printf(m, " "); + + SEQ_printf(m, "%15s %5d %15Ld %13Ld %13Ld %9Ld %5d " + "%15Ld %15Ld %15Ld %15Ld %15Ld\n", + p->comm, p->pid, + (long long)p->se.fair_key, + (long long)(p->se.fair_key - rq->cfs.fair_clock), + (long long)p->se.wait_runtime, + (long long)(p->nvcsw + p->nivcsw), + p->prio, + (long long)p->se.sum_exec_runtime, + (long long)p->se.sum_wait_runtime, + (long long)p->se.sum_sleep_runtime, + (long long)p->se.wait_runtime_overruns, + (long long)p->se.wait_runtime_underruns); +} + +static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now) +{ + struct task_struct *g, *p; + + SEQ_printf(m, + "\nrunnable tasks:\n" + " task PID tree-key delta waiting" + " switches prio" + " sum-exec sum-wait sum-sleep" + " wait-overrun wait-underrun\n" + "------------------------------------------------------------------" + "----------------" + "------------------------------------------------" + "--------------------------------\n"); + + read_lock_irq(&tasklist_lock); + + do_each_thread(g, p) { + if (!p->se.on_rq || task_cpu(p) != rq_cpu) + continue; + + print_task(m, rq, p, now); + } while_each_thread(g, p); + + read_unlock_irq(&tasklist_lock); +} + +static void +print_cfs_rq_runtime_sum(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) +{ + s64 wait_runtime_rq_sum = 0; + struct task_struct *p; + struct rb_node *curr; + unsigned long flags; + struct rq *rq = &per_cpu(runqueues, cpu); + + spin_lock_irqsave(&rq->lock, flags); + curr = first_fair(cfs_rq); + while (curr) { + p = rb_entry(curr, struct task_struct, se.run_node); + wait_runtime_rq_sum += p->se.wait_runtime; + + curr = rb_next(curr); + } + spin_unlock_irqrestore(&rq->lock, flags); + + SEQ_printf(m, " .%-30s: %Ld\n", "wait_runtime_rq_sum", + (long long)wait_runtime_rq_sum); +} + +void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now) +{ + SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq); + +#define P(x) \ + SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(cfs_rq->x)) + + P(fair_clock); + P(exec_clock); + P(wait_runtime); + P(wait_runtime_overruns); + P(wait_runtime_underruns); + P(sleeper_bonus); +#undef P + + print_cfs_rq_runtime_sum(m, cpu, cfs_rq); +} + +static void print_cpu(struct seq_file *m, int cpu, u64 now) +{ + struct rq *rq = &per_cpu(runqueues, cpu); + +#ifdef CONFIG_X86 + { + unsigned int freq = cpu_khz ? : 1; + + SEQ_printf(m, "\ncpu#%d, %u.%03u MHz\n", + cpu, freq / 1000, (freq % 1000)); + } +#else + SEQ_printf(m, "\ncpu#%d\n", cpu); +#endif + +#define P(x) \ + SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(rq->x)) + + P(nr_running); + SEQ_printf(m, " .%-30s: %lu\n", "load", + rq->ls.load.weight); + P(ls.delta_fair); + P(ls.delta_exec); + P(nr_switches); + P(nr_load_updates); + P(nr_uninterruptible); + SEQ_printf(m, " .%-30s: %lu\n", "jiffies", jiffies); + P(next_balance); + P(curr->pid); + P(clock); + P(prev_clock_raw); + P(clock_warps); + P(clock_overflows); + P(clock_unstable_events); + P(clock_max_delta); + P(cpu_load[0]); + P(cpu_load[1]); + P(cpu_load[2]); + P(cpu_load[3]); + P(cpu_load[4]); +#undef P + + print_cfs_stats(m, cpu, now); + + print_rq(m, rq, cpu, now); +} + +static int sched_debug_show(struct seq_file *m, void *v) +{ + u64 now = ktime_to_ns(ktime_get()); + int cpu; + + SEQ_printf(m, "Sched Debug Version: v0.04, cfs-v20, %s %.*s\n", + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + + SEQ_printf(m, "now at %Lu nsecs\n", (unsigned long long)now); + + for_each_online_cpu(cpu) + print_cpu(m, cpu, now); + + SEQ_printf(m, "\n"); + + return 0; +} + +void sysrq_sched_debug_show(void) +{ + sched_debug_show(NULL, NULL); +} + +static int sched_debug_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, sched_debug_show, NULL); +} + +static struct file_operations sched_debug_fops = { + .open = sched_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init init_sched_debug_procfs(void) +{ + struct proc_dir_entry *pe; + + pe = create_proc_entry("sched_debug", 0644, NULL); + if (!pe) + return -ENOMEM; + + pe->proc_fops = &sched_debug_fops; + + return 0; +} + +__initcall(init_sched_debug_procfs); + +void proc_sched_show_task(struct task_struct *p, struct seq_file *m) +{ + unsigned long flags; + int num_threads = 1; + + rcu_read_lock(); + if (lock_task_sighand(p, &flags)) { + num_threads = atomic_read(&p->signal->count); + unlock_task_sighand(p, &flags); + } + rcu_read_unlock(); + + SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, p->pid, num_threads); + SEQ_printf(m, "----------------------------------------------\n"); +#define P(F) \ + SEQ_printf(m, "%-25s:%20Ld\n", #F, (long long)p->F) + + P(se.wait_start); + P(se.wait_start_fair); + P(se.exec_start); + P(se.sleep_start); + P(se.sleep_start_fair); + P(se.block_start); + P(se.sleep_max); + P(se.block_max); + P(se.exec_max); + P(se.wait_max); + P(se.wait_runtime); + P(se.wait_runtime_overruns); + P(se.wait_runtime_underruns); + P(se.sum_wait_runtime); + P(se.sum_exec_runtime); + SEQ_printf(m, "%-25s:%20Ld\n", + "nr_switches", (long long)(p->nvcsw + p->nivcsw)); + P(se.load.weight); + P(policy); + P(prio); +#undef P + + { + u64 t0, t1; + + t0 = sched_clock(); + t1 = sched_clock(); + SEQ_printf(m, "%-25s:%20Ld\n", + "clock-delta", (long long)(t1-t0)); + } +} + +void proc_sched_set_task(struct task_struct *p) +{ + p->se.sleep_max = p->se.block_max = p->se.exec_max = p->se.wait_max = 0; + p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0; + p->se.sum_exec_runtime = 0; +} From b642b6d3fad45f659270a9e35df876b38c489082 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 273/551] sched: scheduler debugging, enable in Kconfig enable CONFIG_SCHED_DEBUG in lib/Kconfig.debug. the runtime overhead of this option is very small. Signed-off-by: Ingo Molnar --- lib/Kconfig.debug | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index da95e10cfd70..fab32a286371 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -105,6 +105,15 @@ config DETECT_SOFTLOCKUP can be detected via the NMI-watchdog, on platforms that support it.) +config SCHED_DEBUG + bool "Collect scheduler debugging info" + depends on DEBUG_KERNEL && PROC_FS + default y + help + If you say Y here, the /proc/sched_debug file will be provided + that can help debug the scheduler. The runtime overhead of this + option is minimal. + config SCHEDSTATS bool "Collect scheduler statistics" depends on DEBUG_KERNEL && PROC_FS From 5e7eaade55d53da856f0e07dc9c188f78f780192 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 274/551] sched: add CFS documentation add Documentation/sched-design-CFS.txt Signed-off-by: Ingo Molnar --- Documentation/sched-design-CFS.txt | 119 +++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 Documentation/sched-design-CFS.txt diff --git a/Documentation/sched-design-CFS.txt b/Documentation/sched-design-CFS.txt new file mode 100644 index 000000000000..16feebb7bdc0 --- /dev/null +++ b/Documentation/sched-design-CFS.txt @@ -0,0 +1,119 @@ + +This is the CFS scheduler. + +80% of CFS's design can be summed up in a single sentence: CFS basically +models an "ideal, precise multi-tasking CPU" on real hardware. + +"Ideal multi-tasking CPU" is a (non-existent :-)) CPU that has 100% +physical power and which can run each task at precise equal speed, in +parallel, each at 1/nr_running speed. For example: if there are 2 tasks +running then it runs each at 50% physical power - totally in parallel. + +On real hardware, we can run only a single task at once, so while that +one task runs, the other tasks that are waiting for the CPU are at a +disadvantage - the current task gets an unfair amount of CPU time. In +CFS this fairness imbalance is expressed and tracked via the per-task +p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of +time the task should now run on the CPU for it to become completely fair +and balanced. + +( small detail: on 'ideal' hardware, the p->wait_runtime value would + always be zero - no task would ever get 'out of balance' from the + 'ideal' share of CPU time. ) + +CFS's task picking logic is based on this p->wait_runtime value and it +is thus very simple: it always tries to run the task with the largest +p->wait_runtime value. In other words, CFS tries to run the task with +the 'gravest need' for more CPU time. So CFS always tries to split up +CPU time between runnable tasks as close to 'ideal multitasking +hardware' as possible. + +Most of the rest of CFS's design just falls out of this really simple +concept, with a few add-on embellishments like nice levels, +multiprocessing and various algorithm variants to recognize sleepers. + +In practice it works like this: the system runs a task a bit, and when +the task schedules (or a scheduler tick happens) the task's CPU usage is +'accounted for': the (small) time it just spent using the physical CPU +is deducted from p->wait_runtime. [minus the 'fair share' it would have +gotten anyway]. Once p->wait_runtime gets low enough so that another +task becomes the 'leftmost task' of the time-ordered rbtree it maintains +(plus a small amount of 'granularity' distance relative to the leftmost +task so that we do not over-schedule tasks and trash the cache) then the +new leftmost task is picked and the current task is preempted. + +The rq->fair_clock value tracks the 'CPU time a runnable task would have +fairly gotten, had it been runnable during that time'. So by using +rq->fair_clock values we can accurately timestamp and measure the +'expected CPU time' a task should have gotten. All runnable tasks are +sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and +CFS picks the 'leftmost' task and sticks to it. As the system progresses +forwards, newly woken tasks are put into the tree more and more to the +right - slowly but surely giving a chance for every task to become the +'leftmost task' and thus get on the CPU within a deterministic amount of +time. + +Some implementation details: + + - the introduction of Scheduling Classes: an extensible hierarchy of + scheduler modules. These modules encapsulate scheduling policy + details and are handled by the scheduler core without the core + code assuming about them too much. + + - sched_fair.c implements the 'CFS desktop scheduler': it is a + replacement for the vanilla scheduler's SCHED_OTHER interactivity + code. + + I'd like to give credit to Con Kolivas for the general approach here: + he has proven via RSDL/SD that 'fair scheduling' is possible and that + it results in better desktop scheduling. Kudos Con! + + The CFS patch uses a completely different approach and implementation + from RSDL/SD. My goal was to make CFS's interactivity quality exceed + that of RSDL/SD, which is a high standard to meet :-) Testing + feedback is welcome to decide this one way or another. [ and, in any + case, all of SD's logic could be added via a kernel/sched_sd.c module + as well, if Con is interested in such an approach. ] + + CFS's design is quite radical: it does not use runqueues, it uses a + time-ordered rbtree to build a 'timeline' of future task execution, + and thus has no 'array switch' artifacts (by which both the vanilla + scheduler and RSDL/SD are affected). + + CFS uses nanosecond granularity accounting and does not rely on any + jiffies or other HZ detail. Thus the CFS scheduler has no notion of + 'timeslices' and has no heuristics whatsoever. There is only one + central tunable: + + /proc/sys/kernel/sched_granularity_ns + + which can be used to tune the scheduler from 'desktop' (low + latencies) to 'server' (good batching) workloads. It defaults to a + setting suitable for desktop workloads. SCHED_BATCH is handled by the + CFS scheduler module too. + + Due to its design, the CFS scheduler is not prone to any of the + 'attacks' that exist today against the heuristics of the stock + scheduler: fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c all + work fine and do not impact interactivity and produce the expected + behavior. + + the CFS scheduler has a much stronger handling of nice levels and + SCHED_BATCH: both types of workloads should be isolated much more + agressively than under the vanilla scheduler. + + ( another detail: due to nanosec accounting and timeline sorting, + sched_yield() support is very simple under CFS, and in fact under + CFS sched_yield() behaves much better than under any other + scheduler i have tested so far. ) + + - sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler + way than the vanilla scheduler does. It uses 100 runqueues (for all + 100 RT priority levels, instead of 140 in the vanilla scheduler) + and it needs no expired array. + + - reworked/sanitized SMP load-balancing: the runqueue-walking + assumptions are gone from the load-balancing code now, and + iterators of the scheduling modules are used. The balancing code got + quite a bit simpler as a result. + From ff80a77f20f811c0cc5b251d0f657cbc6f788385 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 275/551] sched: simplify sched_find_first_bit() simplify sched_rt.c's sched_find_first_bit() function: there are only 100 RT priority levels left. Signed-off-by: Ingo Molnar --- include/asm-generic/bitops/sched.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/include/asm-generic/bitops/sched.h b/include/asm-generic/bitops/sched.h index 815bb0148060..604fab7031a6 100644 --- a/include/asm-generic/bitops/sched.h +++ b/include/asm-generic/bitops/sched.h @@ -6,28 +6,23 @@ /* * Every architecture must define this function. It's the fastest - * way of searching a 140-bit bitmap where the first 100 bits are - * unlikely to be set. It's guaranteed that at least one of the 140 - * bits is cleared. + * way of searching a 100-bit bitmap. It's guaranteed that at least + * one of the 100 bits is cleared. */ static inline int sched_find_first_bit(const unsigned long *b) { #if BITS_PER_LONG == 64 - if (unlikely(b[0])) + if (b[0]) return __ffs(b[0]); - if (likely(b[1])) - return __ffs(b[1]) + 64; - return __ffs(b[2]) + 128; + return __ffs(b[1]) + 64; #elif BITS_PER_LONG == 32 - if (unlikely(b[0])) + if (b[0]) return __ffs(b[0]); - if (unlikely(b[1])) + if (b[1]) return __ffs(b[1]) + 32; - if (unlikely(b[2])) + if (b[2]) return __ffs(b[2]) + 64; - if (b[3]) - return __ffs(b[3]) + 96; - return __ffs(b[4]) + 128; + return __ffs(b[3]) + 96; #else #error BITS_PER_LONG not defined #endif From 23bdd703a585a869f2eb32fb9f66749d0476d71e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 276/551] sched: do not set softirqs to nice +19 do not set softirqs to nice +19. _If_ for whatever reason we missed to process some high-prio softirq and woke up ksoftirqd, we should give it a fair chance to actually get some work done, even if the system is under load. Signed-off-by: Ingo Molnar --- kernel/softirq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/softirq.c b/kernel/softirq.c index 0b9886a00e74..73217a9e2875 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -488,7 +488,6 @@ void __init softirq_init(void) static int ksoftirqd(void * __bind_cpu) { - set_user_nice(current, 19); current->flags |= PF_NOFREEZE; set_current_state(TASK_INTERRUPTIBLE); From 9761eea8516d1ff2c7b185e283c5d81cfc307acb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:00 +0200 Subject: [PATCH 277/551] sched: style cleanups 4 small style cleanups to sched.c: checkpatch.pl is now happy about the totality of sched.c [ignoring false positives] - yay! ;-) Signed-off-by: Ingo Molnar --- kernel/sched.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index f8cf78c6af2e..ef6b6bb3e0b2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1265,9 +1265,9 @@ static int sched_balance_self(int cpu, int flag) struct sched_domain *tmp, *sd = NULL; for_each_domain(cpu, tmp) { - /* - * If power savings logic is enabled for a domain, stop there. - */ + /* + * If power savings logic is enabled for a domain, stop there. + */ if (tmp->flags & SD_POWERSAVINGS_BALANCE) break; if (tmp->flags & flag) @@ -1350,9 +1350,9 @@ static int wake_idle(int cpu, struct task_struct *p) if (idle_cpu(i)) return i; } - } - else + } else { break; + } } return cpu; } @@ -1702,7 +1702,7 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev) /* * Remove function-return probe instances associated with this * task and put them back on the free list. - */ + */ kprobe_flush_task(prev); put_task_struct(prev); } @@ -5920,6 +5920,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) sched_group_nodes[i] = sg; for_each_cpu_mask(j, nodemask) { struct sched_domain *sd; + sd = &per_cpu(node_domains, j); sd->groups = sg; } From 0fec171cdbd7763ef86cbaccb91f3708de6a9003 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:01 +0200 Subject: [PATCH 278/551] sched: clean up sleep_on() APIs clean up the sleep_on() APIs: - do not use fastcall - replace fragile macro magic with proper inline functions Signed-off-by: Ingo Molnar --- include/linux/wait.h | 16 ++++----- kernel/sched.c | 77 +++++++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 41 deletions(-) diff --git a/include/linux/wait.h b/include/linux/wait.h index e820d00e1383..0e686280450b 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -366,15 +366,15 @@ static inline void remove_wait_queue_locked(wait_queue_head_t *q, /* * These are the old interfaces to sleep waiting for an event. - * They are racy. DO NOT use them, use the wait_event* interfaces above. - * We plan to remove these interfaces during 2.7. + * They are racy. DO NOT use them, use the wait_event* interfaces above. + * We plan to remove these interfaces. */ -extern void FASTCALL(sleep_on(wait_queue_head_t *q)); -extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q, - signed long timeout)); -extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q)); -extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, - signed long timeout)); +extern void sleep_on(wait_queue_head_t *q); +extern long sleep_on_timeout(wait_queue_head_t *q, + signed long timeout); +extern void interruptible_sleep_on(wait_queue_head_t *q); +extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, + signed long timeout); /* * Waitqueues which are removed from the waitqueue_head at wakeup time diff --git a/kernel/sched.c b/kernel/sched.c index ef6b6bb3e0b2..0e3caf742ae3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3699,74 +3699,85 @@ out: } EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); - -#define SLEEP_ON_VAR \ - unsigned long flags; \ - wait_queue_t wait; \ - init_waitqueue_entry(&wait, current); - -#define SLEEP_ON_HEAD \ - spin_lock_irqsave(&q->lock,flags); \ - __add_wait_queue(q, &wait); \ - spin_unlock(&q->lock); - -#define SLEEP_ON_TAIL \ - spin_lock_irq(&q->lock); \ - __remove_wait_queue(q, &wait); \ - spin_unlock_irqrestore(&q->lock, flags); - -void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q) +static inline void +sleep_on_head(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags) { - SLEEP_ON_VAR + spin_lock_irqsave(&q->lock, *flags); + __add_wait_queue(q, wait); + spin_unlock(&q->lock); +} + +static inline void +sleep_on_tail(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags) +{ + spin_lock_irq(&q->lock); + __remove_wait_queue(q, wait); + spin_unlock_irqrestore(&q->lock, *flags); +} + +void __sched interruptible_sleep_on(wait_queue_head_t *q) +{ + unsigned long flags; + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); current->state = TASK_INTERRUPTIBLE; - SLEEP_ON_HEAD + sleep_on_head(q, &wait, &flags); schedule(); - SLEEP_ON_TAIL + sleep_on_tail(q, &wait, &flags); } EXPORT_SYMBOL(interruptible_sleep_on); -long fastcall __sched +long __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) { - SLEEP_ON_VAR + unsigned long flags; + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); current->state = TASK_INTERRUPTIBLE; - SLEEP_ON_HEAD + sleep_on_head(q, &wait, &flags); timeout = schedule_timeout(timeout); - SLEEP_ON_TAIL + sleep_on_tail(q, &wait, &flags); return timeout; } EXPORT_SYMBOL(interruptible_sleep_on_timeout); -void fastcall __sched sleep_on(wait_queue_head_t *q) +void __sched sleep_on(wait_queue_head_t *q) { - SLEEP_ON_VAR + unsigned long flags; + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); current->state = TASK_UNINTERRUPTIBLE; - SLEEP_ON_HEAD + sleep_on_head(q, &wait, &flags); schedule(); - SLEEP_ON_TAIL + sleep_on_tail(q, &wait, &flags); } EXPORT_SYMBOL(sleep_on); -long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) +long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) { - SLEEP_ON_VAR + unsigned long flags; + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); current->state = TASK_UNINTERRUPTIBLE; - SLEEP_ON_HEAD + sleep_on_head(q, &wait, &flags); timeout = schedule_timeout(timeout); - SLEEP_ON_TAIL + sleep_on_tail(q, &wait, &flags); return timeout; } - EXPORT_SYMBOL(sleep_on_timeout); #ifdef CONFIG_RT_MUTEXES From 9c4801cebc2add1fe514bc8eb201b16372eee11a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:01 +0200 Subject: [PATCH 279/551] sched: more agressive idle balancing the Linux scheduler is starving a number of workloads. So default to more agressive idle-balancing. This hurts lmbench context-switching numbers (which was the main reason we sucked at idle-balancing for such a long time) but the lmbench numbers are fine once the system is minimally utilized. Signed-off-by: Ingo Molnar --- include/linux/topology.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/linux/topology.h b/include/linux/topology.h index a9d1f049cc15..da6c39b2d051 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -98,7 +98,7 @@ .cache_nice_tries = 0, \ .busy_idx = 0, \ .idle_idx = 0, \ - .newidle_idx = 1, \ + .newidle_idx = 0, \ .wake_idx = 0, \ .forkexec_idx = 0, \ .flags = SD_LOAD_BALANCE \ @@ -128,14 +128,15 @@ .imbalance_pct = 125, \ .cache_nice_tries = 1, \ .busy_idx = 2, \ - .idle_idx = 1, \ - .newidle_idx = 2, \ + .idle_idx = 0, \ + .newidle_idx = 0, \ .wake_idx = 1, \ .forkexec_idx = 1, \ .flags = SD_LOAD_BALANCE \ | SD_BALANCE_NEWIDLE \ | SD_BALANCE_EXEC \ | SD_WAKE_AFFINE \ + | SD_WAKE_IDLE \ | SD_SHARE_PKG_RESOURCES\ | BALANCE_FOR_MC_POWER, \ .last_balance = jiffies, \ @@ -158,14 +159,15 @@ .imbalance_pct = 125, \ .cache_nice_tries = 1, \ .busy_idx = 2, \ - .idle_idx = 1, \ - .newidle_idx = 2, \ + .idle_idx = 0, \ + .newidle_idx = 0, \ .wake_idx = 1, \ .forkexec_idx = 1, \ .flags = SD_LOAD_BALANCE \ | SD_BALANCE_NEWIDLE \ | SD_BALANCE_EXEC \ | SD_WAKE_AFFINE \ + | SD_WAKE_IDLE \ | BALANCE_FOR_PKG_POWER,\ .last_balance = jiffies, \ .balance_interval = 1, \ From 6fb43d7b50e49a36f8be3199141bec473e5ecb00 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:01 +0200 Subject: [PATCH 280/551] sched: micro-optimize mmdrop() micro-optimize mmdrop(). Improves schedule()'s assembly a bit. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 785ec8465bd3..cfb680585ab8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1514,7 +1514,7 @@ extern struct mm_struct * mm_alloc(void); extern void FASTCALL(__mmdrop(struct mm_struct *)); static inline void mmdrop(struct mm_struct * mm) { - if (atomic_dec_and_test(&mm->mm_count)) + if (unlikely(atomic_dec_and_test(&mm->mm_count))) __mmdrop(mm); } From c31f2e8a42c41efa46397732656ddf48cc77593e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 9 Jul 2007 18:52:01 +0200 Subject: [PATCH 281/551] sched: add CFS credits add credits for recent major scheduler contributions: Con Kolivas, for pioneering the fair-scheduling approach Peter Williams, for smpnice Mike Galbraith, for interactivity tuning of CFS Srivatsa Vaddagiri, for group scheduling enhancements Signed-off-by: Ingo Molnar --- kernel/sched.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 0e3caf742ae3..9fbced64bfee 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -16,6 +16,12 @@ * by Davide Libenzi, preemptible kernel bits by Robert Love. * 2003-09-03 Interactivity tuning by Con Kolivas. * 2004-04-02 Scheduler domains code by Nick Piggin + * 2007-04-15 Work begun on replacing all interactivity tuning with a + * fair scheduling design by Con Kolivas. + * 2007-05-05 Load balancing (smp-nice) and other improvements + * by Peter Williams + * 2007-05-06 Interactivity improvements to CFS by Mike Galbraith + * 2007-07-01 Group scheduling enhancements by Srivatsa Vaddagiri */ #include From 98ccf14909ba02a41c5925b0b2c92aeeef23d3b9 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 12 May 2007 00:26:16 +0200 Subject: [PATCH 282/551] mmc: bounce requests for simple hosts Some hosts cannot do scatter/gather in hardware. Since not doing sg is such a big performance hit, we (optionally) bounce the requests to a simple linear buffer that we hand over to the driver. Signed-off-by: Pierre Ossman --- drivers/mmc/card/Kconfig | 18 ++++ drivers/mmc/card/block.c | 7 +- drivers/mmc/card/queue.c | 191 ++++++++++++++++++++++++++++++++++++--- drivers/mmc/card/queue.h | 7 ++ 4 files changed, 208 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 9320a8c73239..a49cb9737cd8 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -14,3 +14,21 @@ config MMC_BLOCK mount the filesystem. Almost everyone wishing MMC support should say Y or M here. +config MMC_BLOCK_BOUNCE + bool "Use bounce buffer for simple hosts" + depends on MMC_BLOCK + default y + help + SD/MMC is a high latency protocol where it is crucial to + send large requests in order to get high performance. Many + controllers, however, are restricted to continuous memory + (i.e. they can't do scatter-gather), something the kernel + rarely can provide. + + Say Y here to help these restricted hosts by bouncing + requests back and forth from a large buffer. You will get + a big performance gain at the cost of up to 64 KiB of + physical memory. + + If unsure, say Y here. + diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 540ff4bea54c..cbd4b6e3e17c 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -262,7 +262,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } brq.data.sg = mq->sg; - brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); + brq.data.sg_len = mmc_queue_map_sg(mq); + + mmc_queue_bounce_pre(mq); if (brq.data.blocks != (req->nr_sectors >> (md->block_bits - 9))) { @@ -279,6 +281,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } mmc_wait_for_req(card->host, &brq.mrq); + + mmc_queue_bounce_post(mq); + if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write command\n", req->rq_disk->disk_name, brq.cmd.error); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dd97bc798409..4fb2089dc690 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -17,6 +17,8 @@ #include #include "queue.h" +#define MMC_QUEUE_BOUNCESZ 65536 + #define MMC_QUEUE_SUSPENDED (1 << 0) /* @@ -118,6 +120,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock struct mmc_host *host = card->host; u64 limit = BLK_BOUNCE_HIGH; int ret; + unsigned int bouncesz; if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) limit = *mmc_dev(host)->dma_mask; @@ -127,21 +130,61 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (!mq->queue) return -ENOMEM; - blk_queue_prep_rq(mq->queue, mmc_prep_request); - blk_queue_bounce_limit(mq->queue, limit); - blk_queue_max_sectors(mq->queue, host->max_req_size / 512); - blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); - blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); - blk_queue_max_segment_size(mq->queue, host->max_seg_size); - mq->queue->queuedata = mq; mq->req = NULL; - mq->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs, - GFP_KERNEL); - if (!mq->sg) { - ret = -ENOMEM; - goto cleanup_queue; + blk_queue_prep_rq(mq->queue, mmc_prep_request); + +#ifdef CONFIG_MMC_BLOCK_BOUNCE + if (host->max_hw_segs == 1) { + bouncesz = MMC_QUEUE_BOUNCESZ; + + if (bouncesz > host->max_req_size) + bouncesz = host->max_req_size; + if (bouncesz > host->max_seg_size) + bouncesz = host->max_seg_size; + + mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); + if (!mq->bounce_buf) { + printk(KERN_WARNING "%s: unable to allocate " + "bounce buffer\n", mmc_card_name(card)); + } else { + blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH); + blk_queue_max_sectors(mq->queue, bouncesz / 512); + blk_queue_max_phys_segments(mq->queue, bouncesz / 512); + blk_queue_max_hw_segments(mq->queue, bouncesz / 512); + blk_queue_max_segment_size(mq->queue, bouncesz); + + mq->sg = kmalloc(sizeof(struct scatterlist), + GFP_KERNEL); + if (!mq->sg) { + ret = -ENOMEM; + goto free_bounce_buf; + } + + mq->bounce_sg = kmalloc(sizeof(struct scatterlist) * + bouncesz / 512, GFP_KERNEL); + if (!mq->bounce_sg) { + ret = -ENOMEM; + goto free_sg; + } + } + } +#endif + + if (!mq->bounce_buf) { + blk_queue_bounce_limit(mq->queue, limit); + blk_queue_max_sectors(mq->queue, host->max_req_size / 512); + blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); + blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); + blk_queue_max_segment_size(mq->queue, host->max_seg_size); + + mq->sg = kmalloc(sizeof(struct scatterlist) * + host->max_phys_segs, GFP_KERNEL); + if (!mq->sg) { + ret = -ENOMEM; + goto cleanup_queue; + } } init_MUTEX(&mq->thread_sem); @@ -149,14 +192,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd"); if (IS_ERR(mq->thread)) { ret = PTR_ERR(mq->thread); - goto free_sg; + goto free_bounce_sg; } return 0; - + free_bounce_sg: + if (mq->bounce_sg) + kfree(mq->bounce_sg); + mq->bounce_sg = NULL; free_sg: kfree(mq->sg); mq->sg = NULL; + free_bounce_buf: + if (mq->bounce_buf) + kfree(mq->bounce_buf); + mq->bounce_buf = NULL; cleanup_queue: blk_cleanup_queue(mq->queue); return ret; @@ -178,9 +228,17 @@ void mmc_cleanup_queue(struct mmc_queue *mq) /* Then terminate our worker thread */ kthread_stop(mq->thread); + if (mq->bounce_sg) + kfree(mq->bounce_sg); + mq->bounce_sg = NULL; + kfree(mq->sg); mq->sg = NULL; + if (mq->bounce_buf) + kfree(mq->bounce_buf); + mq->bounce_buf = NULL; + blk_cleanup_queue(mq->queue); mq->card = NULL; @@ -231,3 +289,108 @@ void mmc_queue_resume(struct mmc_queue *mq) } } +static void copy_sg(struct scatterlist *dst, unsigned int dst_len, + struct scatterlist *src, unsigned int src_len) +{ + unsigned int chunk; + char *dst_buf, *src_buf; + unsigned int dst_size, src_size; + + dst_buf = NULL; + src_buf = NULL; + dst_size = 0; + src_size = 0; + + while (src_len) { + BUG_ON(dst_len == 0); + + if (dst_size == 0) { + dst_buf = page_address(dst->page) + dst->offset; + dst_size = dst->length; + } + + if (src_size == 0) { + src_buf = page_address(src->page) + src->offset; + src_size = src->length; + } + + chunk = min(dst_size, src_size); + + memcpy(dst_buf, src_buf, chunk); + + dst_buf += chunk; + src_buf += chunk; + dst_size -= chunk; + src_size -= chunk; + + if (dst_size == 0) { + dst++; + dst_len--; + } + + if (src_size == 0) { + src++; + src_len--; + } + } +} + +unsigned int mmc_queue_map_sg(struct mmc_queue *mq) +{ + unsigned int sg_len; + + if (!mq->bounce_buf) + return blk_rq_map_sg(mq->queue, mq->req, mq->sg); + + BUG_ON(!mq->bounce_sg); + + sg_len = blk_rq_map_sg(mq->queue, mq->req, mq->bounce_sg); + + mq->bounce_sg_len = sg_len; + + /* + * Shortcut in the event we only get a single entry. + */ + if (sg_len == 1) { + memcpy(mq->sg, mq->bounce_sg, sizeof(struct scatterlist)); + return 1; + } + + mq->sg[0].page = virt_to_page(mq->bounce_buf); + mq->sg[0].offset = offset_in_page(mq->bounce_buf); + mq->sg[0].length = 0; + + while (sg_len) { + mq->sg[0].length += mq->bounce_sg[sg_len - 1].length; + sg_len--; + } + + return 1; +} + +void mmc_queue_bounce_pre(struct mmc_queue *mq) +{ + if (!mq->bounce_buf) + return; + + if (mq->bounce_sg_len == 1) + return; + if (rq_data_dir(mq->req) != WRITE) + return; + + copy_sg(mq->sg, 1, mq->bounce_sg, mq->bounce_sg_len); +} + +void mmc_queue_bounce_post(struct mmc_queue *mq) +{ + if (!mq->bounce_buf) + return; + + if (mq->bounce_sg_len == 1) + return; + if (rq_data_dir(mq->req) != READ) + return; + + copy_sg(mq->bounce_sg, mq->bounce_sg_len, mq->sg, 1); +} + diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 1590b3f3f1f7..64e66e0d4994 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -14,6 +14,9 @@ struct mmc_queue { void *data; struct request_queue *queue; struct scatterlist *sg; + char *bounce_buf; + struct scatterlist *bounce_sg; + unsigned int bounce_sg_len; }; extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *); @@ -21,4 +24,8 @@ extern void mmc_cleanup_queue(struct mmc_queue *); extern void mmc_queue_suspend(struct mmc_queue *); extern void mmc_queue_resume(struct mmc_queue *); +extern unsigned int mmc_queue_map_sg(struct mmc_queue *); +extern void mmc_queue_bounce_pre(struct mmc_queue *); +extern void mmc_queue_bounce_post(struct mmc_queue *); + #endif From 7de064ebc67d9baf6c933d3a7046feb9b4eced05 Mon Sep 17 00:00:00 2001 From: Milko Krachounov Date: Sat, 19 May 2007 01:18:03 +0200 Subject: [PATCH 283/551] sdhci: add ene controller id ENE has a very weird design where an SDHCI device (0805) is presented on the PCI bus, but that device is non-functional, and the real device is hidden as a more generic device. Signed-off-by: Milko Krachounov Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 8 ++++++++ include/linux/pci_ids.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a359efdd77eb..5e9a6ce83559 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -70,6 +70,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, }, + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5b1c9994f89a..75c4d4d06892 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2000,6 +2000,7 @@ #define PCI_VENDOR_ID_ENE 0x1524 #define PCI_DEVICE_ID_ENE_CB712_SD 0x0550 +#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551 #define PCI_DEVICE_ID_ENE_1211 0x1211 #define PCI_DEVICE_ID_ENE_1225 0x1225 #define PCI_DEVICE_ID_ENE_1410 0x1410 From 4101c16a910b15afd190c6bc7d45864461cf5c25 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 19 May 2007 13:39:01 +0200 Subject: [PATCH 284/551] mmc: refactor bus operations Move bus operations to its own file for the sake of clarity. Also delegate sysfs attributes to bus handlers in preparation for other more exotic types. Signed-off-by: Pierre Ossman --- drivers/mmc/core/Makefile | 3 +- drivers/mmc/core/bus.c | 253 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/bus.h | 22 ++++ drivers/mmc/core/core.c | 16 --- drivers/mmc/core/core.h | 4 +- drivers/mmc/core/mmc.c | 59 ++++++++- drivers/mmc/core/sd.c | 63 ++++++++-- drivers/mmc/core/sysfs.c | 228 +++------------------------------- drivers/mmc/core/sysfs.h | 14 ++- 9 files changed, 418 insertions(+), 244 deletions(-) create mode 100644 drivers/mmc/core/bus.c create mode 100644 drivers/mmc/core/bus.h diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 1075b02ae754..54261e3724c4 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -7,5 +7,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y) endif obj-$(CONFIG_MMC) += mmc_core.o -mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o +mmc_core-y := core.o sysfs.o bus.o \ + mmc.o mmc_ops.o sd.o sd_ops.o diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c new file mode 100644 index 000000000000..348b566bf4fd --- /dev/null +++ b/drivers/mmc/core/bus.c @@ -0,0 +1,253 @@ +/* + * linux/drivers/mmc/core/bus.c + * + * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright (C) 2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMC card bus driver model + */ + +#include +#include + +#include +#include + +#include "sysfs.h" +#include "core.h" +#include "bus.h" + +#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) +#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) + +static ssize_t mmc_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mmc_card *card = dev_to_mmc_card(dev); + + switch (card->type) { + case MMC_TYPE_MMC: + return sprintf(buf, "MMC\n"); + case MMC_TYPE_SD: + return sprintf(buf, "SD\n"); + default: + return -EFAULT; + } +} + +static struct device_attribute mmc_dev_attrs[] = { + MMC_ATTR_RO(type), + __ATTR_NULL, +}; + +/* + * This currently matches any MMC driver to any MMC card - drivers + * themselves make the decision whether to drive this card in their + * probe method. + */ +static int mmc_bus_match(struct device *dev, struct device_driver *drv) +{ + return 1; +} + +static int +mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, + int buf_size) +{ + struct mmc_card *card = dev_to_mmc_card(dev); + int retval = 0, i = 0, length = 0; + +#define add_env(fmt,val) do { \ + retval = add_uevent_var(envp, num_envp, &i, \ + buf, buf_size, &length, \ + fmt, val); \ + if (retval) \ + return retval; \ +} while (0); + + switch (card->type) { + case MMC_TYPE_MMC: + add_env("MMC_TYPE=%s", "MMC"); + break; + case MMC_TYPE_SD: + add_env("MMC_TYPE=%s", "SD"); + break; + } + + add_env("MMC_NAME=%s", mmc_card_name(card)); + +#undef add_env + + envp[i] = NULL; + + return 0; +} + +static int mmc_bus_probe(struct device *dev) +{ + struct mmc_driver *drv = to_mmc_driver(dev->driver); + struct mmc_card *card = dev_to_mmc_card(dev); + + return drv->probe(card); +} + +static int mmc_bus_remove(struct device *dev) +{ + struct mmc_driver *drv = to_mmc_driver(dev->driver); + struct mmc_card *card = dev_to_mmc_card(dev); + + drv->remove(card); + + return 0; +} + +static int mmc_bus_suspend(struct device *dev, pm_message_t state) +{ + struct mmc_driver *drv = to_mmc_driver(dev->driver); + struct mmc_card *card = dev_to_mmc_card(dev); + int ret = 0; + + if (dev->driver && drv->suspend) + ret = drv->suspend(card, state); + return ret; +} + +static int mmc_bus_resume(struct device *dev) +{ + struct mmc_driver *drv = to_mmc_driver(dev->driver); + struct mmc_card *card = dev_to_mmc_card(dev); + int ret = 0; + + if (dev->driver && drv->resume) + ret = drv->resume(card); + return ret; +} + +static struct bus_type mmc_bus_type = { + .name = "mmc", + .dev_attrs = mmc_dev_attrs, + .match = mmc_bus_match, + .uevent = mmc_bus_uevent, + .probe = mmc_bus_probe, + .remove = mmc_bus_remove, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, +}; + +int mmc_register_bus(void) +{ + return bus_register(&mmc_bus_type); +} + +void mmc_unregister_bus(void) +{ + bus_unregister(&mmc_bus_type); +} + +/** + * mmc_register_driver - register a media driver + * @drv: MMC media driver + */ +int mmc_register_driver(struct mmc_driver *drv) +{ + drv->drv.bus = &mmc_bus_type; + return driver_register(&drv->drv); +} + +EXPORT_SYMBOL(mmc_register_driver); + +/** + * mmc_unregister_driver - unregister a media driver + * @drv: MMC media driver + */ +void mmc_unregister_driver(struct mmc_driver *drv) +{ + drv->drv.bus = &mmc_bus_type; + driver_unregister(&drv->drv); +} + +EXPORT_SYMBOL(mmc_unregister_driver); + +static void mmc_release_card(struct device *dev) +{ + struct mmc_card *card = dev_to_mmc_card(dev); + + kfree(card); +} + +/* + * Allocate and initialise a new MMC card structure. + */ +struct mmc_card *mmc_alloc_card(struct mmc_host *host) +{ + struct mmc_card *card; + + card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); + if (!card) + return ERR_PTR(-ENOMEM); + + memset(card, 0, sizeof(struct mmc_card)); + + card->host = host; + + device_initialize(&card->dev); + + card->dev.parent = mmc_classdev(host); + card->dev.bus = &mmc_bus_type; + card->dev.release = mmc_release_card; + + return card; +} + +/* + * Register a new MMC card with the driver model. + */ +int mmc_add_card(struct mmc_card *card) +{ + int ret; + + snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), + "%s:%04x", mmc_hostname(card->host), card->rca); + + card->dev.uevent_suppress = 1; + + ret = device_add(&card->dev); + if (ret) + return ret; + + if (card->host->bus_ops->sysfs_add) { + ret = card->host->bus_ops->sysfs_add(card->host, card); + if (ret) { + device_del(&card->dev); + return ret; + } + } + + card->dev.uevent_suppress = 0; + + kobject_uevent(&card->dev.kobj, KOBJ_ADD); + + mmc_card_set_present(card); + + return 0; +} + +/* + * Unregister a new MMC card with the driver model, and + * (eventually) free it. + */ +void mmc_remove_card(struct mmc_card *card) +{ + if (mmc_card_present(card)) { + if (card->host->bus_ops->sysfs_remove) + card->host->bus_ops->sysfs_remove(card->host, card); + device_del(&card->dev); + } + + put_device(&card->dev); +} + diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h new file mode 100644 index 000000000000..4f35431116a8 --- /dev/null +++ b/drivers/mmc/core/bus.h @@ -0,0 +1,22 @@ +/* + * linux/drivers/mmc/core/bus.h + * + * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright 2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _MMC_CORE_BUS_H +#define _MMC_CORE_BUS_H + +struct mmc_card *mmc_alloc_card(struct mmc_host *host); +int mmc_add_card(struct mmc_card *card); +void mmc_remove_card(struct mmc_card *card); + +int mmc_register_bus(void); +void mmc_unregister_bus(void); + +#endif + diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7385acfa1dd9..d876adf4bd4e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -368,22 +368,6 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) mmc_set_ios(host); } -/* - * Allocate a new MMC card - */ -struct mmc_card *mmc_alloc_card(struct mmc_host *host) -{ - struct mmc_card *card; - - card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); - if (!card) - return ERR_PTR(-ENOMEM); - - mmc_init_card(card, host); - - return card; -} - /* * Apply power to the MMC stack. This is a two-stage process. * First, we enable power to the card without the clock running. diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 177264d090ac..1be86c792a52 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -18,6 +18,8 @@ struct mmc_bus_ops { void (*remove)(struct mmc_host *); void (*detect)(struct mmc_host *); + int (*sysfs_add)(struct mmc_host *, struct mmc_card *card); + void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card); void (*suspend)(struct mmc_host *); void (*resume)(struct mmc_host *); }; @@ -54,8 +56,6 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); void mmc_set_timing(struct mmc_host *host, unsigned int timing); -struct mmc_card *mmc_alloc_card(struct mmc_host *host); - static inline void mmc_delay(unsigned int ms) { if (ms < 1000 / HZ) { diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 42cc2867ed7d..e4371555160a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -18,6 +18,7 @@ #include "core.h" #include "sysfs.h" +#include "bus.h" #include "mmc_ops.h" static const unsigned int tran_exp[] = { @@ -413,8 +414,7 @@ static void mmc_detect(struct mmc_host *host) mmc_release_host(host); if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; + mmc_remove(host); mmc_claim_host(host); mmc_detach_bus(host); @@ -422,6 +422,53 @@ static void mmc_detect(struct mmc_host *host) } } +MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], + card->raw_cid[2], card->raw_cid[3]); +MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], + card->raw_csd[2], card->raw_csd[3]); +MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year); +MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev); +MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev); +MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid); +MMC_ATTR_FN(name, "%s\n", card->cid.prod_name); +MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid); +MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial); + +static struct device_attribute mmc_dev_attrs[] = { + MMC_ATTR_RO(cid), + MMC_ATTR_RO(csd), + MMC_ATTR_RO(date), + MMC_ATTR_RO(fwrev), + MMC_ATTR_RO(hwrev), + MMC_ATTR_RO(manfid), + MMC_ATTR_RO(name), + MMC_ATTR_RO(oemid), + MMC_ATTR_RO(serial), + __ATTR_NULL, +}; + +/* + * Adds sysfs entries as relevant. + */ +static int mmc_sysfs_add(struct mmc_host *host, struct mmc_card *card) +{ + int ret; + + ret = mmc_add_attrs(card, mmc_dev_attrs); + if (ret < 0) + return ret; + + return 0; +} + +/* + * Removes the sysfs entries added by mmc_sysfs_add(). + */ +static void mmc_sysfs_remove(struct mmc_host *host, struct mmc_card *card) +{ + mmc_remove_attrs(card, mmc_dev_attrs); +} + #ifdef CONFIG_MMC_UNSAFE_RESUME /* @@ -455,9 +502,7 @@ static void mmc_resume(struct mmc_host *host) err = mmc_sd_init_card(host, host->ocr, host->card); if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - + mmc_remove(host); mmc_detach_bus(host); } @@ -474,6 +519,8 @@ static void mmc_resume(struct mmc_host *host) static const struct mmc_bus_ops mmc_ops = { .remove = mmc_remove, .detect = mmc_detect, + .sysfs_add = mmc_sysfs_add, + .sysfs_remove = mmc_sysfs_remove, .suspend = mmc_suspend, .resume = mmc_resume, }; @@ -518,7 +565,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) mmc_release_host(host); - err = mmc_register_card(host->card); + err = mmc_add_card(host->card); if (err) goto reclaim_host; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 918477c490b0..1240684083f1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -19,11 +19,10 @@ #include "core.h" #include "sysfs.h" +#include "bus.h" #include "mmc_ops.h" #include "sd_ops.h" -#include "core.h" - static const unsigned int tran_exp[] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 @@ -487,8 +486,7 @@ static void mmc_sd_detect(struct mmc_host *host) mmc_release_host(host); if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; + mmc_sd_remove(host); mmc_claim_host(host); mmc_detach_bus(host); @@ -496,6 +494,55 @@ static void mmc_sd_detect(struct mmc_host *host) } } +MMC_ATTR_FN(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], + card->raw_cid[2], card->raw_cid[3]); +MMC_ATTR_FN(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], + card->raw_csd[2], card->raw_csd[3]); +MMC_ATTR_FN(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); +MMC_ATTR_FN(date, "%02d/%04d\n", card->cid.month, card->cid.year); +MMC_ATTR_FN(fwrev, "0x%x\n", card->cid.fwrev); +MMC_ATTR_FN(hwrev, "0x%x\n", card->cid.hwrev); +MMC_ATTR_FN(manfid, "0x%06x\n", card->cid.manfid); +MMC_ATTR_FN(name, "%s\n", card->cid.prod_name); +MMC_ATTR_FN(oemid, "0x%04x\n", card->cid.oemid); +MMC_ATTR_FN(serial, "0x%08x\n", card->cid.serial); + +static struct device_attribute mmc_sd_dev_attrs[] = { + MMC_ATTR_RO(cid), + MMC_ATTR_RO(csd), + MMC_ATTR_RO(scr), + MMC_ATTR_RO(date), + MMC_ATTR_RO(fwrev), + MMC_ATTR_RO(hwrev), + MMC_ATTR_RO(manfid), + MMC_ATTR_RO(name), + MMC_ATTR_RO(oemid), + MMC_ATTR_RO(serial), + __ATTR_NULL, +}; + +/* + * Adds sysfs entries as relevant. + */ +static int mmc_sd_sysfs_add(struct mmc_host *host, struct mmc_card *card) +{ + int ret; + + ret = mmc_add_attrs(card, mmc_sd_dev_attrs); + if (ret < 0) + return ret; + + return 0; +} + +/* + * Removes the sysfs entries added by mmc_sysfs_add(). + */ +static void mmc_sd_sysfs_remove(struct mmc_host *host, struct mmc_card *card) +{ + mmc_remove_attrs(card, mmc_sd_dev_attrs); +} + #ifdef CONFIG_MMC_UNSAFE_RESUME /* @@ -529,9 +576,7 @@ static void mmc_sd_resume(struct mmc_host *host) err = mmc_sd_init_card(host, host->ocr, host->card); if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - + mmc_sd_remove(host); mmc_detach_bus(host); } @@ -548,6 +593,8 @@ static void mmc_sd_resume(struct mmc_host *host) static const struct mmc_bus_ops mmc_sd_ops = { .remove = mmc_sd_remove, .detect = mmc_sd_detect, + .sysfs_add = mmc_sd_sysfs_add, + .sysfs_remove = mmc_sd_sysfs_remove, .suspend = mmc_sd_suspend, .resume = mmc_sd_resume, }; @@ -599,7 +646,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) mmc_release_host(host); - err = mmc_register_card(host->card); + err = mmc_add_card(host->card); if (err) goto reclaim_host; diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c index 843b1fbba557..a43a96c22811 100644 --- a/drivers/mmc/core/sysfs.c +++ b/drivers/mmc/core/sysfs.c @@ -2,6 +2,7 @@ * linux/drivers/mmc/core/sysfs.c * * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright 2007 Pierre Ossman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -18,226 +19,37 @@ #include #include +#include "bus.h" #include "sysfs.h" -#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) -#define MMC_ATTR(name, fmt, args...) \ -static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct mmc_card *card = dev_to_mmc_card(dev); \ - return sprintf(buf, fmt, args); \ -} - -MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], - card->raw_cid[2], card->raw_cid[3]); -MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], - card->raw_csd[2], card->raw_csd[3]); -MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); -MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); -MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); -MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev); -MMC_ATTR(manfid, "0x%06x\n", card->cid.manfid); -MMC_ATTR(name, "%s\n", card->cid.prod_name); -MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid); -MMC_ATTR(serial, "0x%08x\n", card->cid.serial); - -#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL) - -static struct device_attribute mmc_dev_attrs[] = { - MMC_ATTR_RO(cid), - MMC_ATTR_RO(csd), - MMC_ATTR_RO(date), - MMC_ATTR_RO(fwrev), - MMC_ATTR_RO(hwrev), - MMC_ATTR_RO(manfid), - MMC_ATTR_RO(name), - MMC_ATTR_RO(oemid), - MMC_ATTR_RO(serial), - __ATTR_NULL -}; - -static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr); - - -static void mmc_release_card(struct device *dev) +int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs) { - struct mmc_card *card = dev_to_mmc_card(dev); + int error = 0; + int i; - kfree(card); -} - -/* - * This currently matches any MMC driver to any MMC card - drivers - * themselves make the decision whether to drive this card in their - * probe method. - */ -static int mmc_bus_match(struct device *dev, struct device_driver *drv) -{ - return 1; -} - -static int -mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, - int buf_size) -{ - struct mmc_card *card = dev_to_mmc_card(dev); - char ccc[13]; - int retval = 0, i = 0, length = 0; - -#define add_env(fmt,val) do { \ - retval = add_uevent_var(envp, num_envp, &i, \ - buf, buf_size, &length, \ - fmt, val); \ - if (retval) \ - return retval; \ -} while (0); - - for (i = 0; i < 12; i++) - ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; - ccc[12] = '\0'; - - add_env("MMC_CCC=%s", ccc); - add_env("MMC_MANFID=%06x", card->cid.manfid); - add_env("MMC_NAME=%s", mmc_card_name(card)); - add_env("MMC_OEMID=%04x", card->cid.oemid); -#undef add_env - envp[i] = NULL; - - return 0; -} - -static int mmc_bus_suspend(struct device *dev, pm_message_t state) -{ - struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); - int ret = 0; - - if (dev->driver && drv->suspend) - ret = drv->suspend(card, state); - return ret; -} - -static int mmc_bus_resume(struct device *dev) -{ - struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); - int ret = 0; - - if (dev->driver && drv->resume) - ret = drv->resume(card); - return ret; -} - -static int mmc_bus_probe(struct device *dev) -{ - struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); - - return drv->probe(card); -} - -static int mmc_bus_remove(struct device *dev) -{ - struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = dev_to_mmc_card(dev); - - drv->remove(card); - - return 0; -} - -static struct bus_type mmc_bus_type = { - .name = "mmc", - .dev_attrs = mmc_dev_attrs, - .match = mmc_bus_match, - .uevent = mmc_bus_uevent, - .probe = mmc_bus_probe, - .remove = mmc_bus_remove, - .suspend = mmc_bus_suspend, - .resume = mmc_bus_resume, -}; - -/** - * mmc_register_driver - register a media driver - * @drv: MMC media driver - */ -int mmc_register_driver(struct mmc_driver *drv) -{ - drv->drv.bus = &mmc_bus_type; - return driver_register(&drv->drv); -} - -EXPORT_SYMBOL(mmc_register_driver); - -/** - * mmc_unregister_driver - unregister a media driver - * @drv: MMC media driver - */ -void mmc_unregister_driver(struct mmc_driver *drv) -{ - drv->drv.bus = &mmc_bus_type; - driver_unregister(&drv->drv); -} - -EXPORT_SYMBOL(mmc_unregister_driver); - - -/* - * Internal function. Initialise a MMC card structure. - */ -void mmc_init_card(struct mmc_card *card, struct mmc_host *host) -{ - memset(card, 0, sizeof(struct mmc_card)); - card->host = host; - device_initialize(&card->dev); - card->dev.parent = mmc_classdev(host); - card->dev.bus = &mmc_bus_type; - card->dev.release = mmc_release_card; -} - -/* - * Internal function. Register a new MMC card with the driver model. - */ -int mmc_register_card(struct mmc_card *card) -{ - int ret; - - snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), - "%s:%04x", mmc_hostname(card->host), card->rca); - - ret = device_add(&card->dev); - if (ret == 0) { - if (mmc_card_sd(card)) { - ret = device_create_file(&card->dev, &mmc_dev_attr_scr); - if (ret) - device_del(&card->dev); + for (i = 0; attr_name(attrs[i]); i++) { + error = device_create_file(&card->dev, &attrs[i]); + if (error) { + while (--i >= 0) + device_remove_file(&card->dev, &attrs[i]); + break; } } - if (ret == 0) - mmc_card_set_present(card); - return ret; + + return error; } -/* - * Internal function. Unregister a new MMC card with the - * driver model, and (eventually) free it. - */ -void mmc_remove_card(struct mmc_card *card) +void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs) { - if (mmc_card_present(card)) { - if (mmc_card_sd(card)) - device_remove_file(&card->dev, &mmc_dev_attr_scr); + int i; - device_del(&card->dev); - } - - put_device(&card->dev); + for (i = 0; attr_name(attrs[i]); i++) + device_remove_file(&card->dev, &attrs[i]); } - static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); @@ -340,11 +152,11 @@ static int __init mmc_init(void) if (!workqueue) return -ENOMEM; - ret = bus_register(&mmc_bus_type); + ret = mmc_register_bus(); if (ret == 0) { ret = class_register(&mmc_host_class); if (ret) - bus_unregister(&mmc_bus_type); + mmc_unregister_bus(); } return ret; } @@ -352,7 +164,7 @@ static int __init mmc_init(void) static void __exit mmc_exit(void) { class_unregister(&mmc_host_class); - bus_unregister(&mmc_bus_type); + mmc_unregister_bus(); destroy_workqueue(workqueue); } diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h index 80e29b358282..2a326a5b83c6 100644 --- a/drivers/mmc/core/sysfs.h +++ b/drivers/mmc/core/sysfs.h @@ -11,9 +11,17 @@ #ifndef _MMC_CORE_SYSFS_H #define _MMC_CORE_SYSFS_H -void mmc_init_card(struct mmc_card *card, struct mmc_host *host); -int mmc_register_card(struct mmc_card *card); -void mmc_remove_card(struct mmc_card *card); +#define MMC_ATTR_FN(name, fmt, args...) \ +static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + struct mmc_card *card = container_of(dev, struct mmc_card, dev);\ + return sprintf(buf, fmt, args); \ +} + +#define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL) + +int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs); +void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs); struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); int mmc_add_host_sysfs(struct mmc_host *host); From b93931a61a119575f84c33af2438b9384fde9eb7 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 19 May 2007 14:06:24 +0200 Subject: [PATCH 285/551] mmc: refactor host class handling Move basic host class device handling to its own file for clarity. Signed-off-by: Pierre Ossman --- drivers/mmc/core/Makefile | 2 +- drivers/mmc/core/core.c | 82 ++------------------ drivers/mmc/core/core.h | 4 + drivers/mmc/core/host.c | 156 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/host.h | 18 +++++ drivers/mmc/core/sysfs.c | 84 +------------------- drivers/mmc/core/sysfs.h | 5 -- 7 files changed, 187 insertions(+), 164 deletions(-) create mode 100644 drivers/mmc/core/host.c create mode 100644 drivers/mmc/core/host.h diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 54261e3724c4..3fdd08c7f143 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -7,6 +7,6 @@ ifeq ($(CONFIG_MMC_DEBUG),y) endif obj-$(CONFIG_MMC) += mmc_core.o -mmc_core-y := core.o sysfs.o bus.o \ +mmc_core-y := core.o sysfs.o bus.o host.o \ mmc.o mmc_ops.o sd.o sd_ops.o diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index d876adf4bd4e..66e463d100c5 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -496,7 +496,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) EXPORT_SYMBOL(mmc_detect_change); -static void mmc_rescan(struct work_struct *work) +void mmc_rescan(struct work_struct *work) { struct mmc_host *host = container_of(work, struct mmc_host, detect.work); @@ -545,69 +545,13 @@ static void mmc_rescan(struct work_struct *work) } } - -/** - * mmc_alloc_host - initialise the per-host structure. - * @extra: sizeof private data structure - * @dev: pointer to host device model structure - * - * Initialise the per-host structure. - */ -struct mmc_host *mmc_alloc_host(int extra, struct device *dev) +void mmc_start_host(struct mmc_host *host) { - struct mmc_host *host; - - host = mmc_alloc_host_sysfs(extra, dev); - if (host) { - spin_lock_init(&host->lock); - init_waitqueue_head(&host->wq); - INIT_DELAYED_WORK(&host->detect, mmc_rescan); - - /* - * By default, hosts do not support SGIO or large requests. - * They have to set these according to their abilities. - */ - host->max_hw_segs = 1; - host->max_phys_segs = 1; - host->max_seg_size = PAGE_CACHE_SIZE; - - host->max_req_size = PAGE_CACHE_SIZE; - host->max_blk_size = 512; - host->max_blk_count = PAGE_CACHE_SIZE / 512; - } - - return host; + mmc_power_off(host); + mmc_detect_change(host, 0); } -EXPORT_SYMBOL(mmc_alloc_host); - -/** - * mmc_add_host - initialise host hardware - * @host: mmc host - */ -int mmc_add_host(struct mmc_host *host) -{ - int ret; - - ret = mmc_add_host_sysfs(host); - if (ret == 0) { - mmc_power_off(host); - mmc_detect_change(host, 0); - } - - return ret; -} - -EXPORT_SYMBOL(mmc_add_host); - -/** - * mmc_remove_host - remove host hardware - * @host: mmc host - * - * Unregister and remove all cards associated with this host, - * and power down the MMC bus. - */ -void mmc_remove_host(struct mmc_host *host) +void mmc_stop_host(struct mmc_host *host) { #ifdef CONFIG_MMC_DEBUG unsigned long flags; @@ -632,24 +576,8 @@ void mmc_remove_host(struct mmc_host *host) BUG_ON(host->card); mmc_power_off(host); - mmc_remove_host_sysfs(host); } -EXPORT_SYMBOL(mmc_remove_host); - -/** - * mmc_free_host - free the host structure - * @host: mmc host - * - * Free the host once all references to it have been dropped. - */ -void mmc_free_host(struct mmc_host *host) -{ - mmc_free_host_sysfs(host); -} - -EXPORT_SYMBOL(mmc_free_host); - #ifdef CONFIG_PM /** diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 1be86c792a52..ae006b30dd86 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -66,5 +66,9 @@ static inline void mmc_delay(unsigned int ms) } } +void mmc_rescan(struct work_struct *work); +void mmc_start_host(struct mmc_host *host); +void mmc_stop_host(struct mmc_host *host); + #endif diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c new file mode 100644 index 000000000000..1433d95c40bb --- /dev/null +++ b/drivers/mmc/core/host.c @@ -0,0 +1,156 @@ +/* + * linux/drivers/mmc/core/host.c + * + * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright (C) 2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMC host class device management + */ + +#include +#include +#include +#include + +#include + +#include "core.h" +#include "host.h" + +#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) + +static void mmc_host_classdev_release(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + kfree(host); +} + +static struct class mmc_host_class = { + .name = "mmc_host", + .dev_release = mmc_host_classdev_release, +}; + +int mmc_register_host_class(void) +{ + return class_register(&mmc_host_class); +} + +void mmc_unregister_host_class(void) +{ + class_unregister(&mmc_host_class); +} + +static DEFINE_IDR(mmc_host_idr); +static DEFINE_SPINLOCK(mmc_host_lock); + +/** + * mmc_alloc_host - initialise the per-host structure. + * @extra: sizeof private data structure + * @dev: pointer to host device model structure + * + * Initialise the per-host structure. + */ +struct mmc_host *mmc_alloc_host(int extra, struct device *dev) +{ + struct mmc_host *host; + + host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); + if (!host) + return NULL; + + memset(host, 0, sizeof(struct mmc_host) + extra); + + host->parent = dev; + host->class_dev.parent = dev; + host->class_dev.class = &mmc_host_class; + device_initialize(&host->class_dev); + + spin_lock_init(&host->lock); + init_waitqueue_head(&host->wq); + INIT_DELAYED_WORK(&host->detect, mmc_rescan); + + /* + * By default, hosts do not support SGIO or large requests. + * They have to set these according to their abilities. + */ + host->max_hw_segs = 1; + host->max_phys_segs = 1; + host->max_seg_size = PAGE_CACHE_SIZE; + + host->max_req_size = PAGE_CACHE_SIZE; + host->max_blk_size = 512; + host->max_blk_count = PAGE_CACHE_SIZE / 512; + + return host; +} + +EXPORT_SYMBOL(mmc_alloc_host); + +/** + * mmc_add_host - initialise host hardware + * @host: mmc host + */ +int mmc_add_host(struct mmc_host *host) +{ + int err; + + if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) + return -ENOMEM; + + spin_lock(&mmc_host_lock); + err = idr_get_new(&mmc_host_idr, host, &host->index); + spin_unlock(&mmc_host_lock); + if (err) + return err; + + snprintf(host->class_dev.bus_id, BUS_ID_SIZE, + "mmc%d", host->index); + + err = device_add(&host->class_dev); + if (err) + return err; + + mmc_start_host(host); + + return 0; +} + +EXPORT_SYMBOL(mmc_add_host); + +/** + * mmc_remove_host - remove host hardware + * @host: mmc host + * + * Unregister and remove all cards associated with this host, + * and power down the MMC bus. + */ +void mmc_remove_host(struct mmc_host *host) +{ + mmc_stop_host(host); + + device_del(&host->class_dev); + + spin_lock(&mmc_host_lock); + idr_remove(&mmc_host_idr, host->index); + spin_unlock(&mmc_host_lock); +} + +EXPORT_SYMBOL(mmc_remove_host); + +/** + * mmc_free_host - free the host structure + * @host: mmc host + * + * Free the host once all references to it have been dropped. + */ +void mmc_free_host(struct mmc_host *host) +{ + put_device(&host->class_dev); +} + +EXPORT_SYMBOL(mmc_free_host); + diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h new file mode 100644 index 000000000000..c2dc3d2d9f9a --- /dev/null +++ b/drivers/mmc/core/host.h @@ -0,0 +1,18 @@ +/* + * linux/drivers/mmc/core/host.h + * + * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright 2007 Pierre Ossman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _MMC_CORE_HOST_H +#define _MMC_CORE_HOST_H + +int mmc_register_host_class(void); +void mmc_unregister_host_class(void); + +#endif + diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c index a43a96c22811..fbf99f9a0b83 100644 --- a/drivers/mmc/core/sysfs.c +++ b/drivers/mmc/core/sysfs.c @@ -20,11 +20,9 @@ #include #include "bus.h" +#include "host.h" #include "sysfs.h" -#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) -#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) - int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs) { int error = 0; @@ -50,82 +48,6 @@ void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs) device_remove_file(&card->dev, &attrs[i]); } -static void mmc_host_classdev_release(struct device *dev) -{ - struct mmc_host *host = cls_dev_to_mmc_host(dev); - kfree(host); -} - -static struct class mmc_host_class = { - .name = "mmc_host", - .dev_release = mmc_host_classdev_release, -}; - -static DEFINE_IDR(mmc_host_idr); -static DEFINE_SPINLOCK(mmc_host_lock); - -/* - * Internal function. Allocate a new MMC host. - */ -struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev) -{ - struct mmc_host *host; - - host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); - if (host) { - memset(host, 0, sizeof(struct mmc_host) + extra); - - host->parent = dev; - host->class_dev.parent = dev; - host->class_dev.class = &mmc_host_class; - device_initialize(&host->class_dev); - } - - return host; -} - -/* - * Internal function. Register a new MMC host with the MMC class. - */ -int mmc_add_host_sysfs(struct mmc_host *host) -{ - int err; - - if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(&mmc_host_lock); - err = idr_get_new(&mmc_host_idr, host, &host->index); - spin_unlock(&mmc_host_lock); - if (err) - return err; - - snprintf(host->class_dev.bus_id, BUS_ID_SIZE, - "mmc%d", host->index); - - return device_add(&host->class_dev); -} - -/* - * Internal function. Unregister a MMC host with the MMC class. - */ -void mmc_remove_host_sysfs(struct mmc_host *host) -{ - device_del(&host->class_dev); - - spin_lock(&mmc_host_lock); - idr_remove(&mmc_host_idr, host->index); - spin_unlock(&mmc_host_lock); -} - -/* - * Internal function. Free a MMC host. - */ -void mmc_free_host_sysfs(struct mmc_host *host) -{ - put_device(&host->class_dev); -} - static struct workqueue_struct *workqueue; /* @@ -154,7 +76,7 @@ static int __init mmc_init(void) ret = mmc_register_bus(); if (ret == 0) { - ret = class_register(&mmc_host_class); + ret = mmc_register_host_class(); if (ret) mmc_unregister_bus(); } @@ -163,7 +85,7 @@ static int __init mmc_init(void) static void __exit mmc_exit(void) { - class_unregister(&mmc_host_class); + mmc_unregister_host_class(); mmc_unregister_bus(); destroy_workqueue(workqueue); } diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h index 2a326a5b83c6..2f60c79b203b 100644 --- a/drivers/mmc/core/sysfs.h +++ b/drivers/mmc/core/sysfs.h @@ -23,11 +23,6 @@ static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *a int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs); void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs); -struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); -int mmc_add_host_sysfs(struct mmc_host *host); -void mmc_remove_host_sysfs(struct mmc_host *host); -void mmc_free_host_sysfs(struct mmc_host *host); - int mmc_schedule_work(struct work_struct *work); int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); void mmc_flush_scheduled_work(void); From ffce2e7e7060c949ccd703dacc9b3dd81b377373 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 19 May 2007 14:32:22 +0200 Subject: [PATCH 286/551] mmc: move layer init and workqueue to core file Signed-off-by: Pierre Ossman --- drivers/mmc/core/core.c | 49 +++++++++++++++++++++++++++++++++++++- drivers/mmc/core/sysfs.c | 51 ---------------------------------------- drivers/mmc/core/sysfs.h | 4 ---- 3 files changed, 48 insertions(+), 56 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 66e463d100c5..b5d8a6d90cca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -27,7 +27,8 @@ #include #include "core.h" -#include "sysfs.h" +#include "bus.h" +#include "host.h" #include "mmc_ops.h" #include "sd_ops.h" @@ -35,6 +36,25 @@ extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); +static struct workqueue_struct *workqueue; + +/* + * Internal function. Schedule delayed work in the MMC work queue. + */ +static int mmc_schedule_delayed_work(struct delayed_work *work, + unsigned long delay) +{ + return queue_delayed_work(workqueue, work, delay); +} + +/* + * Internal function. Flush all scheduled work from the MMC work queue. + */ +static void mmc_flush_scheduled_work(void) +{ + flush_workqueue(workqueue); +} + /** * mmc_request_done - finish processing an MMC request * @host: MMC host which completed request @@ -638,4 +658,31 @@ EXPORT_SYMBOL(mmc_resume_host); #endif +static int __init mmc_init(void) +{ + int ret; + + workqueue = create_singlethread_workqueue("kmmcd"); + if (!workqueue) + return -ENOMEM; + + ret = mmc_register_bus(); + if (ret == 0) { + ret = mmc_register_host_class(); + if (ret) + mmc_unregister_bus(); + } + return ret; +} + +static void __exit mmc_exit(void) +{ + mmc_unregister_host_class(); + mmc_unregister_bus(); + destroy_workqueue(workqueue); +} + +module_init(mmc_init); +module_exit(mmc_exit); + MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/core/sysfs.c b/drivers/mmc/core/sysfs.c index fbf99f9a0b83..00a97e70f914 100644 --- a/drivers/mmc/core/sysfs.c +++ b/drivers/mmc/core/sysfs.c @@ -10,17 +10,10 @@ * * MMC sysfs/driver model support. */ -#include -#include #include -#include -#include #include -#include -#include "bus.h" -#include "host.h" #include "sysfs.h" int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs) @@ -48,47 +41,3 @@ void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs) device_remove_file(&card->dev, &attrs[i]); } -static struct workqueue_struct *workqueue; - -/* - * Internal function. Schedule delayed work in the MMC work queue. - */ -int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) -{ - return queue_delayed_work(workqueue, work, delay); -} - -/* - * Internal function. Flush all scheduled work from the MMC work queue. - */ -void mmc_flush_scheduled_work(void) -{ - flush_workqueue(workqueue); -} - -static int __init mmc_init(void) -{ - int ret; - - workqueue = create_singlethread_workqueue("kmmcd"); - if (!workqueue) - return -ENOMEM; - - ret = mmc_register_bus(); - if (ret == 0) { - ret = mmc_register_host_class(); - if (ret) - mmc_unregister_bus(); - } - return ret; -} - -static void __exit mmc_exit(void) -{ - mmc_unregister_host_class(); - mmc_unregister_bus(); - destroy_workqueue(workqueue); -} - -module_init(mmc_init); -module_exit(mmc_exit); diff --git a/drivers/mmc/core/sysfs.h b/drivers/mmc/core/sysfs.h index 2f60c79b203b..4b8f670bd10f 100644 --- a/drivers/mmc/core/sysfs.h +++ b/drivers/mmc/core/sysfs.h @@ -23,8 +23,4 @@ static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *a int mmc_add_attrs(struct mmc_card *card, struct device_attribute *attrs); void mmc_remove_attrs(struct mmc_card *card, struct device_attribute *attrs); -int mmc_schedule_work(struct work_struct *work); -int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); -void mmc_flush_scheduled_work(void); - #endif From 8c75deae1ab99661975da098f8b721bafbb247c4 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 19 May 2007 16:14:43 +0200 Subject: [PATCH 287/551] mmc: fix silly copy-and-paste error Signed-off-by: Pierre Ossman --- drivers/mmc/core/mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e4371555160a..66f85bfa8dbb 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -237,7 +237,7 @@ out: * In the case of a resume, "curcard" will contain the card * we're trying to reinitialise. */ -static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, +static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; @@ -500,7 +500,7 @@ static void mmc_resume(struct mmc_host *host) mmc_claim_host(host); - err = mmc_sd_init_card(host, host->ocr, host->card); + err = mmc_init_card(host, host->ocr, host->card); if (err != MMC_ERR_NONE) { mmc_remove(host); mmc_detach_bus(host); @@ -559,7 +559,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) /* * Detect and init the card. */ - err = mmc_sd_init_card(host, host->ocr, NULL); + err = mmc_init_card(host, host->ocr, NULL); if (err != MMC_ERR_NONE) goto err; From 9d26a5d3f2b9c4fe4b2ba491683c6989ecd6ae04 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Tue, 26 Jun 2007 13:31:16 +0200 Subject: [PATCH 288/551] sdhci: Fix "Unexpected interrupt" handling Whenever a power interrupt is signaled it is also reported as an unexpected one. All other unexpected interrupts get lost. Cause is a not inversed bitmask to remove power interrupts from the status. Signed-off-by: Rolf Eike Beer Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5e9a6ce83559..10d15c39d003 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1030,7 +1030,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); } - intmask &= SDHCI_INT_BUS_POWER; + intmask &= ~SDHCI_INT_BUS_POWER; if (intmask) { printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", From e8d04d3dba60bdc139644350fcc88f82e40129dc Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 19 Jun 2007 18:32:34 +0200 Subject: [PATCH 289/551] mmc: at91_mci typo Typo fix in at91_mci driver : standardized the typo (at91_mci everywhere) Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman --- drivers/mmc/host/at91_mci.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 5b00c194b628..647f29473cf9 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -131,7 +131,7 @@ struct at91mci_host /* * Copy from sg to a dma block - used for transfers */ -static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data) +static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data) { unsigned int len, i, size; unsigned *dmabuf = host->buffer; @@ -180,7 +180,7 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data /* * Prepare a dma read */ -static void at91mci_pre_dma_read(struct at91mci_host *host) +static void at91_mci_pre_dma_read(struct at91mci_host *host) { int i; struct scatterlist *sg; @@ -248,7 +248,7 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) /* * Handle after a dma read */ -static void at91mci_post_dma_read(struct at91mci_host *host) +static void at91_mci_post_dma_read(struct at91mci_host *host) { struct mmc_command *cmd; struct mmc_data *data; @@ -299,7 +299,7 @@ static void at91mci_post_dma_read(struct at91mci_host *host) /* Is there another transfer to trigger? */ if (host->transfer_index < data->sg_len) - at91mci_pre_dma_read(host); + at91_mci_pre_dma_read(host); else { at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); @@ -464,7 +464,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ host->buffer = NULL; host->total_length = 0; - at91mci_pre_dma_read(host); + at91_mci_pre_dma_read(host); ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; } else { @@ -476,7 +476,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ host->total_length, &host->physical_address, GFP_KERNEL); - at91mci_sg_to_dma(host, data); + at91_mci_sg_to_dma(host, data); pr_debug("Transmitting %d bytes\n", host->total_length); @@ -506,7 +506,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ /* * Wait for a command to complete */ -static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd) +static void at91_mci_process_command(struct at91mci_host *host, struct mmc_command *cmd) { unsigned int ier; @@ -521,15 +521,15 @@ static void at91mci_process_command(struct at91mci_host *host, struct mmc_comman /* * Process the next step in the request */ -static void at91mci_process_next(struct at91mci_host *host) +static void at91_mci_process_next(struct at91mci_host *host) { if (!(host->flags & FL_SENT_COMMAND)) { host->flags |= FL_SENT_COMMAND; - at91mci_process_command(host, host->request->cmd); + at91_mci_process_command(host, host->request->cmd); } else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; - at91mci_process_command(host, host->request->stop); + at91_mci_process_command(host, host->request->stop); } else mmc_request_done(host->mmc, host->request); @@ -538,7 +538,7 @@ static void at91mci_process_next(struct at91mci_host *host) /* * Handle a command that has been completed */ -static void at91mci_completed_command(struct at91mci_host *host) +static void at91_mci_completed_command(struct at91mci_host *host) { struct mmc_command *cmd = host->cmd; unsigned int status; @@ -583,7 +583,7 @@ static void at91mci_completed_command(struct at91mci_host *host) else cmd->error = MMC_ERR_NONE; - at91mci_process_next(host); + at91_mci_process_next(host); } /* @@ -595,7 +595,7 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->request = mrq; host->flags = 0; - at91mci_process_next(host); + at91_mci_process_next(host); } /* @@ -708,7 +708,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_ENDRX) { pr_debug("Receive has ended\n"); - at91mci_post_dma_read(host); + at91_mci_post_dma_read(host); } if (int_status & AT91_MCI_NOTBUSY) { @@ -737,7 +737,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (completed) { pr_debug("Completed command\n"); at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); - at91mci_completed_command(host); + at91_mci_completed_command(host); } else at91_mci_write(host, AT91_MCI_IDR, int_status); From ed99c541e0a15281c57530d54a4a5e3272f74fb9 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Mon, 9 Jul 2007 14:58:16 +0200 Subject: [PATCH 290/551] mmc: at91_mci: fix hanging and rework to match flowcharts Fixes hanging using multi block operations (seen during CMD25). Follows closely the datasheet flowcharts. This piece of code handles better big file writing. I had to take care of the notbusy signal during write (at91_mci_handle_cmdrdy function) and to rearrange the AT91_MCI_ENDRX and AT91_MCI_RXBUFF flag usage. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman --- drivers/mmc/host/at91_mci.c | 191 ++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 87 deletions(-) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 647f29473cf9..28c881895ab7 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -78,8 +78,6 @@ #define DRIVER_NAME "at91_mci" -#undef SUPPORT_4WIRE - #define FL_SENT_COMMAND (1 << 0) #define FL_SENT_STOP (1 << 1) @@ -268,8 +266,6 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) } while (host->in_use_index < host->transfer_index) { - unsigned int *buffer; - struct scatterlist *sg; pr_debug("finishing index %d\n", host->in_use_index); @@ -280,20 +276,22 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); - /* Swap the contents of the buffer */ - buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; - pr_debug("buffer = %p, length = %d\n", buffer, sg->length); - data->bytes_xfered += sg->length; if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ + unsigned int *buffer; int index; + /* Swap the contents of the buffer */ + buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; + pr_debug("buffer = %p, length = %d\n", buffer, sg->length); + for (index = 0; index < (sg->length / 4); index++) buffer[index] = swab32(buffer[index]); + + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); } - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); flush_dcache_page(sg->page); } @@ -301,8 +299,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) if (host->transfer_index < data->sg_len) at91_mci_pre_dma_read(host); else { + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); - at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); } pr_debug("post dma read done\n"); @@ -323,7 +321,6 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) /* Now wait for cmd ready */ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE); - at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); cmd = host->cmd; if (!cmd) return; @@ -331,18 +328,53 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) data = cmd->data; if (!data) return; + if (cmd->data->flags & MMC_DATA_MULTI) { + pr_debug("multiple write : wait for BLKE...\n"); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); + } else + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); + data->bytes_xfered = host->total_length; } +/*Handle after command sent ready*/ +static int at91_mci_handle_cmdrdy(struct at91mci_host *host) +{ + if (!host->cmd) + return 1; + else if (!host->cmd->data) { + if (host->flags & FL_SENT_STOP) { + /*After multi block write, we must wait for NOTBUSY*/ + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); + } else return 1; + } else if (host->cmd->data->flags & MMC_DATA_WRITE) { + /*After sendding multi-block-write command, start DMA transfer*/ + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); + } + + /* command not completed, have to wait */ + return 0; +} + + /* * Enable the controller */ static void at91_mci_enable(struct at91mci_host *host) { + unsigned int mr; + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); - at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a); + mr = AT91_MCI_PDCMODE | 0x34a; + + if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) + mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; + + at91_mci_write(host, AT91_MCI_MR, mr); /* use Slot A or B (only one at same time) */ at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b); @@ -358,9 +390,8 @@ static void at91_mci_disable(struct at91mci_host *host) /* * Send a command - * return the interrupts to enable */ -static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd) +static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd) { unsigned int cmdr, mr; unsigned int block_length; @@ -371,8 +402,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ host->cmd = cmd; - /* Not sure if this is needed */ -#if 0 + /* Needed for leaving busy state before CMD1 */ if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { pr_debug("Clearing timeout\n"); at91_mci_write(host, AT91_MCI_ARGR, 0); @@ -382,7 +412,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR)); } } -#endif + cmdr = cmd->opcode; if (mmc_resp_type(cmd) == MMC_RSP_NONE) @@ -439,50 +469,48 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ at91_mci_write(host, ATMEL_PDC_TCR, 0); at91_mci_write(host, ATMEL_PDC_TNPR, 0); at91_mci_write(host, ATMEL_PDC_TNCR, 0); + ier = AT91_MCI_CMDRDY; + } else { + /* zero block length and PDC mode */ + mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; + at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); - at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); - at91_mci_write(host, AT91_MCI_CMDR, cmdr); - return AT91_MCI_CMDRDY; - } + /* + * Disable the PDC controller + */ + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); - mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ - at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); + if (cmdr & AT91_MCI_TRCMD_START) { + data->bytes_xfered = 0; + host->transfer_index = 0; + host->in_use_index = 0; + if (cmdr & AT91_MCI_TRDIR) { + /* + * Handle a read + */ + host->buffer = NULL; + host->total_length = 0; - /* - * Disable the PDC controller - */ - at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); + at91_mci_pre_dma_read(host); + ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; + } + else { + /* + * Handle a write + */ + host->total_length = block_length * blocks; + host->buffer = dma_alloc_coherent(NULL, + host->total_length, + &host->physical_address, GFP_KERNEL); - if (cmdr & AT91_MCI_TRCMD_START) { - data->bytes_xfered = 0; - host->transfer_index = 0; - host->in_use_index = 0; - if (cmdr & AT91_MCI_TRDIR) { - /* - * Handle a read - */ - host->buffer = NULL; - host->total_length = 0; + at91_mci_sg_to_dma(host, data); - at91_mci_pre_dma_read(host); - ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; - } - else { - /* - * Handle a write - */ - host->total_length = block_length * blocks; - host->buffer = dma_alloc_coherent(NULL, - host->total_length, - &host->physical_address, GFP_KERNEL); + pr_debug("Transmitting %d bytes\n", host->total_length); - at91_mci_sg_to_dma(host, data); - - pr_debug("Transmitting %d bytes\n", host->total_length); - - at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); - at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4); - ier = AT91_MCI_TXBUFE; + at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); + at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4); + ier = AT91_MCI_CMDRDY; + } } } @@ -497,24 +525,9 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ if (cmdr & AT91_MCI_TRCMD_START) { if (cmdr & AT91_MCI_TRDIR) at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN); - else - at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); } - return ier; -} -/* - * Wait for a command to complete - */ -static void at91_mci_process_command(struct at91mci_host *host, struct mmc_command *cmd) -{ - unsigned int ier; - - ier = at91_mci_send_command(host, cmd); - - pr_debug("setting ier to %08X\n", ier); - - /* Stop on errors or the required value */ + /* Enable selected interrupts */ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier); } @@ -525,11 +538,11 @@ static void at91_mci_process_next(struct at91mci_host *host) { if (!(host->flags & FL_SENT_COMMAND)) { host->flags |= FL_SENT_COMMAND; - at91_mci_process_command(host, host->request->cmd); + at91_mci_send_command(host, host->request->cmd); } else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; - at91_mci_process_command(host, host->request->stop); + at91_mci_send_command(host, host->request->stop); } else mmc_request_done(host->mmc, host->request); @@ -698,29 +711,33 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) at91_mci_handle_transmitted(host); } + if (int_status & AT91_MCI_ENDRX) { + pr_debug("ENDRX\n"); + at91_mci_post_dma_read(host); + } + if (int_status & AT91_MCI_RXBUFF) { pr_debug("RX buffer full\n"); - at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); + at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX); + completed = 1; } if (int_status & AT91_MCI_ENDTX) pr_debug("Transmit has ended\n"); - if (int_status & AT91_MCI_ENDRX) { - pr_debug("Receive has ended\n"); - at91_mci_post_dma_read(host); - } - if (int_status & AT91_MCI_NOTBUSY) { pr_debug("Card is ready\n"); - at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); + completed = 1; } if (int_status & AT91_MCI_DTIP) pr_debug("Data transfer in progress\n"); - if (int_status & AT91_MCI_BLKE) + if (int_status & AT91_MCI_BLKE) { pr_debug("Block transfer has ended\n"); + completed = 1; + } if (int_status & AT91_MCI_TXRDY) pr_debug("Ready to transmit\n"); @@ -730,7 +747,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_CMDRDY) { pr_debug("Command ready\n"); - completed = 1; + completed = at91_mci_handle_cmdrdy(host); } } @@ -830,11 +847,11 @@ static int __init at91_mci_probe(struct platform_device *pdev) host->bus_mode = 0; host->board = pdev->dev.platform_data; if (host->board->wire4) { -#ifdef SUPPORT_4WIRE - mmc->caps |= MMC_CAP_4_BIT_DATA; -#else - printk("AT91 MMC: 4 wire bus mode not supported by this driver - using 1 wire\n"); -#endif + if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) + mmc->caps |= MMC_CAP_4_BIT_DATA; + else + printk("AT91 MMC: 4 wire bus mode not supported" + " - using 1 wire\n"); } /* From b740d8846e2e184909e9f74d4ad9d67ae0e084ea Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:53 +0200 Subject: [PATCH 291/551] serverworks: always tune CSB6 Switch the driver to always program DMA/PIO timings and set device transfer mode instead of trusting BIOS on CSB6 controllers (libata pata_serverworks.c driver is also doing things this way and there were no problems reported so far). While doing conversion I noticed that the old code had many issues: * the code was assuming that hwif->dma_status is always valid (which obviously isn't true if hwif->dma_base == NULL) * value of "(ultra_timing >> (4*unit)) & ~(0xF0)" expression wasn't checked to fit into udma_modes[5] * code validating DMA timings didn't validate corresponding PIO timings * extra CSB5 PIO register wasn't validated et all * hwif->ide_dma_off_quietly() is always called before ide_set_dma() (which in turn calls hwif->speedproc() method - svwks_tune_chipset() in this case) so the code depending on DMA capable bit of DMA status to be set was never executed (=> the code was never validating DMA timings despite actually enabling DMA if the PIO timings were OK!) * on resume driver dependend entirely on BIOS to restore timings and set transfer mode on the device While at it: There is no need to read PIO/MWDMA timings now so don't do it. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Alan Cox --- drivers/ide/pci/serverworks.c | 77 +---------------------------------- 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index d9c4fd1ae996..09a7aedf63ac 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/serverworks.c Version 0.11 Jun 2 2007 + * linux/drivers/ide/pci/serverworks.c Version 0.20 Jun 3 2007 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz @@ -151,84 +151,11 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 && drive->media == ide_disk && speed >= XFER_UDMA_0) BUG(); - - pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing); - pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing); + pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); pci_read_config_word(dev, 0x4A, &csb5_pio); pci_read_config_byte(dev, 0x54, &ultra_enable); - /* If we are in RAID mode (eg AMI MegaIDE) then we can't it - turns out trust the firmware configuration */ - - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) - goto oem_setup_failed; - - /* Per Specified Design by OEM, and ASIC Architect */ - if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { - if (!drive->init_speed) { - u8 dma_stat = inb(hwif->dma_status); - - if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) && - ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) { - drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)]; - return 0; - } else if ((dma_timing) && - ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) { - u8 dmaspeed; - - switch (dma_timing & 0x77) { - case 0x20: - dmaspeed = XFER_MW_DMA_2; - break; - case 0x21: - dmaspeed = XFER_MW_DMA_1; - break; - case 0x77: - dmaspeed = XFER_MW_DMA_0; - break; - default: - goto dma_pio; - } - - drive->current_speed = drive->init_speed = dmaspeed; - return 0; - } -dma_pio: - if (pio_timing) { - u8 piospeed; - - switch (pio_timing & 0x7f) { - case 0x20: - piospeed = XFER_PIO_4; - break; - case 0x22: - piospeed = XFER_PIO_3; - break; - case 0x34: - piospeed = XFER_PIO_2; - break; - case 0x47: - piospeed = XFER_PIO_1; - break; - case 0x5d: - piospeed = XFER_PIO_0; - break; - default: - goto oem_setup_failed; - } - - drive->current_speed = drive->init_speed = piospeed; - return 0; - } - } - } - -oem_setup_failed: - - pio_timing = 0; - dma_timing = 0; ultra_timing &= ~(0x0F << (4*unit)); ultra_enable &= ~(0x01 << drive->dn); csb5_pio &= ~(0x0F << (4*drive->dn)); From 841d2a9bf16471716ba3a5172d24aa40a2ea9398 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:54 +0200 Subject: [PATCH 292/551] ide: make void and rename ide_dma_lostirq() method Since ide_dma_lostirq() method's result is discarded, make it return 'void'. While at it, rename the method to dma_lost_irq(), drop the '__' prefix from the default method's name, and do some cleanups in this method driver-wise: - in aec62xx.c, rename the method in accordance with other drivers, and get rid of unnecessary variables there; - in pdc202xx_old.c, define/use 'hwif' variable; - in sgiioc4.c, rearrange the code to call the resetproc() method directly. Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 5 ++--- drivers/ide/ide-dma.c | 9 ++++----- drivers/ide/ide-io.c | 2 +- drivers/ide/ide.c | 2 +- drivers/ide/mips/au1xxx-ide.c | 5 ++--- drivers/ide/pci/aec62xx.c | 10 +++------- drivers/ide/pci/hpt366.c | 6 +++--- drivers/ide/pci/pdc202xx_old.c | 13 ++++++++----- drivers/ide/pci/sgiioc4.c | 18 +++++++++--------- drivers/ide/pci/sl82c105.c | 7 ++----- drivers/ide/ppc/pmac.c | 9 ++++----- include/linux/ide.h | 4 ++-- 12 files changed, 41 insertions(+), 49 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 66f826252aee..543f8b51f6b1 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -461,10 +461,9 @@ static int icside_dma_timeout(ide_drive_t *drive) return icside_dma_end(drive); } -static int icside_dma_lostirq(ide_drive_t *drive) +static void icside_dma_lost_irq(ide_drive_t *drive) { printk(KERN_ERR "%s: IRQ lost\n", drive->name); - return 1; } static void icside_dma_init(ide_hwif_t *hwif) @@ -491,7 +490,7 @@ static void icside_dma_init(ide_hwif_t *hwif) hwif->ide_dma_end = icside_dma_end; hwif->ide_dma_test_irq = icside_dma_test_irq; hwif->ide_dma_timeout = icside_dma_timeout; - hwif->ide_dma_lostirq = icside_dma_lostirq; + hwif->dma_lost_irq = icside_dma_lost_irq; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index ead141e2db9e..ce322602982e 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -850,13 +850,12 @@ int ide_set_dma(ide_drive_t *drive) EXPORT_SYMBOL_GPL(ide_set_dma); #ifdef CONFIG_BLK_DEV_IDEDMA_PCI -int __ide_dma_lostirq (ide_drive_t *drive) +void ide_dma_lost_irq (ide_drive_t *drive) { printk("%s: DMA interrupt recovery\n", drive->name); - return 1; } -EXPORT_SYMBOL(__ide_dma_lostirq); +EXPORT_SYMBOL(ide_dma_lost_irq); int __ide_dma_timeout (ide_drive_t *drive) { @@ -1020,8 +1019,8 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p hwif->ide_dma_test_irq = &__ide_dma_test_irq; if (!hwif->ide_dma_timeout) hwif->ide_dma_timeout = &__ide_dma_timeout; - if (!hwif->ide_dma_lostirq) - hwif->ide_dma_lostirq = &__ide_dma_lostirq; + if (!hwif->dma_lost_irq) + hwif->dma_lost_irq = &ide_dma_lost_irq; if (hwif->chipset != ide_trm290) { u8 dma_stat = hwif->INB(hwif->dma_status); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index bfe8f1b712ba..9f4f8878b551 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1466,7 +1466,7 @@ void ide_timer_expiry (unsigned long data) startstop = handler(drive); } else if (drive_is_ready(drive)) { if (drive->waiting_for_dma) - (void) hwgroup->hwif->ide_dma_lostirq(drive); + hwgroup->hwif->dma_lost_irq(drive); (void)ide_ack_intr(hwif); printk(KERN_WARNING "%s: lost interrupt\n", drive->name); startstop = handler(drive); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 0cd76bf66833..8a8674d3223f 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -496,7 +496,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; hwif->dma_host_on = tmp_hwif->dma_host_on; hwif->dma_host_off = tmp_hwif->dma_host_off; - hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; + hwif->dma_lost_irq = tmp_hwif->dma_lost_irq; hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout; hwif->OUTB = tmp_hwif->OUTB; diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index ca95e990862e..e8935519edbe 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -456,10 +456,9 @@ static void auide_dma_off_quietly(ide_drive_t *drive) drive->using_dma = 0; } -static int auide_dma_lostirq(ide_drive_t *drive) +static void auide_dma_lost_irq(ide_drive_t *drive) { printk(KERN_ERR "%s: IRQ lost\n", drive->name); - return 0; } static void auide_ddma_tx_callback(int irq, void *param) @@ -731,7 +730,7 @@ static int au_ide_probe(struct device *dev) hwif->ide_dma_test_irq = &auide_dma_test_irq; hwif->dma_host_off = &auide_dma_host_off; hwif->dma_host_on = &auide_dma_host_on; - hwif->ide_dma_lostirq = &auide_dma_lostirq; + hwif->dma_lost_irq = &auide_dma_lost_irq; hwif->ide_dma_on = &auide_dma_on; hwif->autodma = 1; diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index b173bc66ce1e..bed32d0eaa37 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -172,12 +172,9 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) return -1; } -static int aec62xx_irq_timeout (ide_drive_t *drive) +static void aec62xx_dma_lost_irq (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - switch(dev->device) { + switch (HWIF(drive)->pci_dev->device) { case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: case PCI_DEVICE_ID_ARTOP_ATP865: @@ -186,7 +183,6 @@ static int aec62xx_irq_timeout (ide_drive_t *drive) default: break; } - return 0; } static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) @@ -254,7 +250,7 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; - hwif->ide_dma_lostirq = &aec62xx_irq_timeout; + hwif->dma_lost_irq = &aec62xx_dma_lost_irq; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index c33d0b0f11c9..34d06dc7f2b2 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -737,7 +737,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) * This is specific to the HPT366 UDMA chipset * by HighPoint|Triones Technologies, Inc. */ -static int hpt366_ide_dma_lostirq(ide_drive_t *drive) +static void hpt366_dma_lost_irq(ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 mcr1 = 0, mcr3 = 0, scr1 = 0; @@ -749,7 +749,7 @@ static int hpt366_ide_dma_lostirq(ide_drive_t *drive) drive->name, __FUNCTION__, mcr1, mcr3, scr1); if (scr1 & 0x10) pci_write_config_byte(dev, 0x5a, scr1 & ~0x10); - return __ide_dma_lostirq(drive); + ide_dma_lost_irq(drive); } static void hpt370_clear_engine(ide_drive_t *drive) @@ -1355,7 +1355,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->ide_dma_end = &hpt370_ide_dma_end; hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; } else - hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; + hwif->dma_lost_irq = &hpt366_dma_lost_irq; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 23844687deea..5013df84e971 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -267,11 +267,14 @@ somebody_else: return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ } -static int pdc202xx_ide_dma_lostirq(ide_drive_t *drive) +static void pdc202xx_dma_lost_irq(ide_drive_t *drive) { - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_lostirq(drive); + ide_hwif_t *hwif = HWIF(drive); + + if (hwif->resetproc != NULL) + hwif->resetproc(drive); + + ide_dma_lost_irq(drive); } static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) @@ -347,7 +350,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->err_stops_fifo = 1; hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; - hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; + hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index d3185e29a38e..53bee59264ef 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -316,14 +316,6 @@ static void sgiioc4_dma_host_off(ide_drive_t * drive) sgiioc4_clearirq(drive); } -static int -sgiioc4_ide_dma_lostirq(ide_drive_t * drive) -{ - HWIF(drive)->resetproc(drive); - - return __ide_dma_lostirq(drive); -} - static void sgiioc4_resetproc(ide_drive_t * drive) { @@ -331,6 +323,14 @@ sgiioc4_resetproc(ide_drive_t * drive) sgiioc4_clearirq(drive); } +static void +sgiioc4_dma_lost_irq(ide_drive_t * drive) +{ + sgiioc4_resetproc(drive); + + ide_dma_lost_irq(drive); +} + static u8 sgiioc4_INB(unsigned long port) { @@ -607,7 +607,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; hwif->dma_host_on = &sgiioc4_dma_host_on; hwif->dma_host_off = &sgiioc4_dma_host_off; - hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; + hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; hwif->ide_dma_timeout = &__ide_dma_timeout; hwif->INB = &sgiioc4_INB; diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 7c383d9cc472..202ce4965b60 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -195,7 +195,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) * This function is called when the IDE timer expires, the drive * indicates that it is READY, and we were waiting for DMA to complete. */ -static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) +static void sl82c105_dma_lost_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -222,9 +222,6 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) } sl82c105_reset_host(dev); - - /* __ide_dma_lostirq would return 1, so we do as well */ - return 1; } /* @@ -441,7 +438,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) hwif->ide_dma_check = &sl82c105_ide_dma_check; hwif->ide_dma_on = &sl82c105_ide_dma_on; hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; + hwif->dma_lost_irq = &sl82c105_dma_lost_irq; hwif->dma_start = &sl82c105_dma_start; hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 45fc36f0f219..ca72ad202ebc 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -2004,20 +2004,19 @@ static void pmac_ide_dma_host_on(ide_drive_t *drive) { } -static int -pmac_ide_dma_lostirq (ide_drive_t *drive) +static void +pmac_ide_dma_lost_irq (ide_drive_t *drive) { pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; volatile struct dbdma_regs __iomem *dma; unsigned long status; if (pmif == NULL) - return 0; + return; dma = pmif->dma_regs; status = readl(&dma->status); printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status); - return 0; } /* @@ -2058,7 +2057,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->dma_host_off = &pmac_ide_dma_host_off; hwif->dma_host_on = &pmac_ide_dma_host_on; hwif->ide_dma_timeout = &__ide_dma_timeout; - hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq; + hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; hwif->atapi_dma = 1; switch(pmif->kind) { diff --git a/include/linux/ide.h b/include/linux/ide.h index 1e365acdd369..d7f74e7c5155 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -735,7 +735,7 @@ typedef struct hwif_s { void (*ide_dma_clear_irq)(ide_drive_t *drive); void (*dma_host_on)(ide_drive_t *drive); void (*dma_host_off)(ide_drive_t *drive); - int (*ide_dma_lostirq)(ide_drive_t *drive); + void (*dma_lost_irq)(ide_drive_t *drive); int (*ide_dma_timeout)(ide_drive_t *drive); void (*OUTB)(u8 addr, unsigned long port); @@ -1304,7 +1304,7 @@ extern int __ide_dma_check(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *); extern void ide_dma_start(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *); -extern int __ide_dma_lostirq(ide_drive_t *); +extern void ide_dma_lost_irq(ide_drive_t *); extern int __ide_dma_timeout(ide_drive_t *); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ From c283f5dbe31920ca70b80a594a97bfaa2a28be13 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:54 +0200 Subject: [PATCH 293/551] ide: make void and rename ide_dma_timeout() method Since ide_dma_timeout() method's result is discarded, make it return 'void'. While at it, drop 'ide_' from the method's name, drop the '__' prefix from the default method's name, and do some cleanups in this method driver-wise: - in ide-dma.c, au1xxx-ide.c, and pdc202xx_old.c, define/use 'hwif' variable; - in au1xxx-ide.c, get rid of commented out printk(); - in sl82c105.c, get rid of unnecessary variables. Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 11 +++++------ drivers/ide/ide-dma.c | 19 +++++++++++-------- drivers/ide/ide-io.c | 2 +- drivers/ide/ide.c | 2 +- drivers/ide/mips/au1xxx-ide.c | 12 ++++++------ drivers/ide/pci/hpt366.c | 6 +++--- drivers/ide/pci/pdc202xx_old.c | 13 ++++++++----- drivers/ide/pci/sgiioc4.c | 2 +- drivers/ide/pci/sl82c105.c | 13 +++++-------- drivers/ide/ppc/pmac.c | 2 +- include/linux/ide.h | 4 ++-- 11 files changed, 44 insertions(+), 42 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 543f8b51f6b1..444a0b84f5bd 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -448,17 +448,16 @@ static int icside_dma_test_irq(ide_drive_t *drive) ICS_ARCIN_V6_INTRSTAT_1)) & 1; } -static int icside_dma_timeout(ide_drive_t *drive) +static void icside_dma_timeout(ide_drive_t *drive) { printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); if (icside_dma_test_irq(drive)) - return 0; + return; - ide_dump_status(drive, "DMA timeout", - HWIF(drive)->INB(IDE_STATUS_REG)); + ide_dump_status(drive, "DMA timeout", HWIF(drive)->INB(IDE_STATUS_REG)); - return icside_dma_end(drive); + icside_dma_end(drive); } static void icside_dma_lost_irq(ide_drive_t *drive) @@ -489,7 +488,7 @@ static void icside_dma_init(ide_hwif_t *hwif) hwif->dma_start = icside_dma_start; hwif->ide_dma_end = icside_dma_end; hwif->ide_dma_test_irq = icside_dma_test_irq; - hwif->ide_dma_timeout = icside_dma_timeout; + hwif->dma_timeout = icside_dma_timeout; hwif->dma_lost_irq = icside_dma_lost_irq; hwif->drives[0].autodma = hwif->autodma; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index ce322602982e..ca55bfa4ac74 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -857,16 +857,19 @@ void ide_dma_lost_irq (ide_drive_t *drive) EXPORT_SYMBOL(ide_dma_lost_irq); -int __ide_dma_timeout (ide_drive_t *drive) +void ide_dma_timeout (ide_drive_t *drive) { - printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); - if (HWIF(drive)->ide_dma_test_irq(drive)) - return 0; + ide_hwif_t *hwif = HWIF(drive); - return HWIF(drive)->ide_dma_end(drive); + printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); + + if (hwif->ide_dma_test_irq(drive)) + return; + + hwif->ide_dma_end(drive); } -EXPORT_SYMBOL(__ide_dma_timeout); +EXPORT_SYMBOL(ide_dma_timeout); /* * Needed for allowing full modular support of ide-driver @@ -1017,8 +1020,8 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p hwif->ide_dma_end = &__ide_dma_end; if (!hwif->ide_dma_test_irq) hwif->ide_dma_test_irq = &__ide_dma_test_irq; - if (!hwif->ide_dma_timeout) - hwif->ide_dma_timeout = &__ide_dma_timeout; + if (!hwif->dma_timeout) + hwif->dma_timeout = &ide_dma_timeout; if (!hwif->dma_lost_irq) hwif->dma_lost_irq = &ide_dma_lost_irq; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 9f4f8878b551..c5b5011da56e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1350,7 +1350,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) hwif->INB(IDE_STATUS_REG)); } else { printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); - (void) hwif->ide_dma_timeout(drive); + hwif->dma_timeout(drive); } /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 8a8674d3223f..3717a329b43b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -497,7 +497,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->dma_host_on = tmp_hwif->dma_host_on; hwif->dma_host_off = tmp_hwif->dma_host_off; hwif->dma_lost_irq = tmp_hwif->dma_lost_irq; - hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout; + hwif->dma_timeout = tmp_hwif->dma_timeout; hwif->OUTB = tmp_hwif->OUTB; hwif->OUTBSYNC = tmp_hwif->OUTBSYNC; diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index e8935519edbe..405903c42ba1 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -488,16 +488,16 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) -static int auide_dma_timeout(ide_drive_t *drive) +static void auide_dma_timeout(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); + ide_hwif_t *hwif = HWIF(drive); printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); - if (HWIF(drive)->ide_dma_test_irq(drive)) - return 0; + if (hwif->ide_dma_test_irq(drive)) + return; - return HWIF(drive)->ide_dma_end(drive); + hwif->ide_dma_end(drive); } @@ -720,7 +720,7 @@ static int au_ide_probe(struct device *dev) #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA hwif->dma_off_quietly = &auide_dma_off_quietly; - hwif->ide_dma_timeout = &auide_dma_timeout; + hwif->dma_timeout = &auide_dma_timeout; hwif->ide_dma_check = &auide_dma_check; hwif->dma_exec_cmd = &auide_dma_exec_cmd; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 34d06dc7f2b2..65018814ed73 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -799,10 +799,10 @@ static int hpt370_ide_dma_end(ide_drive_t *drive) return __ide_dma_end(drive); } -static int hpt370_ide_dma_timeout(ide_drive_t *drive) +static void hpt370_dma_timeout(ide_drive_t *drive) { hpt370_irq_timeout(drive); - return __ide_dma_timeout(drive); + ide_dma_timeout(drive); } /* returns 1 if DMA IRQ issued, 0 otherwise */ @@ -1353,7 +1353,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) } else if (chip_type >= HPT370) { hwif->dma_start = &hpt370_ide_dma_start; hwif->ide_dma_end = &hpt370_ide_dma_end; - hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; + hwif->dma_timeout = &hpt370_dma_timeout; } else hwif->dma_lost_irq = &hpt366_dma_lost_irq; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 5013df84e971..ae628b86e18a 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -277,11 +277,14 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive) ide_dma_lost_irq(drive); } -static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) +static void pdc202xx_dma_timeout(ide_drive_t *drive) { - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_timeout(drive); + ide_hwif_t *hwif = HWIF(drive); + + if (hwif->resetproc != NULL) + hwif->resetproc(drive); + + ide_dma_timeout(drive); } static void pdc202xx_reset_host (ide_hwif_t *hwif) @@ -351,7 +354,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; - hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; + hwif->dma_timeout = &pdc202xx_dma_timeout; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { if (!(hwif->udma_four)) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 53bee59264ef..d396b2929ed8 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -608,7 +608,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->dma_host_on = &sgiioc4_dma_host_on; hwif->dma_host_off = &sgiioc4_dma_host_off; hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; - hwif->ide_dma_timeout = &__ide_dma_timeout; + hwif->dma_timeout = &ide_dma_timeout; hwif->INB = &sgiioc4_INB; } diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 202ce4965b60..487879842af4 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -241,15 +241,12 @@ static void sl82c105_dma_start(ide_drive_t *drive) ide_dma_start(drive); } -static int sl82c105_ide_dma_timeout(ide_drive_t *drive) +static void sl82c105_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name)); - DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); - - sl82c105_reset_host(dev); - return __ide_dma_timeout(drive); + sl82c105_reset_host(HWIF(drive)->pci_dev); + ide_dma_timeout(drive); } static int sl82c105_ide_dma_on(ide_drive_t *drive) @@ -440,7 +437,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) hwif->dma_off_quietly = &sl82c105_dma_off_quietly; hwif->dma_lost_irq = &sl82c105_dma_lost_irq; hwif->dma_start = &sl82c105_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + hwif->dma_timeout = &sl82c105_dma_timeout; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ca72ad202ebc..f9bada093d19 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -2056,7 +2056,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; hwif->dma_host_off = &pmac_ide_dma_host_off; hwif->dma_host_on = &pmac_ide_dma_host_on; - hwif->ide_dma_timeout = &__ide_dma_timeout; + hwif->dma_timeout = &ide_dma_timeout; hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; hwif->atapi_dma = 1; diff --git a/include/linux/ide.h b/include/linux/ide.h index d7f74e7c5155..0bacf7f7c791 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -736,7 +736,7 @@ typedef struct hwif_s { void (*dma_host_on)(ide_drive_t *drive); void (*dma_host_off)(ide_drive_t *drive); void (*dma_lost_irq)(ide_drive_t *drive); - int (*ide_dma_timeout)(ide_drive_t *drive); + void (*dma_timeout)(ide_drive_t *drive); void (*OUTB)(u8 addr, unsigned long port); void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); @@ -1305,7 +1305,7 @@ extern int ide_dma_setup(ide_drive_t *); extern void ide_dma_start(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *); extern void ide_dma_lost_irq(ide_drive_t *); -extern int __ide_dma_timeout(ide_drive_t *); +extern void ide_dma_timeout(ide_drive_t *); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ #else From ef29888ea8e1fdc499e995260195b66fc91d2728 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 9 Jul 2007 23:17:55 +0200 Subject: [PATCH 294/551] ide: use mutex instead of ide_cfg_sem semaphore in IDE driver The IDE driver uses a semaphore as mutex. Use the mutex API instead of the (binary) semaphore. Signed-off-by: Matthias Kaehlcke Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 6 +++--- drivers/ide/ide.c | 8 ++++---- include/linux/ide.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index f5ce22c38f82..648aabd121cd 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1025,7 +1025,7 @@ static int init_irq (ide_hwif_t *hwif) BUG_ON(irqs_disabled()); BUG_ON(hwif == NULL); - down(&ide_cfg_sem); + mutex_lock(&ide_cfg_mtx); hwif->hwgroup = NULL; #if MAX_HWIFS > 1 /* @@ -1154,7 +1154,7 @@ static int init_irq (ide_hwif_t *hwif) printk(" (%sed with %s)", hwif->sharing_irq ? "shar" : "serializ", match->name); printk("\n"); - up(&ide_cfg_sem); + mutex_unlock(&ide_cfg_mtx); return 0; out_unlink: spin_lock_irq(&ide_lock); @@ -1177,7 +1177,7 @@ out_unlink: } spin_unlock_irq(&ide_lock); out_up: - up(&ide_cfg_sem); + mutex_unlock(&ide_cfg_mtx); return 1; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 3717a329b43b..14ac7c2049e9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -169,7 +169,7 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, static int idebus_parameter; /* holds the "idebus=" parameter */ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ -DECLARE_MUTEX(ide_cfg_sem); +DEFINE_MUTEX(ide_cfg_mtx); __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); #ifdef CONFIG_IDEPCI_PCIBUS_ORDER @@ -564,7 +564,7 @@ void ide_unregister(unsigned int index) { ide_drive_t *drive; ide_hwif_t *hwif, *g; - static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ + static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */ ide_hwgroup_t *hwgroup; int irq_count = 0, unit; @@ -572,7 +572,7 @@ void ide_unregister(unsigned int index) BUG_ON(in_interrupt()); BUG_ON(irqs_disabled()); - down(&ide_cfg_sem); + mutex_lock(&ide_cfg_mtx); spin_lock_irq(&ide_lock); hwif = &ide_hwifs[index]; if (!hwif->present) @@ -679,7 +679,7 @@ void ide_unregister(unsigned int index) abort: spin_unlock_irq(&ide_lock); - up(&ide_cfg_sem); + mutex_unlock(&ide_cfg_mtx); } EXPORT_SYMBOL(ide_unregister); diff --git a/include/linux/ide.h b/include/linux/ide.h index 0bacf7f7c791..16ae68857f57 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1382,11 +1382,11 @@ extern const ide_pio_timings_t ide_pio_timings[6]; extern spinlock_t ide_lock; -extern struct semaphore ide_cfg_sem; +extern struct mutex ide_cfg_mtx; /* * Structure locking: * - * ide_cfg_sem and ide_lock together protect changes to + * ide_cfg_mtx and ide_lock together protect changes to * ide_hwif_t->{next,hwgroup} * ide_drive_t->next * From 2648e5d9a80d8a020feb343c52a8704e978e60c6 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:55 +0200 Subject: [PATCH 295/551] hpt366: simplify UltraDMA filtering (take 4) Simplify UltraDMA mode filtering in the driver: - make use of the newly introduced 'udma_mask' field of 'ide_pci_device_t' to set the correct hwif->ultra_mask, modifying init_setup_hpt366() to select the correct mask based on the chip revision; - replace 'max_mode' field of the 'struct hpt_info' with 'max_ultra' specifying the maximum UltraDMA mode allowed; - rewrite hpt3xx_udma_filter() to differ the filters based on the 'chip_type' field, and only use it for HPT366 and HPT370[A] where it's really necessary. Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt366.c | 154 +++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 72 deletions(-) diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 65018814ed73..ce363c923613 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.06 Jun 27, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.10 Jun 29, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -77,7 +77,7 @@ * since they may tamper with its fields * - prefix the driver startup messages with the real chip name * - claim the extra 240 bytes of I/O space for all chips - * - optimize the rate masking/filtering and the drive list lookup code + * - optimize the UltraDMA filtering and the drive list lookup code * - use pci_get_slot() to get to the function 1 of HPT36x/374 * - cache offset of the channel's misc. control registers (MCRs) being used * throughout the driver @@ -99,9 +99,9 @@ * stop duplicating it for each channel by storing the pointer in the pci_dev * structure: first, at the init_setup stage, point it to a static "template" * with only the chip type and its specific base DPLL frequency, the highest - * supported DMA mode, and the chip settings table pointer filled, then, at - * the init_chipset stage, allocate per-chip instance and fill it with the - * rest of the necessary information + * UltraDMA mode, and the chip settings table pointer filled, then, at the + * init_chipset stage, allocate per-chip instance and fill it with the rest + * of the necessary information * - get rid of the constant thresholds in the HPT37x PCI clock detection code, * switch to calculating PCI clock frequency based on the chip's base DPLL * frequency @@ -112,6 +112,7 @@ * also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips; * unify HPT36x/37x timing setup code and the speedproc handlers by joining * the register setting lists into the table indexed by the clock selected + * - set the correct hwif->ultra_mask for each individual chip * Sergei Shtylyov, or */ @@ -391,7 +392,7 @@ enum ata_clock { struct hpt_info { u8 chip_type; /* Chip type */ - u8 max_mode; /* Speeds allowed */ + u8 max_ultra; /* Max. UltraDMA mode allowed */ u8 dpll_clk; /* DPLL clock in MHz */ u8 pci_clk; /* PCI clock in MHz */ u32 **settings; /* Chipset settings table */ @@ -430,77 +431,77 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { static struct hpt_info hpt36x __devinitdata = { .chip_type = HPT36x, - .max_mode = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1, + .max_ultra = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2, .dpll_clk = 0, /* no DPLL */ .settings = hpt36x_settings }; static struct hpt_info hpt370 __devinitdata = { .chip_type = HPT370, - .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, + .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt370a __devinitdata = { .chip_type = HPT370A, - .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, + .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt374 __devinitdata = { .chip_type = HPT374, - .max_mode = 3, + .max_ultra = 5, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt372 __devinitdata = { .chip_type = HPT372, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 55, .settings = hpt37x_settings }; static struct hpt_info hpt372a __devinitdata = { .chip_type = HPT372A, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt302 __devinitdata = { .chip_type = HPT302, - .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt371 __devinitdata = { .chip_type = HPT371, - .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt372n __devinitdata = { .chip_type = HPT372N, - .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; static struct hpt_info hpt302n __devinitdata = { .chip_type = HPT302N, - .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT302_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; static struct hpt_info hpt371n __devinitdata = { .chip_type = HPT371N, - .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, + .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; @@ -523,53 +524,38 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list) static u8 hpt3xx_udma_filter(ide_drive_t *drive) { struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); - u8 chip_type = info->chip_type; - u8 mode = info->max_mode; u8 mask; - switch (mode) { - case 0x04: - mask = 0x7f; - break; - case 0x03: + switch (info->chip_type) { + case HPT370A: + if (!HPT370_ALLOW_ATA100_5 || + check_in_drive_list(drive, bad_ata100_5)) + return 0x1f; + else + return 0x3f; + case HPT370: + if (!HPT370_ALLOW_ATA100_5 || + check_in_drive_list(drive, bad_ata100_5)) + mask = 0x1f; + else mask = 0x3f; - if (chip_type >= HPT374) - break; - if (!check_in_drive_list(drive, bad_ata100_5)) - goto check_bad_ata33; - /* fall thru */ - case 0x02: + break; + case HPT36x: + if (!HPT366_ALLOW_ATA66_4 || + check_in_drive_list(drive, bad_ata66_4)) + mask = 0x0f; + else mask = 0x1f; - /* - * CHECK ME, Does this need to be changed to HPT374 ?? - */ - if (chip_type >= HPT370) - goto check_bad_ata33; - if (HPT366_ALLOW_ATA66_4 && - !check_in_drive_list(drive, bad_ata66_4)) - goto check_bad_ata33; - - mask = 0x0f; - if (HPT366_ALLOW_ATA66_3 && - !check_in_drive_list(drive, bad_ata66_3)) - goto check_bad_ata33; - /* fall thru */ - case 0x01: + if (!HPT366_ALLOW_ATA66_3 || + check_in_drive_list(drive, bad_ata66_3)) mask = 0x07; - - check_bad_ata33: - if (chip_type >= HPT370A) - break; - if (!check_in_drive_list(drive, bad_ata33)) - break; - /* fall thru */ - case 0x00: - default: - mask = 0x00; - break; + break; + default: + return 0x7f; } - return mask; + + return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask; } static u32 get_speed_setting(u8 speed, struct hpt_info *info) @@ -1150,7 +1136,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * Select 66 MHz DPLL clock only if UltraATA/133 mode is * supported/enabled, use 50 MHz DPLL clock otherwise... */ - if (info->max_mode == 0x04) { + if (info->max_ultra == 6) { dpll_clk = 66; clock = ATA_CLOCK_66MHZ; } else if (dpll_clk) { /* HPT36x chips don't have DPLL */ @@ -1243,7 +1229,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) struct pci_dev *dev = hwif->pci_dev; struct hpt_info *info = pci_get_drvdata(dev); int serialize = HPT_SERIALIZE_IO; - u8 scr1 = 0, ata66 = (hwif->channel) ? 0x01 : 0x02; + u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; u8 chip_type = info->chip_type; u8 new_mcr, old_mcr = 0; @@ -1256,7 +1242,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; hwif->busproc = &hpt3xx_busproc; - hwif->udma_filter = &hpt3xx_udma_filter; + + if (chip_type <= HPT370A) + hwif->udma_filter = &hpt3xx_udma_filter; /* * HPT3xxN chips have some complications: @@ -1305,7 +1293,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) return; } - hwif->ultra_mask = 0x7f; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; /* @@ -1503,9 +1491,35 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - if (rev > 6) + switch (rev) { + case 0: + case 1: + case 2: + /* + * HPT36x chips have one channel per function and have + * both channel enable bits located differently and visible + * to both functions -- really stupid design decision... :-( + * Bit 4 is for the primary channel, bit 5 for the secondary. + */ + d->channels = 1; + d->enablebits[0].mask = d->enablebits[0].val = 0x10; + + d->udma_mask = HPT366_ALLOW_ATA66_3 ? + (HPT366_ALLOW_ATA66_4 ? 0x1f : 0x0f) : 0x07; + break; + case 3: + case 4: + d->udma_mask = HPT370_ALLOW_ATA100_5 ? 0x3f : 0x1f; + break; + default: rev = 6; - + /* fall thru */ + case 5: + case 6: + d->udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f; + break; + } + d->name = chipset_names[rev]; pci_set_drvdata(dev, info[rev]); @@ -1513,15 +1527,6 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) if (rev > 2) goto init_single; - /* - * HPT36x chips have one channel per function and have - * both channel enable bits located differently and visible - * to both functions -- really stupid design decision... :-( - * Bit 4 is for the primary channel, bit 5 for the secondary. - */ - d->channels = 1; - d->enablebits[0].mask = d->enablebits[0].val = 0x10; - if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { u8 mcr1 = 0, pin1 = 0, pin2 = 0; int ret; @@ -1573,6 +1578,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f, .bootable = OFF_BOARD, .extra = 240 },{ /* 2 */ @@ -1584,6 +1590,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT302_ALLOW_ATA133_6 ? 0x7f : 0x3f, .bootable = OFF_BOARD, .extra = 240 },{ /* 3 */ @@ -1595,6 +1602,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT371_ALLOW_ATA133_6 ? 0x7f : 0x3f, .bootable = OFF_BOARD, .extra = 240 },{ /* 4 */ @@ -1606,6 +1614,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .channels = 2, /* 4 */ .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = 0x3f, .bootable = OFF_BOARD, .extra = 240 },{ /* 5 */ @@ -1617,6 +1626,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .channels = 2, /* 4 */ .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f, .bootable = OFF_BOARD, .extra = 240 } From 83a6d4ab3b09c0c1921b657bbaac5ada3c9c3623 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:55 +0200 Subject: [PATCH 296/551] cmd64x: init. code cleanup Fix two minor issues with PCI0646 chip reporting in the init_chipset() method: "IRQ workaround enabled" message printed out not only for revision 0x01 and "CMD646: chipset revision" printed twice (by IDE core and the driver itself). Also, remove empty/pointless switch cases for the chips other than PCI0646, duplicate write to the MRDMODE register when enabling interrupts and MEMORY READ LINE cycles, and needless/misplaced initialization of the timing registers in this method. Switch to reading only the PCI revision ID register itself, not the whole 32 bits at its address in init_chipset() and init_hwif() methods; in addition, get rid of the useless clearing of hwif->autodma and perform some cosmetic style changes in the latter method. Refactor ata66_cmd64x() by moving all the code into the 'switch' statement, renaming/adding variables, and fixing the coding style. While at it, finally get rid of the meaningless aliasing register #define's... Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cmd64x.c | 126 ++++++++++++++------------------------- 1 file changed, 45 insertions(+), 81 deletions(-) diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 7c57dc696f52..b0aa7d03b8a5 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cmd64x.c Version 1.47 Mar 19, 2007 + * linux/drivers/ide/pci/cmd64x.c Version 1.50 May 10, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Due to massive hardware bugs, UltraDMA is only supported @@ -52,9 +52,6 @@ #define ARTTIM23_DIS_RA2 0x04 #define ARTTIM23_DIS_RA3 0x08 #define ARTTIM23_INTR_CH1 0x10 -#define ARTTIM2 0x57 -#define ARTTIM3 0x57 -#define DRWTIM23 0x58 #define DRWTIM2 0x58 #define BRST 0x59 #define DRWTIM3 0x5b @@ -469,71 +466,43 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive) static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name) { - u32 class_rev = 0; u8 mrdmode = 0; - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; + if (dev->device == PCI_DEVICE_ID_CMD_646) { + u8 rev = 0; - switch(dev->device) { - case PCI_DEVICE_ID_CMD_643: - break; - case PCI_DEVICE_ID_CMD_646: - printk(KERN_INFO "%s: chipset revision 0x%02X, ", name, class_rev); - switch(class_rev) { - case 0x07: - case 0x05: - printk("UltraDMA Capable"); - break; - case 0x03: - printk("MultiWord DMA Force Limited"); - break; - case 0x01: - default: - printk("MultiWord DMA Limited, IRQ workaround enabled"); - break; - } - printk("\n"); - break; - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); + + switch (rev) { + case 0x07: + case 0x05: + printk("%s: UltraDMA capable", name); break; + case 0x03: default: + printk("%s: MultiWord DMA force limited", name); break; + case 0x01: + printk("%s: MultiWord DMA limited, " + "IRQ workaround enabled\n", name); + break; + } } /* Set a good latency timer and cache line size value. */ (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); /* FIXME: pci_set_master() to ensure a good latency timer value */ - /* Setup interrupts. */ - (void) pci_read_config_byte(dev, MRDMODE, &mrdmode); - mrdmode &= ~(0x30); - (void) pci_write_config_byte(dev, MRDMODE, mrdmode); - - /* Use MEMORY READ LINE for reads. - * NOTE: Although not mentioned in the PCI0646U specs, - * these bits are write only and won't be read - * back as set or not. The PCI0646U2 specs clarify - * this point. + /* + * Enable interrupts, select MEMORY READ LINE for reads. + * + * NOTE: although not mentioned in the PCI0646U specs, + * bits 0-1 are write only and won't be read back as + * set or not -- PCI0646U2 specs clarify this point. */ - (void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02); - - /* Set reasonable active/recovery/address-setup values. */ - (void) pci_write_config_byte(dev, ARTTIM0, 0x40); - (void) pci_write_config_byte(dev, DRWTIM0, 0x3f); - (void) pci_write_config_byte(dev, ARTTIM1, 0x40); - (void) pci_write_config_byte(dev, DRWTIM1, 0x3f); -#ifdef __i386__ - (void) pci_write_config_byte(dev, ARTTIM23, 0x1c); -#else - (void) pci_write_config_byte(dev, ARTTIM23, 0x5c); -#endif - (void) pci_write_config_byte(dev, DRWTIM23, 0x3f); - (void) pci_write_config_byte(dev, DRWTIM3, 0x3f); -#ifdef CONFIG_PPC - (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0); -#endif /* CONFIG_PPC */ + (void) pci_read_config_byte (dev, MRDMODE, &mrdmode); + mrdmode &= ~0x30; + (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02)); #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) @@ -550,27 +519,25 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) { - u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01; + struct pci_dev *dev = hwif->pci_dev; + u8 bmidecsr = 0, mask = hwif->channel ? 0x02 : 0x01; - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_CMD_643: - case PCI_DEVICE_ID_CMD_646: - return ata66; - default: - break; + switch (dev->device) { + case PCI_DEVICE_ID_CMD_648: + case PCI_DEVICE_ID_CMD_649: + pci_read_config_byte(dev, BMIDECSR, &bmidecsr); + return (bmidecsr & mask) ? 1 : 0; + default: + return 0; } - pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66); - return (ata66 & mask) ? 1 : 0; } static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - unsigned int class_rev; + u8 rev = 0; - hwif->autodma = 0; - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); hwif->tuneproc = &cmd64x_tune_drive; hwif->speedproc = &cmd64x_tune_chipset; @@ -580,8 +547,8 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) if (!hwif->dma_base) return; - hwif->atapi_dma = 1; - + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; hwif->ultra_mask = hwif->cds->udma_mask; /* @@ -596,16 +563,15 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) * * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. */ - if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5) + if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5) hwif->ultra_mask = 0x00; - hwif->mwdma_mask = 0x07; - hwif->ide_dma_check = &cmd64x_config_drive_for_dma; - if (!(hwif->udma_four)) + + if (!hwif->udma_four) hwif->udma_four = ata66_cmd64x(hwif); - switch(dev->device) { + switch (dev->device) { case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_649: alt_irq_bits: @@ -614,10 +580,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) break; case PCI_DEVICE_ID_CMD_646: hwif->chipset = ide_cmd646; - if (class_rev == 0x01) { + if (rev == 0x01) { hwif->ide_dma_end = &cmd646_1_ide_dma_end; break; - } else if (class_rev >= 0x03) + } else if (rev >= 0x03) goto alt_irq_bits; /* fall thru */ default: @@ -626,11 +592,9 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) break; } - if (!noautodma) hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; } static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) From b1d19db4e770a752ec032971388fa69a73c84919 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 297/551] aec62xx: rework init_setup_aec6x80() Rework init_setup_aec6x80() so that it won't rewrite the constant name strings anymore -- in order to do this: - in aec62xx_init_one(), pass a local copy of 'struct pci_device_id' down the call chain; - change the names for in aec62xx_chipsets[] to default to AEC-6280[R]; - override the 'name' field in init_setup_aec6x80() only if bit 4 of the DMA status register is set. While at it, also change the 'udma_mask' field for AEC-6x80R chips in this function and remove the code doing the same from the init_hwif() method... Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/aec62xx.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index bed32d0eaa37..7067df2590c3 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.21 Apr 21, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.22 Apr 23, 2007 * * Copyright (C) 1999-2002 Andre Hedrick * Copyright (C) 2007 MontaVista Software, Inc. @@ -239,14 +239,6 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) } hwif->ultra_mask = hwif->cds->udma_mask; - - /* atp865 and atp865r */ - if (hwif->ultra_mask == 0x3f) { - /* check bit 0x10 of DMA status register */ - if (inb(pci_resource_start(dev, 4) + 2) & 0x10) - hwif->ultra_mask = 0x7f; /* udma0-6 */ - } - hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; @@ -287,16 +279,12 @@ static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) { - unsigned long bar4reg = pci_resource_start(dev, 4); + unsigned long dma_base = pci_resource_start(dev, 4); - if (inb(bar4reg+2) & 0x10) { - strcpy(d->name, "AEC6880"); - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) - strcpy(d->name, "AEC6880R"); - } else { - strcpy(d->name, "AEC6280"); - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) - strcpy(d->name, "AEC6280R"); + if (inb(dma_base + 2) & 0x10) { + d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ? + "AEC6880R" : "AEC6880"; + d->udma_mask = 0x7f; /* udma0-6 */ } return ide_setup_pci_device(dev, d); @@ -336,7 +324,7 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .bootable = NEVER_BOARD, .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ - .name = "AEC6X80", + .name = "AEC6280", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, @@ -346,7 +334,7 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .udma_mask = 0x3f, /* udma0-5 */ },{ /* 4 */ - .name = "AEC6X80R", + .name = "AEC6280R", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, @@ -366,13 +354,16 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { * * Called when the PCI registration layer (or the IDE initialization) * finds a device matching our IDE device tables. + * + * NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R] + * chips, pass a local copy of 'struct pci_device_id' down the call chain. */ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data]; + ide_pci_device_t d = aec62xx_chipsets[id->driver_data]; - return d->init_setup(dev, d); + return d.init_setup(dev, &d); } static struct pci_device_id aec62xx_pci_tbl[] = { From 1b9da32a2855afa3c5f27690e03a33dc97410c42 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 298/551] aec62xx: remove init_dma() method (take 2) Get rid of the init_dma() method (which had no particular reason to exist) by folding it into the init_hwif() method. While at it, also perform some cleanup in the latter method: - get rid of the useless clearing of hwif->autodma; - fold the serialization code into one 'if' statement; - fold setting the drives' 'autotune' and 'autodma' fields into the single statements... Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/aec62xx.c | 51 ++++++++++++--------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 7067df2590c3..99184be6a98c 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.22 Apr 23, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.23 May 23, 2007 * * Copyright (C) 1999-2002 Andre Hedrick * Copyright (C) 2007 MontaVista Software, Inc. @@ -220,21 +220,18 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *dev = hwif->pci_dev; + u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f; + unsigned long flags; - hwif->autodma = 0; hwif->tuneproc = &aec62xx_tune_drive; hwif->speedproc = &aec62xx_tune_chipset; - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) - hwif->serialized = hwif->channel; - - if (hwif->mate) - hwif->mate->serialized = hwif->serialized; + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF && hwif->mate) + hwif->mate->serialized = hwif->serialized = 1; if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; return; } @@ -244,32 +241,21 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; hwif->dma_lost_irq = &aec62xx_dma_lost_irq; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase) -{ - struct pci_dev *dev = hwif->pci_dev; - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { - u8 reg54h = 0; - unsigned long flags; - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_byte(dev, 0x54, ®54h); - pci_write_config_byte(dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); + pci_read_config_byte (dev, 0x54, ®54); + pci_write_config_byte(dev, 0x54, (reg54 & ~mask)); spin_unlock_irqrestore(&ide_lock, flags); - } else { - u8 ata66 = 0; + } else if (!hwif->udma_four) { + u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01; + pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); - if (!(hwif->udma_four)) - hwif->udma_four = (ata66&(hwif->channel?0x02:0x01))?0:1; + hwif->udma_four = (ata66 & mask) ? 0 : 1; } - ide_setup_dma(hwif, dmabase, 8); + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; } static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) @@ -296,7 +282,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, @@ -307,7 +292,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, .channels = 2, .autodma = NOAUTODMA, .bootable = OFF_BOARD, @@ -317,7 +301,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, @@ -328,7 +311,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, @@ -338,7 +320,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, .channels = 2, .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, From f9383c4269d264c3cf563bd2de365891f6592ebd Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 299/551] ide: use mutex instead of ide_setting_sem semaphore in IDE driver The IDE driver uses a semaphore as mutex. Use the mutex API instead of the (binary) semaphore. Signed-off-by: Matthias Kaehlcke Signed-off-by: Bartlomiej Zolnierkiewicz -- --- drivers/ide/ide-disk.c | 8 ++++---- drivers/ide/ide-proc.c | 34 +++++++++++++++++----------------- drivers/ide/ide.c | 12 ++++++------ include/linux/ide.h | 3 ++- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index dc2175c81f5e..b1304a7f3e0a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1190,11 +1190,11 @@ static int idedisk_ioctl(struct inode *inode, struct file *file, return generic_ide_ioctl(drive, file, bdev, cmd, arg); read_val: - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); spin_lock_irqsave(&ide_lock, flags); err = *val; spin_unlock_irqrestore(&ide_lock, flags); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); return err >= 0 ? put_user(err, (long __user *)arg) : err; set_val: @@ -1204,9 +1204,9 @@ set_val: if (!capable(CAP_SYS_ADMIN)) err = -EACCES; else { - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); err = setfunc(drive, arg); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); } } return err; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index ea94c9aa1220..fc1d8ae6a803 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -156,7 +156,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d { ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); while ((*p) && strcmp((*p)->name, name) < 0) p = &((*p)->next); if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL) @@ -177,10 +177,10 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d if (auto_remove) setting->auto_remove = 1; *p = setting; - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); return 0; abort: - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); kfree(setting); return -1; } @@ -224,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name) * * Automatically remove all the driver specific settings for this * drive. This function may not be called from IRQ context. The - * caller must hold ide_setting_sem. + * caller must hold ide_setting_mtx. */ static void auto_remove_settings (ide_drive_t *drive) @@ -269,7 +269,7 @@ static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name) * @setting: drive setting * * Read a drive setting and return the value. The caller - * must hold the ide_setting_sem when making this call. + * must hold the ide_setting_mtx when making this call. * * BUGS: the data return and error are the same return value * so an error -EINVAL and true return of the same value cannot @@ -306,7 +306,7 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting) * @val: value * * Write a drive setting if it is possible. The caller - * must hold the ide_setting_sem when making this call. + * must hold the ide_setting_mtx when making this call. * * BUGS: the data return and error are the same return value * so an error -EINVAL and true return of the same value cannot @@ -367,7 +367,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) * @drive: drive being configured * * Add the generic parts of the system settings to the /proc files. - * The caller must not be holding the ide_setting_sem. + * The caller must not be holding the ide_setting_mtx. */ void ide_add_generic_settings (ide_drive_t *drive) @@ -408,7 +408,7 @@ static int proc_ide_read_settings proc_ide_settings_warn(); - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); while(setting) { @@ -428,7 +428,7 @@ static int proc_ide_read_settings setting = setting->next; } len = out - page; - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -508,16 +508,16 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer, ++p; } - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); setting = ide_find_setting_by_name(drive, name); if (!setting) { - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); goto parse_error; } if (for_real) ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); } } while (!for_real++); free_page((unsigned long)buf); @@ -705,7 +705,7 @@ EXPORT_SYMBOL(ide_proc_register_driver); * Clean up the driver specific /proc files and IDE settings * for a given drive. * - * Takes ide_setting_sem and ide_lock. + * Takes ide_setting_mtx and ide_lock. * Caller must hold none of the locks. */ @@ -715,10 +715,10 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) ide_remove_proc_entries(drive->proc, driver->proc); - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); spin_lock_irqsave(&ide_lock, flags); /* - * ide_setting_sem protects the settings list + * ide_setting_mtx protects the settings list * ide_lock protects the use of settings * * so we need to hold both, ide_settings_sem because we want to @@ -726,11 +726,11 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) * a setting out that is being used. * * OTOH both ide_{read,write}_setting are only ever used under - * ide_setting_sem. + * ide_setting_mtx. */ auto_remove_settings(drive); spin_unlock_irqrestore(&ide_lock, flags); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); } EXPORT_SYMBOL(ide_proc_unregister_driver); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 14ac7c2049e9..574414689253 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -817,9 +817,9 @@ EXPORT_SYMBOL(ide_register_hw); * Locks for IDE setting functionality */ -DECLARE_MUTEX(ide_setting_sem); +DEFINE_MUTEX(ide_setting_mtx); -EXPORT_SYMBOL_GPL(ide_setting_sem); +EXPORT_SYMBOL_GPL(ide_setting_mtx); /** * ide_spin_wait_hwgroup - wait for group @@ -1192,11 +1192,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device } read_val: - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); spin_lock_irqsave(&ide_lock, flags); err = *val; spin_unlock_irqrestore(&ide_lock, flags); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); return err >= 0 ? put_user(err, (long __user *)arg) : err; set_val: @@ -1206,9 +1206,9 @@ set_val: if (!capable(CAP_SYS_ADMIN)) err = -EACCES; else { - down(&ide_setting_sem); + mutex_lock(&ide_setting_mtx); err = setfunc(drive, arg); - up(&ide_setting_sem); + mutex_unlock(&ide_setting_mtx); } } return err; diff --git a/include/linux/ide.h b/include/linux/ide.h index 16ae68857f57..b6546f442fa4 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -25,6 +25,7 @@ #include #include #include +#include /****************************************************************************** * IDE driver configuration options (play with these as desired): @@ -863,7 +864,7 @@ typedef struct hwgroup_s { typedef struct ide_driver_s ide_driver_t; -extern struct semaphore ide_setting_sem; +extern struct mutex ide_setting_mtx; int set_io_32bit(ide_drive_t *, int); int set_pio_mode(ide_drive_t *, int); From 6d78013bfc20b8579827fc8f214c6f85d469c051 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 300/551] aec62xx: kill speedproc() method wrapper (take 2) There's no reason to have the speedproc() method wrapper for the two quite different chip families, so just get rid of it. Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/aec62xx.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 99184be6a98c..794ac40ec90f 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.23 May 23, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.24 May 24, 2007 * * Copyright (C) 1999-2002 Andre Hedrick * Copyright (C) 2007 MontaVista Software, Inc. @@ -140,25 +140,10 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) return(ide_config_drive_speed(drive, speed)); } -static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed) -{ - switch (HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP865: - case PCI_DEVICE_ID_ARTOP_ATP865R: - case PCI_DEVICE_ID_ARTOP_ATP860: - case PCI_DEVICE_ID_ARTOP_ATP860R: - return ((int) aec6260_tune_chipset(drive, speed)); - case PCI_DEVICE_ID_ARTOP_ATP850UF: - return ((int) aec6210_tune_chipset(drive, speed)); - default: - return -1; - } -} - static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) aec62xx_tune_chipset(drive, pio + XFER_PIO_0); + (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0); } static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) @@ -225,10 +210,13 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) unsigned long flags; hwif->tuneproc = &aec62xx_tune_drive; - hwif->speedproc = &aec62xx_tune_chipset; - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF && hwif->mate) - hwif->mate->serialized = hwif->serialized = 1; + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { + if(hwif->mate) + hwif->mate->serialized = hwif->serialized = 1; + hwif->speedproc = &aec6210_tune_chipset; + } else + hwif->speedproc = &aec6260_tune_chipset; if (!hwif->dma_base) { hwif->drives[0].autotune = hwif->drives[1].autotune = 1; From c2d3ce8c39cb17dfc8d0426a98bd79f5d7b21e36 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 301/551] ide_in_drive_list(): accept NULL as the wildcard for firmware revision Earlier, the matching of (model,rev) in ide-dma black/white list handling was to consider "ALL" in the table to match any revision. This makes NULL to be also an accepted wildcard, and changes the entries of tables in ide-dma.c to use NULL. The code still accepts "ALL" as the wildcard, in order to keep any out-of-tree ide driver that feeds its own table that uses "ALL" as the wildcard to ide_in_drive_list() function from breaking. Signed-off-by: Junio C Hamano Cc: Alan Cox Cc: Dave Jones Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 67 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index ca55bfa4ac74..e80f8e1a0b93 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -91,45 +91,45 @@ static const struct drive_list_entry drive_whitelist [] = { - { "Micropolis 2112A" , "ALL" }, - { "CONNER CTMA 4000" , "ALL" }, - { "CONNER CTT8000-A" , "ALL" }, - { "ST34342A" , "ALL" }, + { "Micropolis 2112A" , NULL }, + { "CONNER CTMA 4000" , NULL }, + { "CONNER CTT8000-A" , NULL }, + { "ST34342A" , NULL }, { NULL , NULL } }; static const struct drive_list_entry drive_blacklist [] = { - { "WDC AC11000H" , "ALL" }, - { "WDC AC22100H" , "ALL" }, - { "WDC AC32500H" , "ALL" }, - { "WDC AC33100H" , "ALL" }, - { "WDC AC31600H" , "ALL" }, + { "WDC AC11000H" , NULL }, + { "WDC AC22100H" , NULL }, + { "WDC AC32500H" , NULL }, + { "WDC AC33100H" , NULL }, + { "WDC AC31600H" , NULL }, { "WDC AC32100H" , "24.09P07" }, { "WDC AC23200L" , "21.10N21" }, - { "Compaq CRD-8241B" , "ALL" }, - { "CRD-8400B" , "ALL" }, - { "CRD-8480B", "ALL" }, - { "CRD-8482B", "ALL" }, - { "CRD-84" , "ALL" }, - { "SanDisk SDP3B" , "ALL" }, - { "SanDisk SDP3B-64" , "ALL" }, - { "SANYO CD-ROM CRD" , "ALL" }, - { "HITACHI CDR-8" , "ALL" }, - { "HITACHI CDR-8335" , "ALL" }, - { "HITACHI CDR-8435" , "ALL" }, - { "Toshiba CD-ROM XM-6202B" , "ALL" }, - { "TOSHIBA CD-ROM XM-1702BC", "ALL" }, - { "CD-532E-A" , "ALL" }, - { "E-IDE CD-ROM CR-840", "ALL" }, - { "CD-ROM Drive/F5A", "ALL" }, - { "WPI CDD-820", "ALL" }, - { "SAMSUNG CD-ROM SC-148C", "ALL" }, - { "SAMSUNG CD-ROM SC", "ALL" }, - { "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" }, - { "_NEC DV5800A", "ALL" }, + { "Compaq CRD-8241B" , NULL }, + { "CRD-8400B" , NULL }, + { "CRD-8480B", NULL }, + { "CRD-8482B", NULL }, + { "CRD-84" , NULL }, + { "SanDisk SDP3B" , NULL }, + { "SanDisk SDP3B-64" , NULL }, + { "SANYO CD-ROM CRD" , NULL }, + { "HITACHI CDR-8" , NULL }, + { "HITACHI CDR-8335" , NULL }, + { "HITACHI CDR-8435" , NULL }, + { "Toshiba CD-ROM XM-6202B" , NULL }, + { "TOSHIBA CD-ROM XM-1702BC", NULL }, + { "CD-532E-A" , NULL }, + { "E-IDE CD-ROM CR-840", NULL }, + { "CD-ROM Drive/F5A", NULL }, + { "WPI CDD-820", NULL }, + { "SAMSUNG CD-ROM SC-148C", NULL }, + { "SAMSUNG CD-ROM SC", NULL }, + { "ATAPI CD-ROM DRIVE 40X MAXIMUM", NULL }, + { "_NEC DV5800A", NULL }, { "SAMSUNG CD-ROM SN-124", "N001" }, - { "Seagate STT20000A", "ALL" }, + { "Seagate STT20000A", NULL }, { NULL , NULL } }; @@ -147,8 +147,9 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv { for ( ; drive_table->id_model ; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && - ((strstr(id->fw_rev, drive_table->id_firmware)) || - (!strcmp(drive_table->id_firmware, "ALL")))) + (!drive_table->id_firmware || + !strcmp(drive_table->id_firmware, "ALL") || /* to be removed later */ + strstr(id->fw_rev, drive_table->id_firmware))) return 1; return 0; } From bb53cfe9fa21c4f875d5c9470865fbbd0657804e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 9 Jul 2007 23:17:56 +0200 Subject: [PATCH 302/551] mips au1xxx_ide.h: use NULL as firmware-revision wildcard This updates the DMA whitelist in MIPS specific au1xxx ide driver to use NULL instead of "ALL" as the wildcard. Signed-off-by: Junio C Hamano Cc: Alan Cox Cc: Dave Jones Signed-off-by: Bartlomiej Zolnierkiewicz --- include/asm-mips/mach-au1x00/au1xxx_ide.h | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h index 8fcae21adbd5..4663e8b415c9 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -88,26 +88,26 @@ static const struct drive_list_entry dma_white_list [] = { /* * Hitachi */ - { "HITACHI_DK14FA-20" , "ALL" }, - { "HTS726060M9AT00" , "ALL" }, + { "HITACHI_DK14FA-20" , NULL }, + { "HTS726060M9AT00" , NULL }, /* * Maxtor */ - { "Maxtor 6E040L0" , "ALL" }, - { "Maxtor 6Y080P0" , "ALL" }, - { "Maxtor 6Y160P0" , "ALL" }, + { "Maxtor 6E040L0" , NULL }, + { "Maxtor 6Y080P0" , NULL }, + { "Maxtor 6Y160P0" , NULL }, /* * Seagate */ - { "ST3120026A" , "ALL" }, - { "ST320014A" , "ALL" }, - { "ST94011A" , "ALL" }, - { "ST340016A" , "ALL" }, + { "ST3120026A" , NULL }, + { "ST320014A" , NULL }, + { "ST94011A" , NULL }, + { "ST340016A" , NULL }, /* * Western Digital */ - { "WDC WD400UE-00HCT0" , "ALL" }, - { "WDC WD400JB-00JJC0" , "ALL" }, + { "WDC WD400UE-00HCT0" , NULL }, + { "WDC WD400JB-00JJC0" , NULL }, { NULL , NULL } }; @@ -116,9 +116,9 @@ static const struct drive_list_entry dma_black_list [] = { /* * Western Digital */ - { "WDC WD100EB-00CGH0" , "ALL" }, - { "WDC WD200BB-00AUA1" , "ALL" }, - { "WDC AC24300L" , "ALL" }, + { "WDC WD100EB-00CGH0" , NULL }, + { "WDC WD200BB-00AUA1" , NULL }, + { "WDC AC24300L" , NULL }, { NULL , NULL } }; #endif From f3577db0c294ab4ce8460a8003312474b509e95f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 303/551] ide_in_drive_list(): "ALL" is not a wildcard anymore This removes the support to treat "ALL" as a wildcard for firmware revision. This is made a separate patch, as it will break out-of-tree ide drivers that feed its own table that uses "ALL" as the wildcard to ide_in_drive_list(). Signed-off-by: Junio C Hamano Cc: Alan Cox Cc: Dave Jones Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index e80f8e1a0b93..85db8e85443a 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -148,7 +148,6 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv for ( ; drive_table->id_model ; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && (!drive_table->id_firmware || - !strcmp(drive_table->id_firmware, "ALL") || /* to be removed later */ strstr(id->fw_rev, drive_table->id_firmware))) return 1; return 0; From 74c8f97a6c2d12fb144ad34076e969e8a01dc4b3 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 304/551] ide-cd: replace C code with call to ARRAY_SIZE() macro Delete the unnecessary macro ARY_LEN and use ARRAY_SIZE directly. Signed-off-by: Robert P. J. Day Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 6 +++--- drivers/ide/ide-cd.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 252ab8295edf..1486eb212ccc 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -481,7 +481,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, else printk(" Unknown Error Type: "); - if (sense->sense_key < ARY_LEN(sense_key_texts)) + if (sense->sense_key < ARRAY_SIZE(sense_key_texts)) s = sense_key_texts[sense->sense_key]; printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key); @@ -491,7 +491,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, sense->ascq); s = buf; } else { - int lo = 0, mid, hi = ARY_LEN(sense_data_texts); + int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts); unsigned long key = (sense->sense_key << 16); key |= (sense->asc << 8); if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd)) @@ -524,7 +524,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, if (failed_command != NULL) { - int lo=0, mid, hi= ARY_LEN (packet_command_texts); + int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts); s = NULL; while (hi > lo) { diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index ad1f2ed14a37..228b29c5d2e4 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -498,8 +498,6 @@ struct cdrom_info { * Descriptions of ATAPI error codes. */ -#define ARY_LEN(a) ((sizeof(a) / sizeof(a[0]))) - /* This stuff should be in cdrom.h, since it is now generic... */ /* ATAPI sense keys (from table 140 of ATAPI 2.6) */ From e71bc140c013dfaff0369ebcc9802a798e358473 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 305/551] ide: remove references to the non-existent CONFIG_SCSI_EATA_DMA Signed-off-by: Robert P. J. Day Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 648aabd121cd..cc5801399467 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -144,7 +144,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) local_irq_enable(); ide_fix_driveid(id); -#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) +#if defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) /* * EATA SCSI controllers do a hardware ATA emulation: * Ignore them if there is a driver for them available. @@ -154,7 +154,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); goto err_misc; } -#endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */ +#endif /* CONFIG_SCSI_EATA || CONFIG_SCSI_EATA_PIO */ /* * WIN_IDENTIFY returns little-endian info, From f50f9d8867b95925078ba0fa450e3a5736629d28 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 306/551] ide: remove content related to dead CONFIG_BLK_DEV_MAC_MEDIABAY config variable Signed-off-by: Robert P. J. Day Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/macide.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index c211fc78345d..b557c45a5a9d 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -77,15 +77,6 @@ int macide_ack_intr(ide_hwif_t* hwif) return 0; } -#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY -static void macide_mediabay_interrupt(int irq, void *dev_id) -{ - int state = baboon->mb_status & 0x04; - - printk(KERN_INFO "macide: media bay %s detected\n", state? "removal":"insertion"); -} -#endif - /* * Probe for a Macintosh IDE interface */ @@ -128,11 +119,6 @@ void macide_init(void) ide_drive_t *drive = &ide_hwifs[index].drives[0]; drive->capacity64 = drive->cyl*drive->head*drive->sect; -#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY - request_irq(IRQ_BABOON_2, macide_mediabay_interrupt, - IRQ_FLG_FAST, "mediabay", - macide_mediabay_interrupt); -#endif } break; From ecea57309e826c8aed020e4dae92b368f2eda2a5 Mon Sep 17 00:00:00 2001 From: Andi Drebes Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 307/551] drivers/ide/legacy/hd.c: Array size calculation using sizeof replaced with ARRAY_SIZE This patch replaces an array size calculation in drivers/ide/legacy/hd.c that was done using sizeof with the ARRAY_SIZE macro. Tested by compilation on an i386 box using "allyesconfig". Diffed against Linus' git-tree. Signed-off-by: Andi Drebes Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/hd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 45ed03591cd8..661c12f6dda6 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -130,7 +130,7 @@ struct hd_i_struct { #ifdef HD_TYPE static struct hd_i_struct hd_info[] = { HD_TYPE }; -static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct))); +static int NR_HD = ARRAY_SIZE(hd_info); #else static struct hd_i_struct hd_info[MAX_HD]; static int NR_HD; From 15a4f943e729d8ba215ee551df6d7988ba14ac00 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 308/551] ide: fix pre-EIDE SWDMA support If the word 62 is not defined use the word 52 to get SWDMA mask in ide_get_mode_mask(). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 85db8e85443a..e8c6e1ed497a 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -702,8 +702,22 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) mask = id->dma_mword & hwif->mwdma_mask; break; case XFER_SW_DMA_0: - if (id->field_valid & 2) + if (id->field_valid & 2) { mask = id->dma_1word & hwif->swdma_mask; + } else if (id->tDMA) { + /* + * ide_fix_driveid() doesn't convert ->tDMA to the + * CPU endianness so we need to do it here + */ + u8 mode = le16_to_cpu(id->tDMA); + + /* + * if the mode is valid convert it to the mask + * (the maximum allowed mode is XFER_SW_DMA_2) + */ + if (mode <= 2) + mask = ((2 << mode) - 1) & hwif->swdma_mask; + } break; default: BUG(); From 75b1d97535327d0428c6bffd9d5407e65546fd5d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:57 +0200 Subject: [PATCH 309/551] ide: convert ide_find_best_mode() users to use ide_max_dma_mode() ide-timing.h: * remove handling of DMA modes from ide_find_best_mode() and rename it to ide_find_best_pio_mode() * drop no longer needed "map" argument from ide_find_best_pio_mode() and delete needless ->id check * remove no longer needed XFER_SWDMA and XFER_UDMA* defines au1xxx-ide.c: * use ide_max_dma_mode() instead of ide_find_best_mode() * remove needless CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef amd74xx.c: * store UDMA masks in amd_ide_chip[] and while at it make "base" field to be u8 instead of unsigned long * convert the driver to use UDMA masks from amd_ide_chip[] * use ide_max_dma_mode() and ide_find_best_pio_mode() instead of ide_find_best_mode() * delete stale comment from amd74xx_ide_dma_check() * remove no longer needed AMD_UDMA* defines via82cxxx.c: * remove unused DISPLAY_VIA_TIMINGS define * store UDMA masks in via_isa_bridges[] and while at it make "flags" field to be u8 instead of u16 * convert the driver to use UDMA masks from via_isa_bridges[] * use ide_max_dma_mode() and ide_find_best_pio_mode() instead of ide_find_best_mode() * remove no longer needed VIA_UDMA* defines pmac.c: * use ide_max_dma_mode() instead of ide_find_best_mode() There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Sergei Shtylyov --- drivers/ide/ide-timing.h | 56 +-------------- drivers/ide/mips/au1xxx-ide.c | 7 +- drivers/ide/pci/amd74xx.c | 118 ++++++++++++++---------------- drivers/ide/pci/via82cxxx.c | 132 ++++++++++++++++------------------ drivers/ide/ppc/pmac.c | 25 ++----- 5 files changed, 123 insertions(+), 215 deletions(-) diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index c0864b1e9228..e6cb8593b5ba 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -102,66 +102,16 @@ static struct ide_timing ide_timing[] = { #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) #define XFER_MODE 0xf0 -#define XFER_UDMA_133 0x48 -#define XFER_UDMA_100 0x44 -#define XFER_UDMA_66 0x42 -#define XFER_UDMA 0x40 #define XFER_MWDMA 0x20 -#define XFER_SWDMA 0x10 #define XFER_EPIO 0x01 #define XFER_PIO 0x00 -static short ide_find_best_mode(ide_drive_t *drive, int map) +static short ide_find_best_pio_mode(ide_drive_t *drive) { struct hd_driveid *id = drive->id; short best = 0; - if (!id) - return XFER_PIO_SLOW; - - if ((map & XFER_UDMA) && (id->field_valid & 4)) { /* Want UDMA and UDMA bitmap valid */ - - if ((map & XFER_UDMA_133) == XFER_UDMA_133) - if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best; - - if ((map & XFER_UDMA_100) == XFER_UDMA_100) - if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best; - - if ((map & XFER_UDMA_66) == XFER_UDMA_66) - if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 : - (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best; - - if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 : - (id->dma_ultra & 0x0002) ? XFER_UDMA_1 : - (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : 0)) return best; - } - - if ((map & XFER_MWDMA) && (id->field_valid & 2)) { /* Want MWDMA and drive has EIDE fields */ - - if ((best = (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 : - (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 : - (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : 0)) return best; - } - - if (map & XFER_SWDMA) { /* Want SWDMA */ - - if (id->field_valid & 2) { /* EIDE SWDMA */ - - if ((best = (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 : - (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 : - (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0)) return best; - } - - if (id->capability & 1) { /* Pre-EIDE style SWDMA */ - - if ((best = (id->tDMA == 2) ? XFER_SW_DMA_2 : - (id->tDMA == 1) ? XFER_SW_DMA_1 : - (id->tDMA == 0) ? XFER_SW_DMA_0 : 0)) return best; - } - } - - - if ((map & XFER_EPIO) && (id->field_valid & 2)) { /* EIDE PIO modes */ + if (id->field_valid & 2) { /* EIDE PIO modes */ if ((best = (drive->id->eide_pio_modes & 4) ? XFER_PIO_5 : (drive->id->eide_pio_modes & 2) ? XFER_PIO_4 : @@ -262,7 +212,7 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing */ if ((speed & XFER_MODE) != XFER_PIO) { - ide_timing_compute(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO), &p, T, UT); + ide_timing_compute(drive, ide_find_best_pio_mode(drive), &p, T, UT); ide_timing_merge(&p, t, t, IDE_TIMING_ALL); } diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 405903c42ba1..2e7013a2a7f6 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -381,9 +381,7 @@ static int auide_dma_setup(ide_drive_t *drive) static int auide_dma_check(ide_drive_t *drive) { - u8 speed; - -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + u8 speed = ide_max_dma_mode(drive); if( dbdma_init_done == 0 ){ auide_hwif.white_list = ide_in_drive_list(drive->id, @@ -394,7 +392,6 @@ static int auide_dma_check(ide_drive_t *drive) auide_ddma_init(&auide_hwif); dbdma_init_done = 1; } -#endif /* Is the drive in our DMA black list? */ @@ -409,8 +406,6 @@ static int auide_dma_check(ide_drive_t *drive) else drive->using_dma = 1; - speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA); - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) return 0; diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index a2be65fcf89c..a7443f15b27a 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -1,10 +1,11 @@ /* - * Version 2.16 + * Version 2.20 * * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 * IDE driver for Linux. * * Copyright (c) 2000-2002 Vojtech Pavlik + * Copyright (c) 2007 Bartlomiej Zolnierkiewicz * * Based on the work of: * Andre Hedrick @@ -37,11 +38,6 @@ #define AMD_ADDRESS_SETUP (0x0c + amd_config->base) #define AMD_UDMA_TIMING (0x10 + amd_config->base) -#define AMD_UDMA 0x07 -#define AMD_UDMA_33 0x01 -#define AMD_UDMA_66 0x02 -#define AMD_UDMA_100 0x03 -#define AMD_UDMA_133 0x04 #define AMD_CHECK_SWDMA 0x08 #define AMD_BAD_SWDMA 0x10 #define AMD_BAD_FIFO 0x20 @@ -53,32 +49,33 @@ static struct amd_ide_chip { unsigned short id; - unsigned long base; - unsigned char flags; + u8 base; + u8 udma_mask; + u8 flags; } amd_ide_chips[] = { - { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, - { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, - { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, - { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, AMD_UDMA_100 }, - { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, AMD_UDMA_100 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, + { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, ATA_UDMA2, AMD_BAD_SWDMA }, + { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, ATA_UDMA4, AMD_CHECK_SWDMA }, + { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, ATA_UDMA5, AMD_BAD_FIFO }, + { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, ATA_UDMA5, }, + { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, ATA_UDMA6, AMD_CHECK_SERENADE }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, ATA_UDMA5, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, ATA_UDMA6, }, + { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, ATA_UDMA5, }, { 0 } }; @@ -87,7 +84,7 @@ static ide_pci_device_t *amd_chipset; static unsigned int amd_80w; static unsigned int amd_clock; -static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; +static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" }; static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; /* @@ -128,7 +125,7 @@ static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count) pci_read_config_byte(dev, PCI_REVISION_ID, &t); amd_print("Revision: IDE %#x", t); - amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]); + amd_print("Highest DMA rate: UDMA%s", amd_dma[fls(amd_config->udma_mask) - 1]); amd_print("BM-DMA base: %#lx", amd_base); amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10); @@ -221,12 +218,12 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn), ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); - switch (amd_config->flags & AMD_UDMA) { - case AMD_UDMA_33: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case AMD_UDMA_66: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; - case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; - case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; - default: return; + switch (amd_config->udma_mask) { + case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; + case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; + case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; + case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; + default: return; } pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t); @@ -248,7 +245,7 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed) ide_config_drive_speed(drive, speed); T = 1000000000 / amd_clock; - UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); + UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2); ide_timing_compute(drive, speed, &t, T, UT); @@ -277,29 +274,19 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed) static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) { if (pio == 255) { - amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); + amd_set_drive(drive, ide_find_best_pio_mode(drive)); return; } amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); } -/* - * amd74xx_dmaproc() is a callback from upper layers that can do - * a lot, but we use it for DMA/PIO tuning only, delegating everything - * else to the default ide_dmaproc(). - */ - static int amd74xx_ide_dma_check(ide_drive_t *drive) { - int w80 = HWIF(drive)->udma_four; + u8 speed = ide_max_dma_mode(drive); - u8 speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | - ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0)); + if (speed == 0) + speed = ide_find_best_pio_mode(drive); amd_set_drive(drive, speed); @@ -334,10 +321,10 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch * Check 80-wire cable presence. */ - switch (amd_config->flags & AMD_UDMA) { + switch (amd_config->udma_mask) { - case AMD_UDMA_133: - case AMD_UDMA_100: + case ATA_UDMA6: + case ATA_UDMA5: pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); @@ -349,7 +336,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch } break; - case AMD_UDMA_66: + case ATA_UDMA4: /* no host side cable detection */ amd_80w = 0x03; break; @@ -370,7 +357,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch if ((amd_config->flags & AMD_CHECK_SERENADE) && dev->subsystem_vendor == PCI_VENDOR_ID_AMD && dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) - amd_config->flags = AMD_UDMA_100; + amd_config->udma_mask = ATA_UDMA5; /* * Determine the system bus clock. @@ -395,8 +382,9 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch */ pci_read_config_byte(dev, PCI_REVISION_ID, &t); - printk(KERN_INFO "%s: %s (rev %02x) %s controller\n", - amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]); + printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n", + amd_chipset->name, pci_name(dev), t, + amd_dma[fls(amd_config->udma_mask) - 1]); /* * Register /proc/ide/amd74xx entry @@ -437,9 +425,11 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) return; hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; + + hwif->ultra_mask = amd_config->udma_mask; + hwif->mwdma_mask = 0x07; + if ((amd_config->flags & AMD_BAD_SWDMA) == 0) + hwif->swdma_mask = 0x07; if (!hwif->udma_four) hwif->udma_four = (amd_80w >> hwif->channel) & 1; diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index a508550c4095..49bd1c645fb2 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -1,6 +1,6 @@ /* * - * Version 3.38 + * Version 3.40 * * VIA IDE driver for Linux. Supported southbridges: * @@ -9,6 +9,7 @@ * vt8235, vt8237, vt8237a * * Copyright (c) 2000-2002 Vojtech Pavlik + * Copyright (c) 2007 Bartlomiej Zolnierkiewicz * * Based on the work of: * Michel Aubry @@ -41,8 +42,6 @@ #include "ide-timing.h" -#define DISPLAY_VIA_TIMINGS - #define VIA_IDE_ENABLE 0x40 #define VIA_IDE_CONFIG 0x41 #define VIA_FIFO_CONFIG 0x43 @@ -54,18 +53,12 @@ #define VIA_ADDRESS_SETUP 0x4c #define VIA_UDMA_TIMING 0x50 -#define VIA_UDMA 0x007 -#define VIA_UDMA_NONE 0x000 -#define VIA_UDMA_33 0x001 -#define VIA_UDMA_66 0x002 -#define VIA_UDMA_100 0x003 -#define VIA_UDMA_133 0x004 -#define VIA_BAD_PREQ 0x010 /* Crashes if PREQ# till DDACK# set */ -#define VIA_BAD_CLK66 0x020 /* 66 MHz clock doesn't work correctly */ -#define VIA_SET_FIFO 0x040 /* Needs to have FIFO split set */ -#define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */ -#define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */ -#define VIA_BAD_AST 0x200 /* Don't touch Address Setup Timing */ +#define VIA_BAD_PREQ 0x01 /* Crashes if PREQ# till DDACK# set */ +#define VIA_BAD_CLK66 0x02 /* 66 MHz clock doesn't work correctly */ +#define VIA_SET_FIFO 0x04 /* Needs to have FIFO split set */ +#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */ +#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */ +#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */ /* * VIA SouthBridge chips. @@ -76,36 +69,37 @@ static struct via_isa_bridge { u16 id; u8 rev_min; u8 rev_max; - u16 flags; + u8 udma_mask; + u8 flags; } via_isa_bridges[] = { - { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, - { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, + { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, + { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, ATA_UDMA5, }, + { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, ATA_UDMA5, }, + { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, ATA_UDMA5, }, + { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, ATA_UDMA5, }, + { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, ATA_UDMA4, }, + { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 }, + { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, ATA_UDMA4, }, + { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ }, + { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO }, + { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO }, + { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK }, + { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, { NULL } }; static unsigned int via_clock; -static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; +static char *via_dma[] = { "16", "25", "33", "44", "66", "100", "133" }; struct via82cxxx_dev { @@ -140,12 +134,12 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); - switch (vdev->via_config->flags & VIA_UDMA) { - case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; - case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; - case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; - default: return; + switch (vdev->via_config->udma_mask) { + case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; + case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; + case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; + case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; + default: return; } pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t); @@ -173,12 +167,12 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) T = 1000000000 / via_clock; - switch (vdev->via_config->flags & VIA_UDMA) { - case VIA_UDMA_33: UT = T; break; - case VIA_UDMA_66: UT = T/2; break; - case VIA_UDMA_100: UT = T/3; break; - case VIA_UDMA_133: UT = T/4; break; - default: UT = T; + switch (vdev->via_config->udma_mask) { + case ATA_UDMA2: UT = T; break; + case ATA_UDMA4: UT = T/2; break; + case ATA_UDMA5: UT = T/3; break; + case ATA_UDMA6: UT = T/4; break; + default: UT = T; } ide_timing_compute(drive, speed, &t, T, UT); @@ -208,8 +202,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) { if (pio == 255) { - via_set_drive(drive, - ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); + via_set_drive(drive, ide_find_best_pio_mode(drive)); return; } @@ -226,16 +219,10 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) static int via82cxxx_ide_dma_check (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); - u16 w80 = hwif->udma_four; + u8 speed = ide_max_dma_mode(drive); - u16 speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | - (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); + if (speed == 0) + speed = ide_find_best_pio_mode(drive); via_set_drive(drive, speed); @@ -272,8 +259,8 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u) { int i; - switch (vdev->via_config->flags & VIA_UDMA) { - case VIA_UDMA_66: + switch (vdev->via_config->udma_mask) { + case ATA_UDMA4: for (i = 24; i >= 0; i -= 8) if (((u >> (i & 16)) & 8) && ((u >> i) & 0x20) && @@ -286,7 +273,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u) } break; - case VIA_UDMA_100: + case ATA_UDMA5: for (i = 24; i >= 0; i -= 8) if (((u >> i) & 0x10) || (((u >> i) & 0x20) && @@ -298,7 +285,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u) } break; - case VIA_UDMA_133: + case ATA_UDMA6: for (i = 24; i >= 0; i -= 8) if (((u >> i) & 0x10) || (((u >> i) & 0x20) && @@ -353,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const via_cable_detect(vdev, u); - if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { + if (via_config->udma_mask == ATA_UDMA4) { /* Enable Clk66 */ pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); } else if (via_config->flags & VIA_BAD_CLK66) { @@ -416,10 +403,12 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const */ pci_read_config_byte(isa, PCI_REVISION_ID, &t); - printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %s " + printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %sDMA%s " "controller on pci%s\n", via_config->name, t, - via_dma[via_config->flags & VIA_UDMA], + via_config->udma_mask ? "U" : "MW", + via_dma[via_config->udma_mask ? + (fls(via_config->udma_mask) - 1) : 0], pci_name(dev)); pci_dev_put(isa); @@ -454,7 +443,8 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) return; hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; + + hwif->ultra_mask = vdev->via_config->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index f9bada093d19..5e3077409457 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1821,28 +1821,11 @@ pmac_ide_dma_check(ide_drive_t *drive) enable = 0; if (enable) { - short mode; - - map = XFER_MWDMA; - if (pmif->kind == controller_kl_ata4 - || pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6 - || pmif->kind == controller_sh_ata6) { - map |= XFER_UDMA; - if (pmif->cable_80) { - map |= XFER_UDMA_66; - if (pmif->kind == controller_un_ata6 || - pmif->kind == controller_k2_ata6 || - pmif->kind == controller_sh_ata6) - map |= XFER_UDMA_100; - if (pmif->kind == controller_sh_ata6) - map |= XFER_UDMA_133; - } - } - mode = ide_find_best_mode(drive, map); - if (mode & XFER_UDMA) + u8 mode = ide_max_dma_mode(drive); + + if (mode >= XFER_UDMA_0) drive->using_dma = pmac_ide_udma_enable(drive, mode); - else if (mode & XFER_MWDMA) + else if (mode >= XFER_MW_DMA_0) drive->using_dma = pmac_ide_mdma_enable(drive, mode); hwif->OUTB(0, IDE_CONTROL_REG); /* Apply settings to controller */ From 49521f97ccd3c2bf6e71a91cea8fe65d170fa4fb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:58 +0200 Subject: [PATCH 310/551] ide: add short cables support This patch allows users to override both host and device side cable detection with "ideX=ata66" kernel parameter. Thanks to this it should be now possible to use UDMA > 2 modes on systems (laptops mainly) which use short 40-pin cable instead of 80-pin one. Next patches add automatic detection of some systems using short cables. Changes: * Rename hwif->udma_four to hwif->cbl and make it u8. * Convert all existing users accordingly (use ATA_CBL_* defines while at it). * Add ATA_CBL_PATA40_SHORT support to ide-iops.c:eighty_ninty_three(). * Use ATA_CBL_PATA40_SHORT for "ideX=ata66" kernel parameter. Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Sergei Shtylyov --- drivers/ide/cris/ide-cris.c | 2 +- drivers/ide/ide-iops.c | 8 ++++++-- drivers/ide/ide.c | 9 +++++++-- drivers/ide/pci/aec62xx.c | 5 +++-- drivers/ide/pci/alim15x3.c | 9 +++++---- drivers/ide/pci/amd74xx.c | 9 +++++++-- drivers/ide/pci/atiixp.c | 5 +++-- drivers/ide/pci/cmd64x.c | 10 +++++----- drivers/ide/pci/cs5535.c | 6 +++--- drivers/ide/pci/hpt366.c | 4 ++-- drivers/ide/pci/it8213.c | 8 ++++---- drivers/ide/pci/it821x.c | 9 +++++---- drivers/ide/pci/jmicron.c | 20 +++++++++++--------- drivers/ide/pci/pdc202xx_new.c | 9 ++++++--- drivers/ide/pci/pdc202xx_old.c | 9 ++++++--- drivers/ide/pci/piix.c | 8 ++++---- drivers/ide/pci/scc_pata.c | 2 +- drivers/ide/pci/serverworks.c | 26 +++++++++++++------------- drivers/ide/pci/siimage.c | 20 +++++++++++--------- drivers/ide/pci/sis5513.c | 9 +++++---- drivers/ide/pci/slc90e66.c | 5 ++--- drivers/ide/pci/tc86c001.c | 4 ++-- drivers/ide/pci/via82cxxx.c | 9 +++++++-- drivers/ide/ppc/pmac.c | 6 +++--- include/linux/ide.h | 3 ++- 25 files changed, 124 insertions(+), 90 deletions(-) diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index ca0341c05e55..886091bc7db0 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -819,7 +819,7 @@ init_e100_ide (void) hwif->dma_host_off = &cris_dma_off; hwif->dma_host_on = &cris_dma_on; hwif->dma_off_quietly = &cris_dma_off; - hwif->udma_four = 0; + hwif->cbl = ATA_CBL_PATA40; hwif->ultra_mask = cris_ultra_mask; hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ hwif->autodma = 1; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index f0be5f665a0e..92578b6832e9 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -574,7 +574,10 @@ u8 eighty_ninty_three (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if (hwif->udma_four == 0) + if (hwif->cbl == ATA_CBL_PATA40_SHORT) + return 1; + + if (hwif->cbl != ATA_CBL_PATA80) goto no_80w; /* Check for SATA but only if we are ATA5 or higher */ @@ -600,7 +603,8 @@ no_80w: printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " "limiting max speed to UDMA33\n", - drive->name, hwif->udma_four ? "drive" : "host"); + drive->name, + hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); drive->udma33_warned = 1; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 574414689253..c948a5c17a5d 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -460,6 +460,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->mwdma_mask = tmp_hwif->mwdma_mask; hwif->swdma_mask = tmp_hwif->swdma_mask; + hwif->cbl = tmp_hwif->cbl; + hwif->chipset = tmp_hwif->chipset; hwif->hold = tmp_hwif->hold; @@ -533,7 +535,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->extra_base = tmp_hwif->extra_base; hwif->extra_ports = tmp_hwif->extra_ports; hwif->autodma = tmp_hwif->autodma; - hwif->udma_four = tmp_hwif->udma_four; hwif->hwif_data = tmp_hwif->hwif_data; } @@ -1548,7 +1549,11 @@ static int __init ide_setup(char *s) goto bad_option; case -7: /* ata66 */ #ifdef CONFIG_BLK_DEV_IDEPCI - hwif->udma_four = 1; + /* + * Use ATA_CBL_PATA40_SHORT so drive side + * cable detection is also overriden. + */ + hwif->cbl = ATA_CBL_PATA40_SHORT; goto obsolete_option; #else goto bad_hwif; diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 794ac40ec90f..e5d09367627e 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -234,11 +234,12 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) pci_read_config_byte (dev, 0x54, ®54); pci_write_config_byte(dev, 0x54, (reg54 & ~mask)); spin_unlock_irqrestore(&ide_lock, flags); - } else if (!hwif->udma_four) { + } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) { u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01; pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); - hwif->udma_four = (ata66 & mask) ? 0 : 1; + + hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; } if (!noautodma) diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 27525ec2e19a..d52c54bb6a78 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -594,7 +594,7 @@ out: * FIXME: frobs bits that are not defined on newer ALi devicea */ -static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) +static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ata66 = 0; @@ -657,7 +657,7 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) local_irq_restore(flags); - return(ata66); + return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } /** @@ -708,8 +708,9 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) hwif->dma_setup = &ali15x3_dma_setup; if (!noautodma) hwif->autodma = 1; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_ali15x3(hwif); + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_ali15x3(hwif); } hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index a7443f15b27a..84ed30cdb324 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -431,8 +431,13 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) if ((amd_config->flags & AMD_BAD_SWDMA) == 0) hwif->swdma_mask = 0x07; - if (!hwif->udma_four) - hwif->udma_four = (amd_80w >> hwif->channel) & 1; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) { + if ((amd_80w >> hwif->channel) & 1) + hwif->cbl = ATA_CBL_PATA80; + else + hwif->cbl = ATA_CBL_PATA40; + } + hwif->ide_dma_check = &amd74xx_ide_dma_check; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 8ab33faf6f76..2761510309b3 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -264,10 +264,11 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->swdma_mask = 0x04; pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode); + if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40) - hwif->udma_four = 1; + hwif->cbl = ATA_CBL_PATA80; else - hwif->udma_four = 0; + hwif->cbl = ATA_CBL_PATA40; hwif->dma_host_on = &atiixp_dma_host_on; hwif->dma_host_off = &atiixp_dma_host_off; diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index b0aa7d03b8a5..8631b6c8aa15 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -517,7 +517,7 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha return 0; } -static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) +static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u8 bmidecsr = 0, mask = hwif->channel ? 0x02 : 0x01; @@ -526,9 +526,9 @@ static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_649: pci_read_config_byte(dev, BMIDECSR, &bmidecsr); - return (bmidecsr & mask) ? 1 : 0; + return (bmidecsr & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; default: - return 0; + return ATA_CBL_PATA40; } } @@ -568,8 +568,8 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->ide_dma_check = &cmd64x_config_drive_for_dma; - if (!hwif->udma_four) - hwif->udma_four = ata66_cmd64x(hwif); + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_cmd64x(hwif); switch (dev->device) { case PCI_DEVICE_ID_CMD_648: diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 41925c47ef05..10f61f38243c 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -187,7 +187,8 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) /* if a 80 wire cable was detected */ pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit); - return (bit & 1); + + return (bit & 1) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } /**** @@ -212,8 +213,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) hwif->ultra_mask = 0x1F; hwif->mwdma_mask = 0x07; - - hwif->udma_four = cs5535_cable_detect(hwif->pci_dev); + hwif->cbl = cs5535_cable_detect(hwif->pci_dev); if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index ce363c923613..4b6bae8eee82 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1330,8 +1330,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) } else pci_read_config_byte (dev, 0x5a, &scr1); - if (!hwif->udma_four) - hwif->udma_four = (scr1 & ata66) ? 0 : 1; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index c04a02687b95..ff48c23e571e 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -231,7 +231,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive) static void __devinit init_hwif_it8213(ide_hwif_t *hwif) { - u8 reg42h = 0, ata66 = 0; + u8 reg42h = 0; hwif->speedproc = &it8213_tune_chipset; hwif->tuneproc = &it8213_tuneproc; @@ -250,11 +250,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) hwif->swdma_mask = 0x04; pci_read_config_byte(hwif->pci_dev, 0x42, ®42h); - ata66 = (reg42h & 0x02) ? 0 : 1; hwif->ide_dma_check = &it8213_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66; + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; /* * The BIOS often doesn't set up DMA on this controller diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 3aeb7f1b7916..8197b653ba1e 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -491,10 +491,10 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive) * the needed logic onboard. */ -static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif) +static u8 __devinit ata66_it821x(ide_hwif_t *hwif) { /* The reference driver also only does disk side */ - return 1; + return ATA_CBL_PATA80; } /** @@ -662,8 +662,9 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &it821x_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_it821x(hwif); + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_it821x(hwif); /* * The BIOS often doesn't set up DMA on this controller diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index 76ed25147229..a6008f63e71e 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -25,10 +25,10 @@ typedef enum { * ata66_jmicron - Cable check * @hwif: IDE port * - * Return 1 if the cable is 80pin + * Returns the cable type. */ -static int __devinit ata66_jmicron(ide_hwif_t *hwif) +static u8 __devinit ata66_jmicron(ide_hwif_t *hwif) { struct pci_dev *pdev = hwif->pci_dev; @@ -70,16 +70,17 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif) { case PORT_PATA0: if (control & (1 << 3)) /* 40/80 pin primary */ - return 0; - return 1; + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; case PORT_PATA1: if (control5 & (1 << 19)) /* 40/80 pin secondary */ - return 0; - return 1; + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; case PORT_SATA: break; } - return 1; /* Avoid bogus "control reaches end of non-void function" */ + /* Avoid bogus "control reaches end of non-void function" */ + return ATA_CBL_PATA80; } static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) @@ -159,8 +160,9 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &jmicron_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_jmicron(hwif); + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_jmicron(hwif); hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 0765dce6948e..ee5020df005d 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -225,7 +225,10 @@ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) static u8 pdcnew_cable_detect(ide_hwif_t *hwif) { - return get_indexed_reg(hwif, 0x0b) & 0x04; + if (get_indexed_reg(hwif, 0x0b) & 0x04) + return ATA_CBL_PATA40; + else + return ATA_CBL_PATA80; } static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) @@ -509,8 +512,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; - if (!hwif->udma_four) - hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = pdcnew_cable_detect(hwif); if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index ae628b86e18a..41ac4a94959f 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -152,8 +152,10 @@ static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) { u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10); + pci_read_config_word(hwif->pci_dev, 0x50, &CIS); - return (CIS & mask) ? 1 : 0; + + return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; } /* @@ -357,8 +359,9 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->dma_timeout = &pdc202xx_dma_timeout; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { - if (!(hwif->udma_four)) - hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = pdc202xx_old_cable_detect(hwif); + hwif->dma_start = &pdc202xx_old_ide_dma_start; hwif->ide_dma_end = &pdc202xx_old_ide_dma_end; } diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 8b219dd63024..1547c37f3332 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -394,14 +394,14 @@ static void piix_dma_clear_irq(ide_drive_t *drive) hwif->OUTB(dma_stat, hwif->dma_status); } -static int __devinit piix_cable_detect(ide_hwif_t *hwif) +static u8 __devinit piix_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30; pci_read_config_byte(dev, 0x54, ®54h); - return (reg54h & mask) ? 1 : 0; + return (reg54h & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } /** @@ -444,8 +444,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->swdma_mask = 0x04; if (hwif->ultra_mask & 0x78) { - if (!hwif->udma_four) - hwif->udma_four = piix_cable_detect(hwif); + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = piix_cable_detect(hwif); } if (no_piix_dma) diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 55bc0a32e34f..7b87488e3daa 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -716,7 +716,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->atapi_dma = 1; /* we support 80c cable only. */ - hwif->udma_four = 1; + hwif->cbl = ATA_CBL_PATA80; hwif->autodma = 0; if (!noautodma) diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 09a7aedf63ac..1371b5bf6bf0 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -329,9 +329,9 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha return dev->irq; } -static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) +static u8 __devinit ata66_svwks_svwks(ide_hwif_t *hwif) { - return 1; + return ATA_CBL_PATA80; } /* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits @@ -341,7 +341,7 @@ static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) * Bit 14 clear = primary IDE channel does not have 80-pin cable. * Bit 14 set = primary IDE channel has 80-pin cable. */ -static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif) +static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && @@ -349,8 +349,8 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif) (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE || dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE)) return ((1 << (hwif->channel + 14)) & - dev->subsystem_device) ? 1 : 0; - return 0; + dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; + return ATA_CBL_PATA40; } /* Sun Cobalt Alpine hardware avoids the 80-pin cable @@ -359,18 +359,18 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif) * * WARNING: this only works on Alpine hardware! */ -static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif) +static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN && dev->vendor == PCI_VENDOR_ID_SERVERWORKS && dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) return ((1 << (hwif->channel + 14)) & - dev->subsystem_device) ? 1 : 0; - return 0; + dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; + return ATA_CBL_PATA40; } -static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) +static u8 __devinit ata66_svwks(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -389,9 +389,9 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) /* Per Specified Design by OEM, and ASIC Architect */ if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) - return 1; + return ATA_CBL_PATA80; - return 0; + return ATA_CBL_PATA40; } static void __devinit init_hwif_svwks (ide_hwif_t *hwif) @@ -422,8 +422,8 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->ide_dma_check = &svwks_config_drive_xfer_rate; if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { - if (!hwif->udma_four) - hwif->udma_four = ata66_svwks(hwif); + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_svwks(hwif); } if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 1a4444e7226a..1c3e35487893 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -933,16 +933,17 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif) * interface. */ -static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif) +static u8 __devinit ata66_siimage(ide_hwif_t *hwif) { unsigned long addr = siimage_selreg(hwif, 0); - if (pci_get_drvdata(hwif->pci_dev) == NULL) { - u8 ata66 = 0; - pci_read_config_byte(hwif->pci_dev, addr, &ata66); - return (ata66 & 0x01) ? 1 : 0; - } + u8 ata66 = 0; - return (hwif->INB(addr) & 0x01) ? 1 : 0; + if (pci_get_drvdata(hwif->pci_dev) == NULL) + pci_read_config_byte(hwif->pci_dev, addr, &ata66); + else + ata66 = hwif->INB(addr); + + return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } /** @@ -988,8 +989,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->atapi_dma = 1; hwif->ide_dma_check = &siimage_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_siimage(hwif); + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_siimage(hwif); if (hwif->mmio) { hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index ec0adad9ef61..4457c9d379f6 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -796,7 +796,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c return 0; } -static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif) +static u8 __devinit ata66_sis5513(ide_hwif_t *hwif) { u8 ata66 = 0; @@ -811,7 +811,8 @@ static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif) pci_read_config_byte(hwif->pci_dev, 0x48, ®48h); ata66 = (reg48h & mask) ? 0 : 1; } - return ata66; + + return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) @@ -841,8 +842,8 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) if (!chipset_family) return; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_sis5513(hwif); + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_sis5513(hwif); if (chipset_family > ATA_16) { hwif->ide_dma_check = &sis5513_config_xfer_rate; diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index c40f291f91e0..575dbbd8b482 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -199,10 +199,9 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->mwdma_mask = 0x06; hwif->swdma_mask = 0x04; - if (!hwif->udma_four) { + if (hwif->cbl != ATA_CBL_PATA40_SHORT) /* bit[0(1)]: 0:80, 1:40 */ - hwif->udma_four = (reg47 & mask) ? 0 : 1; - } + hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index cee619bb2eaf..8de1f8e22494 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c @@ -220,13 +220,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate; hwif->dma_start = &tc86c001_dma_start; - if (!hwif->udma_four) { + if (hwif->cbl != ATA_CBL_PATA40_SHORT) { /* * System Control 1 Register bit 13 (PDIAGN): * 0=80-pin cable, 1=40-pin cable */ scr1 = hwif->INW(sc_base + 0x00); - hwif->udma_four = (scr1 & 0x2000) ? 0 : 1; + hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; } if (!noautodma) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 49bd1c645fb2..ae88e9f65921 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -448,8 +448,13 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (!hwif->udma_four) - hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) { + if ((vdev->via_80w >> hwif->channel) & 1) + hwif->cbl = ATA_CBL_PATA80; + else + hwif->cbl = ATA_CBL_PATA40; + } + hwif->ide_dma_check = &via82cxxx_ide_dma_check; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 5e3077409457..e46f47206542 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -942,8 +942,8 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) return 1; case XFER_UDMA_4: case XFER_UDMA_3: - if (HWIF(drive)->udma_four == 0) - return 1; + if (drive->hwif->cbl != ATA_CBL_PATA80) + return 1; case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: @@ -1244,7 +1244,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->chipset = ide_pmac; hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay; hwif->hold = pmif->mediabay; - hwif->udma_four = pmif->cable_80; + hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; hwif->tuneproc = pmac_ide_tuneproc; diff --git a/include/linux/ide.h b/include/linux/ide.h index b6546f442fa4..19ab25804056 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -686,6 +686,8 @@ typedef struct hwif_s { u8 mwdma_mask; u8 swdma_mask; + u8 cbl; /* cable type */ + hwif_chipset_t chipset; /* sub-module for tuning.. */ struct pci_dev *pci_dev; /* for pci chipsets */ @@ -792,7 +794,6 @@ typedef struct hwif_s { unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ unsigned autodma : 1; /* auto-attempt using DMA at boot */ - unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */ unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */ unsigned auto_poll : 1; /* supports nop auto-poll */ From 7207626f47a3d66ce361bad197eefca4b8a6fa17 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:58 +0200 Subject: [PATCH 311/551] piix: backport short cables support from ata_piix.c Backport short cables support from ata_piix.c. This patch should allow UDMA > 2 modes on: - Acer 5602WLMi - Acer 3682WLMi - Asus W5F - Acer Aspire 2023WLMi Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov --- drivers/ide/pci/piix.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 1547c37f3332..2e0b29ef596a 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.47 February 8, 2007 + * linux/drivers/ide/pci/piix.c Version 0.50 Jun 10, 2007 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick @@ -394,12 +394,43 @@ static void piix_dma_clear_irq(ide_drive_t *drive) hwif->OUTB(dma_stat, hwif->dma_status); } +struct ich_laptop { + u16 device; + u16 subvendor; + u16 subdevice; +}; + +/* + * List of laptops that use short cables rather than 80 wire + */ + +static const struct ich_laptop ich_laptop[] = { + /* devid, subvendor, subdev */ + { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ + { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ + { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ + /* end marker */ + { 0, } +}; + static u8 __devinit piix_cable_detect(ide_hwif_t *hwif) { - struct pci_dev *dev = hwif->pci_dev; + struct pci_dev *pdev = hwif->pci_dev; + const struct ich_laptop *lap = &ich_laptop[0]; u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30; - pci_read_config_byte(dev, 0x54, ®54h); + /* check for specials */ + while (lap->device) { + if (lap->device == pdev->device && + lap->subvendor == pdev->subsystem_vendor && + lap->subdevice == pdev->subsystem_device) { + return ATA_CBL_PATA40_SHORT; + } + lap++; + } + + pci_read_config_byte(pdev, 0x54, ®54h); return (reg54h & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; } From 95ba8c17bc57bf4666e9de2be715b69d9a1ba211 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:58 +0200 Subject: [PATCH 312/551] alim15x3: backport short cables support from pata_ali.c Backport short cables support from pata_ali.c and while at it cleanup existing cable detection code. This patch should allow UDMA > 2 modes on HP Pavilion N5430 and Fujitsu P2000. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov --- drivers/ide/pci/alim15x3.c | 71 ++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index d52c54bb6a78..8a6b27b3bcc3 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/alim15x3.c Version 0.21 2007/02/03 + * linux/drivers/ide/pci/alim15x3.c Version 0.25 Jun 9 2007 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer @@ -10,6 +10,7 @@ * Copyright (C) 2002 Alan Cox * ALi (now ULi M5228) support by Clear Zhang * Copyright (C) 2007 MontaVista Software, Inc. + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * (U)DMA capable version of ali 1533/1543(C), 1535(D) * @@ -36,6 +37,7 @@ #include #include #include +#include #include @@ -583,6 +585,35 @@ out: return 0; } +/* + * Cable special cases + */ + +static struct dmi_system_id cable_dmi_table[] = { + { + .ident = "HP Pavilion N5430", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"), + }, + }, + { } +}; + +static int ali_cable_override(struct pci_dev *pdev) +{ + /* Fujitsu P2000 */ + if (pdev->subsystem_vendor == 0x10CF && + pdev->subsystem_device == 0x10AF) + return 1; + + /* Systems by DMI */ + if (dmi_check_system(cable_dmi_table)) + return 1; + + return 0; +} + /** * ata66_ali15x3 - check for UDMA 66 support * @hwif: IDE interface @@ -597,34 +628,28 @@ out: static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - unsigned int ata66 = 0; - u8 cable_80_pin[2] = { 0, 0 }; - unsigned long flags; - u8 tmpbyte; + u8 cbl = ATA_CBL_PATA40, tmpbyte; local_irq_save(flags); if (m5229_revision >= 0xC2) { /* - * Ultra66 cable detection (from Host View) - * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin + * m5229 80-pin cable detection (from Host View) + * + * 0x4a bit0 is 0 => primary channel has 80-pin + * 0x4a bit1 is 0 => secondary channel has 80-pin + * + * Certain laptops use short but suitable cables + * and don't implement the detect logic. */ - pci_read_config_byte(dev, 0x4a, &tmpbyte); - /* - * 0x4a, bit0 is 0 => primary channel - * has 80-pin (from host view) - */ - if (!(tmpbyte & 0x01)) cable_80_pin[0] = 1; - /* - * 0x4a, bit1 is 0 => secondary channel - * has 80-pin (from host view) - */ - if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1; - /* - * Allow ata66 if cable of current channel has 80 pins - */ - ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; + if (ali_cable_override(dev)) + cbl = ATA_CBL_PATA40_SHORT; + else { + pci_read_config_byte(dev, 0x4a, &tmpbyte); + if ((tmpbyte & (1 << hwif->channel)) == 0) + cbl = ATA_CBL_PATA80; + } } else { /* * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 @@ -657,7 +682,7 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif) local_irq_restore(flags); - return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; + return cbl; } /** From f2befd9e80b39a5aa54d65cf59b6a5feb9a8117e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:58 +0200 Subject: [PATCH 313/551] sis5513: backport short cables support from pata_sis.c Backport short cables support from pata_sis.c. This patch allows UDMA > 2 modes on ASUS A6K. Thanks to testing this patch goes out to Jiri Stavinoha. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov --- drivers/ide/pci/sis5513.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 4457c9d379f6..f875183ac8d9 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/sis5513.c Version 0.20 Mar 4, 2007 + * linux/drivers/ide/pci/sis5513.c Version 0.25 Jun 10, 2007 * * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2002 Lionel Bouton , Maintainer @@ -796,10 +796,33 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c return 0; } +struct sis_laptop { + u16 device; + u16 subvendor; + u16 subdevice; +}; + +static const struct sis_laptop sis_laptop[] = { + /* devid, subvendor, subdev */ + { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + /* end marker */ + { 0, } +}; + static u8 __devinit ata66_sis5513(ide_hwif_t *hwif) { + struct pci_dev *pdev = hwif->pci_dev; + const struct sis_laptop *lap = &sis_laptop[0]; u8 ata66 = 0; + while (lap->device) { + if (lap->device == pdev->device && + lap->subvendor == pdev->subsystem_vendor && + lap->subdevice == pdev->subsystem_device) + return ATA_CBL_PATA40_SHORT; + lap++; + } + if (chipset_family >= ATA_133) { u16 regw = 0; u16 reg_addr = hwif->channel ? 0x52: 0x50; From bdab00b73d2f77075a3c73556e2692bf06849c17 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 9 Jul 2007 23:17:58 +0200 Subject: [PATCH 314/551] via82cxxx: backport short cables support from pata_via.c Backport short cables support from pata_via.c. This patch should allow UDMA > 2 modes on Acer Ferrari 3400. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov --- drivers/ide/pci/via82cxxx.c | 48 +++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index ae88e9f65921..d21dd2e7eeb3 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -1,6 +1,6 @@ /* * - * Version 3.40 + * Version 3.45 * * VIA IDE driver for Linux. Supported southbridges: * @@ -34,6 +34,8 @@ #include #include #include +#include + #include #ifdef CONFIG_PPC_CHRP @@ -415,6 +417,42 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const return 0; } +/* + * Cable special cases + */ + +static struct dmi_system_id cable_dmi_table[] = { + { + .ident = "Acer Ferrari 3400", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."), + DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"), + }, + }, + { } +}; + +static int via_cable_override(void) +{ + /* Systems by DMI */ + if (dmi_check_system(cable_dmi_table)) + return 1; + return 0; +} + +static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif) +{ + struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); + + if (via_cable_override()) + return ATA_CBL_PATA40_SHORT; + + if ((vdev->via_80w >> hwif->channel) & 1) + return ATA_CBL_PATA80; + else + return ATA_CBL_PATA40; +} + static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) { struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); @@ -448,12 +486,8 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (hwif->cbl != ATA_CBL_PATA40_SHORT) { - if ((vdev->via_80w >> hwif->channel) & 1) - hwif->cbl = ATA_CBL_PATA80; - else - hwif->cbl = ATA_CBL_PATA40; - } + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = via82cxxx_cable_detect(hwif); hwif->ide_dma_check = &via82cxxx_ide_dma_check; if (!noautodma) From 27a278aa4309df244a2619f47031acce00ca1b7c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jul 2007 23:17:59 +0200 Subject: [PATCH 315/551] drivers/ide/ide-dma.c: unexport ide_set_dma ide_set_dma no longer has any modular user. Signed-off-by: Adrian Bunk Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index e8c6e1ed497a..5fe1d72ab451 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -861,8 +861,6 @@ int ide_set_dma(ide_drive_t *drive) return rc; } -EXPORT_SYMBOL_GPL(ide_set_dma); - #ifdef CONFIG_BLK_DEV_IDEDMA_PCI void ide_dma_lost_irq (ide_drive_t *drive) { From 17a624869ea470e33c708871978223c3d9a4c417 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Thu, 3 May 2007 20:24:19 +0200 Subject: [PATCH 316/551] ieee1394: ohci1394: remove dead CONFIG variable spotted by Robert P. J. Day Signed-off-by: Stefan Richter --- drivers/ieee1394/ohci1394.c | 51 ++++++------------------------------- 1 file changed, 8 insertions(+), 43 deletions(-) diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 5dadfd296f79..a75b1446b6ed 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -138,19 +138,6 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host-> #define DBGMSG(fmt, args...) do {} while (0) #endif -#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG -#define OHCI_DMA_ALLOC(fmt, args...) \ - HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ - ++global_outstanding_dmas, ## args) -#define OHCI_DMA_FREE(fmt, args...) \ - HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ - --global_outstanding_dmas, ## args) -static int global_outstanding_dmas = 0; -#else -#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0) -#define OHCI_DMA_FREE(fmt, args...) do {} while (0) -#endif - /* print general (card independent) information */ #define PRINT_G(level, fmt, args...) \ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) @@ -733,7 +720,6 @@ static void insert_packet(struct ti_ohci *ohci, pci_map_single(ohci->dev, packet->data, packet->data_size, PCI_DMA_TODEVICE)); - OHCI_DMA_ALLOC("single, block transmit packet"); d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.status = 0; @@ -783,7 +769,6 @@ static void insert_packet(struct ti_ohci *ohci, d->prg_cpu[idx]->end.address = cpu_to_le32( pci_map_single(ohci->dev, packet->data, packet->data_size, PCI_DMA_TODEVICE)); - OHCI_DMA_ALLOC("single, iso transmit packet"); d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.status = 0; @@ -2869,12 +2854,10 @@ static void dma_trm_tasklet (unsigned long data) list_del_init(&packet->driver_list); hpsb_packet_sent(ohci->host, packet, ack); - if (datasize) { + if (datasize) pci_unmap_single(ohci->dev, cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), datasize, PCI_DMA_TODEVICE); - OHCI_DMA_FREE("single Xmit data packet"); - } d->sent_ind = (d->sent_ind+1)%d->num_desc; d->free_prgs++; @@ -2913,23 +2896,19 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) if (d->buf_cpu) { for (i=0; inum_desc; i++) - if (d->buf_cpu[i] && d->buf_bus[i]) { + if (d->buf_cpu[i] && d->buf_bus[i]) pci_free_consistent( ohci->dev, d->buf_size, d->buf_cpu[i], d->buf_bus[i]); - OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i); - } kfree(d->buf_cpu); kfree(d->buf_bus); } if (d->prg_cpu) { for (i=0; inum_desc; i++) - if (d->prg_cpu[i] && d->prg_bus[i]) { - pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); - OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i); - } + if (d->prg_cpu[i] && d->prg_bus[i]) + pci_pool_free(d->prg_pool, d->prg_cpu[i], + d->prg_bus[i]); pci_pool_destroy(d->prg_pool); - OHCI_DMA_FREE("dma_rcv prg pool"); kfree(d->prg_cpu); kfree(d->prg_bus); } @@ -2998,13 +2977,10 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, } num_allocs++; - OHCI_DMA_ALLOC("dma_rcv prg pool"); - for (i=0; inum_desc; i++) { d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, d->buf_size, d->buf_bus+i); - OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i); if (d->buf_cpu[i] != NULL) { memset(d->buf_cpu[i], 0, d->buf_size); @@ -3016,7 +2992,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, } d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); - OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i); if (d->prg_cpu[i] != NULL) { memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); @@ -3057,12 +3032,10 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d) if (d->prg_cpu) { for (i=0; inum_desc; i++) - if (d->prg_cpu[i] && d->prg_bus[i]) { - pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); - OHCI_DMA_FREE("pool dma_trm prg[%d]", i); - } + if (d->prg_cpu[i] && d->prg_bus[i]) + pci_pool_free(d->prg_pool, d->prg_cpu[i], + d->prg_bus[i]); pci_pool_destroy(d->prg_pool); - OHCI_DMA_FREE("dma_trm prg pool"); kfree(d->prg_cpu); kfree(d->prg_bus); } @@ -3108,11 +3081,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, } num_allocs++; - OHCI_DMA_ALLOC("dma_rcv prg pool"); - for (i = 0; i < d->num_desc; i++) { d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); - OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i); if (d->prg_cpu[i] != NULL) { memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); @@ -3294,7 +3264,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->csr_config_rom_cpu = pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, &ohci->csr_config_rom_bus); - OHCI_DMA_ALLOC("consistent csr_config_rom"); if (ohci->csr_config_rom_cpu == NULL) FAIL(-ENOMEM, "Failed to allocate buffer config rom"); ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; @@ -3303,8 +3272,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->selfid_buf_cpu = pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, &ohci->selfid_buf_bus); - OHCI_DMA_ALLOC("consistent selfid_buf"); - if (ohci->selfid_buf_cpu == NULL) FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; @@ -3490,13 +3457,11 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, ohci->selfid_buf_cpu, ohci->selfid_buf_bus); - OHCI_DMA_FREE("consistent selfid_buf"); case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, ohci->csr_config_rom_cpu, ohci->csr_config_rom_bus); - OHCI_DMA_FREE("consistent csr_config_rom"); case OHCI_INIT_HAVE_IOMAPPING: iounmap(ohci->registers); From 6552731a058a4facefd921b0b45a9a5392baa5ea Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 19 May 2007 12:29:37 +0200 Subject: [PATCH 317/551] ieee1394: add comments in struct hpsb_packet to clarify who is supposed to set what Signed-off-by: Stefan Richter --- drivers/ieee1394/ieee1394_core.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index ad526523d0ef..11fd324ee045 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -37,7 +37,7 @@ struct hpsb_packet { hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete } __attribute__((packed)) state; - /* These are core internal. */ + /* These are core-internal. */ signed char tlabel; signed char ack_code; unsigned char tcode; @@ -62,11 +62,15 @@ struct hpsb_packet { /* Store jiffies for implementing bus timeouts. */ unsigned long sendtime; - /* Sizes are in bytes. *data can be DMA-mapped. */ + /* Core-internal. */ size_t allocated_data_size; /* as allocated */ + + /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */ size_t data_size; /* as filled in */ size_t header_size; /* as filled in, not counting the CRC */ - quadlet_t *data; + + /* Buffers */ + quadlet_t *data; /* can be DMA-mapped */ quadlet_t header[5]; quadlet_t embedded_data[0]; /* keep as last member */ }; From ee9be425961c3ccf75553c83a73bf1f707e66d91 Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Mon, 7 May 2007 04:14:47 +0200 Subject: [PATCH 318/551] ieee1394: raw1394: Fix read() for 32bit userland on 64bit kernel read() always failed with -EFAULT. This was happening due to raw1394_compat_read copying data to wrong location - access_ok always failed as 'r' is kernel address, not user. Whole function just tried to copy data from 'r' to 'r', which is not good. Signed-off-by: Petr Vandrovec Acked-by: Dan Dennedy Signed-off-by: Stefan Richter (split into 3 patches) --- drivers/ieee1394/raw1394.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index f1d05eeb9f51..858fd9ba0143 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -459,7 +459,7 @@ static const char __user *raw1394_compat_write(const char __user *buf) static int raw1394_compat_read(const char __user *buf, struct raw1394_request *r) { - struct compat_raw1394_req __user *cr = (typeof(cr)) r; + struct compat_raw1394_req __user *cr = (typeof(cr)) buf; if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || P(type) || P(error) || From 883b97eaf2a3fba7628f9f78ca7dc422aaf9728b Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Mon, 7 May 2007 04:14:47 +0200 Subject: [PATCH 319/551] ieee1394: raw1394: Fix write() for 32bit userland on 64bit kernel * write(fd, buf, 52) from 32bit app was returning 56. Most of callers did not care, but some (arm registration) did, and anyway it looks bad if request for writing 52 bytes returns 56. And returning sizeof anything in 'int' is not good as well. So all functions now return '0' instead of sizeof(struct raw1394_request) on success, and write() itself provides correct return value (it just returns value it was asked to write on success as raw1394 does not do any partial writes at all). * Related to this was problem that write() could have returned 0 when kernel state would become corrupted and moved to different state than opened/initialized/connected. Now it returns -EBADFD which seemed appropriate. Signed-off-by: Petr Vandrovec Acked-by: Dan Dennedy Signed-off-by: Stefan Richter (split into 3 patches) --- drivers/ieee1394/raw1394.c | 65 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 858fd9ba0143..94a3b6db589c 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -587,7 +587,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req) req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } static int state_initialized(struct file_info *fi, struct pending_request *req) @@ -601,7 +601,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) req->req.generation = atomic_read(&internal_generation); req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } switch (req->req.type) { @@ -673,7 +673,7 @@ out_set_card: } queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } static void handle_iso_listen(struct file_info *fi, struct pending_request *req) @@ -865,7 +865,7 @@ static int handle_async_request(struct file_info *fi, if (req->req.error) { req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } hpsb_set_packet_complete_task(packet, @@ -883,7 +883,7 @@ static int handle_async_request(struct file_info *fi, hpsb_free_tlabel(packet); queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int handle_iso_send(struct file_info *fi, struct pending_request *req, @@ -907,7 +907,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } req->req.length = 0; @@ -927,7 +927,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int handle_async_send(struct file_info *fi, struct pending_request *req) @@ -943,7 +943,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } data_size = req->req.length - header_length; @@ -957,7 +957,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } if (copy_from_user @@ -966,7 +966,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } packet->type = hpsb_async; @@ -994,7 +994,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, @@ -1869,7 +1869,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) spin_lock_irqsave(&host_info_lock, flags); list_add_tail(&addr->addr_list, &fi->addr_list); spin_unlock_irqrestore(&host_info_lock, flags); - return sizeof(struct raw1394_request); + return 0; } retval = hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, @@ -1887,7 +1887,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) return (-EALREADY); } free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } static int arm_unregister(struct file_info *fi, struct pending_request *req) @@ -1955,7 +1955,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, @@ -1971,7 +1971,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } /* Copy data from ARM buffer(s) to user buffer. */ @@ -2013,7 +2013,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) * queue no response, and therefore nobody * will free it. */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { DBGMSG("arm_get_buf request exceeded mapping"); spin_unlock_irqrestore(&host_info_lock, flags); @@ -2065,7 +2065,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) * queue no response, and therefore nobody * will free it. */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { DBGMSG("arm_set_buf request exceeded mapping"); spin_unlock_irqrestore(&host_info_lock, flags); @@ -2086,7 +2086,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) (req->req.misc == RAW1394_NOTIFY_ON)) { fi->notification = (u8) req->req.misc; free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } /* error EINVAL (22) invalid argument */ return (-EINVAL); @@ -2119,12 +2119,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) req->req.length = 0; queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int get_config_rom(struct file_info *fi, struct pending_request *req) { - int ret = sizeof(struct raw1394_request); + int ret = 0; quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); int status; @@ -2154,7 +2154,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) static int update_config_rom(struct file_info *fi, struct pending_request *req) { - int ret = sizeof(struct raw1394_request); + int ret = 0; quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); if (!data) return -ENOMEM; @@ -2221,7 +2221,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) hpsb_update_config_rom_image(fi->host); free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } } @@ -2286,7 +2286,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) /* we have to free the request, because we queue no response, * and therefore nobody will free it */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { for (dentry = fi->csr1212_dirs[dr]->value.directory.dentries_head; @@ -2311,7 +2311,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_ECHO: queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; case RAW1394_REQ_ISO_SEND: print_old_iso_deprecation(); @@ -2335,24 +2335,24 @@ static int state_connected(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_ISO_LISTEN: print_old_iso_deprecation(); handle_iso_listen(fi, req); - return sizeof(struct raw1394_request); + return 0; case RAW1394_REQ_FCP_LISTEN: handle_fcp_listen(fi, req); - return sizeof(struct raw1394_request); + return 0; case RAW1394_REQ_RESET_BUS: if (req->req.misc == RAW1394_LONG_RESET) { DBGMSG("busreset called (type: LONG)"); hpsb_reset_bus(fi->host, LONG_RESET); free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } if (req->req.misc == RAW1394_SHORT_RESET) { DBGMSG("busreset called (type: SHORT)"); hpsb_reset_bus(fi->host, SHORT_RESET); free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } /* error EINVAL (22) invalid argument */ return (-EINVAL); @@ -2371,7 +2371,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) req->req.generation = get_hpsb_generation(fi->host); req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } switch (req->req.type) { @@ -2384,7 +2384,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) if (req->req.length == 0) { req->req.error = RAW1394_ERROR_INVALID_ARG; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } return handle_async_request(fi, req, node); @@ -2395,7 +2395,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, { struct file_info *fi = (struct file_info *)file->private_data; struct pending_request *req; - ssize_t retval = 0; + ssize_t retval = -EBADFD; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && @@ -2437,6 +2437,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, if (retval < 0) { free_pending_request(req); + } else { + BUG_ON(retval); + retval = count; } return retval; From 650c12c528d3e0ac69405dd35d3bc8a7228e49f2 Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Mon, 7 May 2007 04:14:47 +0200 Subject: [PATCH 320/551] ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel Add compat_ioctl. Although all structures are more or less same, raw1394_iso_packets got pointer inside, and raw1394_cycle_timer got unwanted padding in the middle. I did not add any translation for ioctls passing array of integers around as integers seem to have same size (32 bits) on all architectures supported by Linux. Signed-off-by: Petr Vandrovec Acked-by: Dan Dennedy Signed-off-by: Stefan Richter (split into 3 patches) --- drivers/ieee1394/raw1394.c | 97 +++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 94a3b6db589c..151a48f41c8f 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2805,6 +2805,99 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +#ifdef CONFIG_COMPAT +struct raw1394_iso_packets32 { + __u32 n_packets; + compat_uptr_t infos; +} __attribute__((packed)); + +struct raw1394_cycle_timer32 { + __u32 cycle_timer; + __u64 local_time; +} __attribute__((packed)); + +#define RAW1394_IOC_ISO_RECV_PACKETS32 \ + _IOW ('#', 0x25, struct raw1394_iso_packets32) +#define RAW1394_IOC_ISO_XMIT_PACKETS32 \ + _IOW ('#', 0x27, struct raw1394_iso_packets32) +#define RAW1394_IOC_GET_CYCLE_TIMER32 \ + _IOR ('#', 0x30, struct raw1394_cycle_timer32) + +static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, + struct raw1394_iso_packets32 __user *arg) +{ + compat_uptr_t infos32; + void *infos; + long err = -EFAULT; + struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets)); + + if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) && + !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { + infos = compat_ptr(infos32); + if (!copy_to_user(&dst->infos, &infos, sizeof infos)) + err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst); + } + return err; +} + +static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr) +{ + struct raw1394_cycle_timer32 ct; + int err; + + err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); + if (!err) + if (copy_to_user(uaddr, &ct, sizeof(ct))) + err = -EFAULT; + return err; +} + +static long raw1394_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct file_info *fi = file->private_data; + void __user *argp = (void __user *)arg; + long err; + + lock_kernel(); + switch (cmd) { + /* These requests have same format as long as 'int' has same size. */ + case RAW1394_IOC_ISO_RECV_INIT: + case RAW1394_IOC_ISO_RECV_START: + case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: + case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: + case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: + case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: + case RAW1394_IOC_ISO_RECV_FLUSH: + case RAW1394_IOC_ISO_XMIT_RECV_STOP: + case RAW1394_IOC_ISO_XMIT_INIT: + case RAW1394_IOC_ISO_XMIT_START: + case RAW1394_IOC_ISO_XMIT_SYNC: + case RAW1394_IOC_ISO_GET_STATUS: + case RAW1394_IOC_ISO_SHUTDOWN: + case RAW1394_IOC_ISO_QUEUE_ACTIVITY: + err = raw1394_ioctl(NULL, file, cmd, arg); + break; + /* These request have different format. */ + case RAW1394_IOC_ISO_RECV_PACKETS32: + err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp); + break; + case RAW1394_IOC_ISO_XMIT_PACKETS32: + err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp); + break; + case RAW1394_IOC_GET_CYCLE_TIMER32: + err = raw1394_read_cycle_timer32(fi, argp); + break; + default: + err = -EINVAL; + break; + } + unlock_kernel(); + + return err; +} +#endif + static unsigned int raw1394_poll(struct file *file, poll_table * pt) { struct file_info *fi = file->private_data; @@ -3044,7 +3137,9 @@ static const struct file_operations raw1394_fops = { .write = raw1394_write, .mmap = raw1394_mmap, .ioctl = raw1394_ioctl, - // .compat_ioctl = ... someone needs to do this +#ifdef CONFIG_COMPAT + .compat_ioctl = raw1394_compat_ioctl, +#endif .poll = raw1394_poll, .open = raw1394_open, .release = raw1394_release, From 19f00e66f8aa7ee581c6d003fd68ee9f9dee4057 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 21 May 2007 18:52:06 +0200 Subject: [PATCH 321/551] ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel, amendment Pointed out by Arnd Bergmann: PPC32 aligns this at 64bit, IA32 packs it. A kernel-wide available __compat_u64 which is 4-byte aligned on AMD64 and IA64 would be nicer though. Signed-off-by: Stefan Richter --- drivers/ieee1394/raw1394.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 151a48f41c8f..7b5aeb39ad85 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2814,7 +2814,11 @@ struct raw1394_iso_packets32 { struct raw1394_cycle_timer32 { __u32 cycle_timer; __u64 local_time; -} __attribute__((packed)); +} +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) +__attribute__((packed)) +#endif +; #define RAW1394_IOC_ISO_RECV_PACKETS32 \ _IOW ('#', 0x25, struct raw1394_iso_packets32) From 59337087cb33db58aa0d4463892b4475cf66a50b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 4 Jul 2007 23:13:53 +0200 Subject: [PATCH 322/551] ieee1394: raw1394: fix a 32/64-bits compat fix I was told that only i386 aligns 64 bit integers at 4 bytes boundaries while all other architectures (32 bit architectures with 64 bit siblings) align it on 8 bytes boundaries. Signed-off-by: Stefan Richter --- drivers/ieee1394/raw1394.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 7b5aeb39ad85..a3093b79e284 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -434,7 +434,11 @@ struct compat_raw1394_req { __u64 sendb; __u64 recvb; -} __attribute__((packed)); +} +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) +__attribute__((packed)) +#endif +; static const char __user *raw1394_compat_write(const char __user *buf) { From dd7f2928d834f7ac67202bcdf24a44ba9b138f08 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 May 2007 11:50:53 +0200 Subject: [PATCH 323/551] ieee1394: convert ieee1394 from "struct class_device" to "struct device" Here is a straightforward conversion to "struct device". The "struct class_device" will be removed from the kernel. It seems to work fine for me with and without CONFIG_SYSFS_DEPRECATED set. Signed-off-by: Stefan Richter --- drivers/ieee1394/dv1394.c | 8 +-- drivers/ieee1394/hosts.c | 10 +-- drivers/ieee1394/hosts.h | 2 +- drivers/ieee1394/nodemgr.c | 118 ++++++++++++++++++----------------- drivers/ieee1394/nodemgr.h | 4 +- drivers/ieee1394/raw1394.c | 18 +++--- drivers/ieee1394/video1394.c | 10 +-- 7 files changed, 86 insertions(+), 84 deletions(-) diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 208141377612..65722117ab6e 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -2280,7 +2280,7 @@ static void dv1394_remove_host(struct hpsb_host *host) } while (video); if (found_ohci_card) - class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, + device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2))); } @@ -2295,9 +2295,9 @@ static void dv1394_add_host(struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; - class_device_create(hpsb_protocol_class, NULL, MKDEV( - IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), - NULL, "dv1394-%d", id); + device_create(hpsb_protocol_class, NULL, MKDEV( + IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), + "dv1394-%d", id); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index bd0755c789c5..7ea64eec2270 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -156,13 +156,13 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, h->device.parent = dev; snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); - h->class_dev.dev = &h->device; - h->class_dev.class = &hpsb_host_class; - snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); + h->host_dev.parent = &h->device; + h->host_dev.class = &hpsb_host_class; + snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); if (device_register(&h->device)) goto fail; - if (class_device_register(&h->class_dev)) { + if (device_register(&h->host_dev)) { device_unregister(&h->device); goto fail; } @@ -202,7 +202,7 @@ void hpsb_remove_host(struct hpsb_host *host) host->driver = &dummy_driver; highlevel_remove_host(host); - class_device_unregister(&host->class_dev); + device_unregister(&host->host_dev); device_unregister(&host->device); } diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index feb55d032294..979fd190f60f 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h @@ -57,7 +57,7 @@ struct hpsb_host { struct hpsb_host_driver *driver; struct pci_dev *pdev; struct device device; - struct class_device class_dev; + struct device host_dev; struct delayed_work delayed_reset; unsigned config_roms:31; diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 81b3864d2ba7..893955249bad 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -154,7 +154,7 @@ struct host_info { }; static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); static void nodemgr_resume_ne(struct node_entry *ne); static void nodemgr_remove_ne(struct node_entry *ne); @@ -165,37 +165,38 @@ struct bus_type ieee1394_bus_type = { .match = nodemgr_bus_match, }; -static void host_cls_release(struct class_device *class_dev) +static void host_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device); + put_device(&container_of((dev), struct hpsb_host, host_dev)->device); } struct class hpsb_host_class = { .name = "ieee1394_host", - .release = host_cls_release, + .dev_release = host_cls_release, }; -static void ne_cls_release(struct class_device *class_dev) +static void ne_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct node_entry, class_dev)->device); + put_device(&container_of((dev), struct node_entry, node_dev)->device); } static struct class nodemgr_ne_class = { .name = "ieee1394_node", - .release = ne_cls_release, + .dev_release = ne_cls_release, }; -static void ud_cls_release(struct class_device *class_dev) +static void ud_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct unit_directory, class_dev)->device); + put_device(&container_of((dev), struct unit_directory, unit_dev)->device); } /* The name here is only so that unit directory hotplug works with old - * style hotplug, which only ever did unit directories anyway. */ + * style hotplug, which only ever did unit directories anyway. + */ static struct class nodemgr_ud_class = { .name = "ieee1394", - .release = ud_cls_release, - .uevent = nodemgr_uevent, + .dev_release = ud_cls_release, + .dev_uevent = nodemgr_uevent, }; static struct hpsb_highlevel nodemgr_highlevel; @@ -730,11 +731,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds); static void nodemgr_remove_uds(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *tmp, *ud; - /* Iteration over nodemgr_ud_class.children has to be protected by - * nodemgr_ud_class.sem, but class_device_unregister() will eventually + /* Iteration over nodemgr_ud_class.devices has to be protected by + * nodemgr_ud_class.sem, but device_unregister() will eventually * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, * release the semaphore, and then unregister the ud. Since this code * may be called from other contexts besides the knodemgrds, protect the @@ -744,9 +745,9 @@ static void nodemgr_remove_uds(struct node_entry *ne) for (;;) { ud = NULL; down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - tmp = container_of(cdev, struct unit_directory, - class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + tmp = container_of(dev, struct unit_directory, + unit_dev); if (tmp->ne == ne) { ud = tmp; break; @@ -755,7 +756,7 @@ static void nodemgr_remove_uds(struct node_entry *ne) up(&nodemgr_ud_class.sem); if (ud == NULL) break; - class_device_unregister(&ud->class_dev); + device_unregister(&ud->unit_dev); device_unregister(&ud->device); } mutex_unlock(&nodemgr_serialize_remove_uds); @@ -772,10 +773,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); - nodemgr_remove_uds(ne); - class_device_unregister(&ne->class_dev); + device_unregister(&ne->node_dev); device_unregister(dev); put_device(dev); @@ -783,7 +783,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) static int __nodemgr_remove_host_dev(struct device *dev, void *data) { - nodemgr_remove_ne(container_of(dev, struct node_entry, device)); + if (dev->bus == &ieee1394_bus_type) + nodemgr_remove_ne(container_of(dev, struct node_entry, + device)); return 0; } @@ -850,14 +852,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", (unsigned long long)(ne->guid)); - ne->class_dev.dev = &ne->device; - ne->class_dev.class = &nodemgr_ne_class; - snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", - (unsigned long long)(ne->guid)); + ne->node_dev.parent = &ne->device; + ne->node_dev.class = &nodemgr_ne_class; + snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", + (unsigned long long)(ne->guid)); if (device_register(&ne->device)) goto fail_devreg; - if (class_device_register(&ne->class_dev)) + if (device_register(&ne->node_dev)) goto fail_classdevreg; get_device(&ne->device); @@ -885,12 +887,12 @@ fail_alloc: static struct node_entry *find_entry_by_guid(u64 guid) { - struct class_device *cdev; + struct device *dev; struct node_entry *ne, *ret_ne = NULL; down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->guid == guid) { ret_ne = ne; @@ -906,12 +908,12 @@ static struct node_entry *find_entry_by_guid(u64 guid) static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid) { - struct class_device *cdev; + struct device *dev; struct node_entry *ne, *ret_ne = NULL; down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->host == host && ne->nodeid == nodeid) { ret_ne = ne; @@ -935,14 +937,14 @@ static void nodemgr_register_device(struct node_entry *ne, snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", ne->device.bus_id, ud->id); - ud->class_dev.dev = &ud->device; - ud->class_dev.class = &nodemgr_ud_class; - snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", + ud->unit_dev.parent = &ud->device; + ud->unit_dev.class = &nodemgr_ud_class; + snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", ne->device.bus_id, ud->id); if (device_register(&ud->device)) goto fail_devreg; - if (class_device_register(&ud->class_dev)) + if (device_register(&ud->unit_dev)) goto fail_classdevreg; get_device(&ud->device); @@ -1159,7 +1161,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent #ifdef CONFIG_HOTPLUG -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct unit_directory *ud; @@ -1169,10 +1171,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, /* ieee1394:venNmoNspNverN */ char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; - if (!cdev) + if (!dev) return -ENODEV; - ud = container_of(cdev, struct unit_directory, class_dev); + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne->in_limbo || ud->ignore_driver) return -ENODEV; @@ -1207,7 +1209,7 @@ do { \ #else -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { return -ENODEV; @@ -1378,7 +1380,7 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) static void nodemgr_suspend_ne(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *ud; HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", @@ -1388,8 +1390,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne) WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; @@ -1404,15 +1406,15 @@ static void nodemgr_suspend_ne(struct node_entry *ne) static void nodemgr_resume_ne(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *ud; ne->in_limbo = 0; device_remove_file(&ne->device, &dev_attr_ne_in_limbo); down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; @@ -1430,11 +1432,11 @@ static void nodemgr_update_pdrv(struct node_entry *ne) { struct unit_directory *ud; struct hpsb_protocol_driver *pdrv; - struct class_device *cdev; + struct device *dev; down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; @@ -1509,7 +1511,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge static void nodemgr_node_probe(struct host_info *hi, int generation) { struct hpsb_host *host = hi->host; - struct class_device *cdev; + struct device *dev; struct node_entry *ne; /* Do some processing of the nodes we've probed. This pulls them @@ -1522,13 +1524,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) * improvement...) */ down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (!ne->needs_probe) nodemgr_probe_ne(hi, ne, generation); } - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->needs_probe) nodemgr_probe_ne(hi, ne, generation); } @@ -1756,13 +1758,13 @@ exit: */ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) { - struct class_device *cdev; + struct device *dev; struct hpsb_host *host; int error = 0; down(&hpsb_host_class.sem); - list_for_each_entry(cdev, &hpsb_host_class.children, node) { - host = container_of(cdev, struct hpsb_host, class_dev); + list_for_each_entry(dev, &hpsb_host_class.devices, node) { + host = container_of(dev, struct hpsb_host, host_dev); if ((error = cb(host, data))) break; diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index 4530b29d941c..919e92e2a955 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h @@ -84,7 +84,7 @@ struct unit_directory { int length; /* Number of quadlets */ struct device device; - struct class_device class_dev; + struct device unit_dev; struct csr1212_keyval *ud_kv; u32 lun; /* logical unit number immediate value */ @@ -107,7 +107,7 @@ struct node_entry { u32 capabilities; struct device device; - struct class_device class_dev; + struct device node_dev; /* Means this node is not attached anymore */ int in_limbo; diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index a3093b79e284..1dadd5a15ba1 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -3160,9 +3160,9 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); if (IS_ERR - (class_device_create - (hpsb_protocol_class, NULL, - MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, + (device_create( + hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), RAW1394_DEVICE_NAME))) { ret = -EFAULT; goto out_unreg; @@ -3189,9 +3189,9 @@ static int __init init_raw1394(void) goto out; out_dev: - class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_RAW1394 * 16)); out_unreg: hpsb_unregister_highlevel(&raw1394_highlevel); out: @@ -3200,9 +3200,9 @@ static int __init init_raw1394(void) static void __exit cleanup_raw1394(void) { - class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_protocol(&raw1394_driver); diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 87ebd0846c34..bd28adfd7afc 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1340,9 +1340,9 @@ static void video1394_add_host (struct hpsb_host *host) hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; - class_device_create(hpsb_protocol_class, NULL, MKDEV( - IEEE1394_MAJOR, minor), - NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + device_create(hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, minor), + "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } @@ -1351,8 +1351,8 @@ static void video1394_remove_host (struct hpsb_host *host) struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); if (ohci) - class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); + device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); return; } From a0e857eeffba8976be6bdb9f4bb011c18eb2aff7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:47:45 +0200 Subject: [PATCH 324/551] ieee1394: nodemgr: parallelize between several hosts Remove the global nodemgr_serialize mutex which enclosed most of the host thread event loop. This allows for parallelism between several host adapter cards. Properly serialize the driver hooks .update(), .suspend(), .resume(), and .remove() by means of device->sem. These hooks can be called from outside the host threads' contexts. Get() and put() the device.driver when calling its hooks. Signed-off-by: Stefan Richter --- drivers/ieee1394/nodemgr.c | 71 +++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 893955249bad..c4d3d4131f01 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "csr.h" #include "highlevel.h" @@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = { * but now we are much simpler because of the LDM. */ -static DEFINE_MUTEX(nodemgr_serialize); - struct host_info { struct hpsb_host *host; struct list_head list; @@ -1382,6 +1381,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne) { struct device *dev; struct unit_directory *ud; + struct device_driver *drv; + int error; HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); @@ -1395,10 +1396,19 @@ static void nodemgr_suspend_ne(struct node_entry *ne) if (ud->ne != ne) continue; - if (ud->device.driver && - (!ud->device.driver->suspend || - ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + error = 1; /* release if suspend is not implemented */ + if (drv->suspend) { + down(&ud->device.sem); + error = drv->suspend(&ud->device, PMSG_SUSPEND); + up(&ud->device.sem); + } + if (error) device_release_driver(&ud->device); + put_driver(drv); } up(&nodemgr_ud_class.sem); } @@ -1408,6 +1418,7 @@ static void nodemgr_resume_ne(struct node_entry *ne) { struct device *dev; struct unit_directory *ud; + struct device_driver *drv; ne->in_limbo = 0; device_remove_file(&ne->device, &dev_attr_ne_in_limbo); @@ -1418,8 +1429,16 @@ static void nodemgr_resume_ne(struct node_entry *ne) if (ud->ne != ne) continue; - if (ud->device.driver && ud->device.driver->resume) - ud->device.driver->resume(&ud->device); + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + if (drv->resume) { + down(&ud->device.sem); + drv->resume(&ud->device); + up(&ud->device.sem); + } + put_driver(drv); } up(&nodemgr_ud_class.sem); @@ -1430,9 +1449,11 @@ static void nodemgr_resume_ne(struct node_entry *ne) static void nodemgr_update_pdrv(struct node_entry *ne) { - struct unit_directory *ud; - struct hpsb_protocol_driver *pdrv; struct device *dev; + struct unit_directory *ud; + struct device_driver *drv; + struct hpsb_protocol_driver *pdrv; + int error; down(&nodemgr_ud_class.sem); list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { @@ -1440,13 +1461,20 @@ static void nodemgr_update_pdrv(struct node_entry *ne) if (ud->ne != ne) continue; - if (ud->device.driver) { - pdrv = container_of(ud->device.driver, - struct hpsb_protocol_driver, - driver); - if (pdrv->update && pdrv->update(ud)) - device_release_driver(&ud->device); + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + error = 0; + pdrv = container_of(drv, struct hpsb_protocol_driver, driver); + if (pdrv->update) { + down(&ud->device.sem); + error = pdrv->update(ud); + up(&ud->device.sem); } + if (error) + device_release_driver(&ud->device); + put_driver(drv); } up(&nodemgr_ud_class.sem); } @@ -1688,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi) if (kthread_should_stop()) goto exit; - if (mutex_lock_interruptible(&nodemgr_serialize)) { - if (try_to_freeze()) - continue; - goto exit; - } - /* Pause for 1/4 second in 1/16 second intervals, * to make sure things settle down. */ g = get_hpsb_generation(host); for (i = 0; i < 4 ; i++) { if (msleep_interruptible(63) || kthread_should_stop()) - goto unlock_exit; + goto exit; /* Now get the generation in which the node ID's we collect * are valid. During the bus scan we will use this generation @@ -1717,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi) if (!nodemgr_check_irm_capability(host, reset_cycles) || !nodemgr_do_irm_duties(host, reset_cycles)) { reset_cycles++; - mutex_unlock(&nodemgr_serialize); continue; } reset_cycles = 0; @@ -1734,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi) /* Update some of our sysfs symlinks */ nodemgr_update_host_dev_links(host); - - mutex_unlock(&nodemgr_serialize); } -unlock_exit: - mutex_unlock(&nodemgr_serialize); exit: HPSB_VERBOSE("NodeMgr: Exiting thread"); return 0; From 8e4dc400b7659691abdd92b3fc01ef094fc8a1e7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 27 May 2007 23:14:05 +0200 Subject: [PATCH 325/551] ieee1394: eth1394: revert parent device to that in 2.6.20 After ieee1394 was converted away from class_device like the networking subsystem was already in 2.6.21, eth1394's device may point to the fw-host device as its parent again like in 2.6.20. This affects userspace tools which examine the sysfs representation of eth1394's device. Signed-off-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 7c13fb3c167b..93362eed94ed 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -599,9 +599,7 @@ static void ether1394_add_host(struct hpsb_host *host) } SET_MODULE_OWNER(dev); - - /* This used to be &host->device in Linux 2.6.20 and before. */ - SET_NETDEV_DEV(dev, host->device.parent); + SET_NETDEV_DEV(dev, &host->device); priv = netdev_priv(dev); INIT_LIST_HEAD(&priv->ip_node_list); From 93f2e0259a76ceb9c598d5af382aecbb2df01c51 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 8 Jul 2007 13:34:21 +0200 Subject: [PATCH 326/551] ieee1394: first minimal NUMA awareness Association of a host device with a node on NUMA machines optimizes allocations of skbs given from the networking stack to eth1394. Signed-off-by: Stefan Richter --- drivers/ieee1394/hosts.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 7ea64eec2270..8dd09d850419 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -154,6 +154,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); h->device.parent = dev; + set_dev_node(&h->device, dev_to_node(dev)); snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); h->host_dev.parent = &h->device; From 77bba7aea7dc833caa34761fa7ce081a40a14493 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:54:52 +0200 Subject: [PATCH 327/551] ieee1394: sbp2: change some module parameters from int to bool This is upwards compatible, except that integer values other than 0 or 1 are no longer accepted. But values like "Y", "N", "no", "nnoooh!" work now. Also, improve a comment on the serialize_io parameter and make the ORB_SET_EXCLUSIVE macro ultra-safe. Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 15 +++++++-------- drivers/ieee1394/sbp2.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 3f873cc7e247..e0c385a3b450 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -118,14 +118,13 @@ MODULE_PARM_DESC(max_speed, "Force max speed " "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); /* - * Set serialize_io to 1 if you'd like only one scsi command sent - * down to us at a time (debugging). This might be necessary for very - * badly behaved sbp2 devices. + * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs. + * This is and always has been buggy in multiple subtle ways. See above TODOs. */ static int sbp2_serialize_io = 1; -module_param_named(serialize_io, sbp2_serialize_io, int, 0444); -MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers " - "(default = 1, faster = 0)"); +module_param_named(serialize_io, sbp2_serialize_io, bool, 0444); +MODULE_PARM_DESC(serialize_io, "Serialize requests coming from SCSI drivers " + "(default = Y, faster but buggy = N)"); /* * Bump up max_sectors if you'd like to support very large sized @@ -154,9 +153,9 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported " * are possible on OXFW911 and newer Oxsemi bridges. */ static int sbp2_exclusive_login = 1; -module_param_named(exclusive_login, sbp2_exclusive_login, int, 0644); +module_param_named(exclusive_login, sbp2_exclusive_login, bool, 0644); MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " - "(default = 1)"); + "(default = Y, use N for concurrent initiators)"); /* * If any of the following workarounds is required for your device to work, diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 44402b9d82a8..333a4bb76743 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -67,7 +67,7 @@ struct sbp2_command_orb { #define ORB_SET_LUN(v) ((v) & 0xffff) #define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16) #define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20) -#define ORB_SET_EXCLUSIVE(v) (((v) & 0x1) << 28) +#define ORB_SET_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) #define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff) #define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16) From 53c96b41742a2dadd14e65c23fc119f2a2fd9f05 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 24 Jun 2007 15:31:54 +0200 Subject: [PATCH 328/551] ieee1394: remove old isochronous ABI Based on patch "the scheduled removal of RAW1394_REQ_ISO_{SEND,LISTEN}" from Adrian Bunk, November 20 2006. This patch also removes the underlying facilities in ohci1394 and disables them in pcilynx. That is, hpsb_host_driver.devctl() and hpsb_host_driver.transmit_packet() are no longer used for iso reception and transmission. Since video1394 and dv1394 only work with ohci1394 and raw1394's rawiso interface has never been implemented in pcilynx, pcilynx is now no longer useful for isochronous applications. raw1394 will still handle the request types but will complete the requests with errors that indicate API version conflicts. Signed-off-by: Stefan Richter --- .../ABI/removed/raw1394_legacy_isochronous | 16 ++ Documentation/feature-removal-schedule.txt | 10 - drivers/ieee1394/highlevel.c | 45 ---- drivers/ieee1394/highlevel.h | 16 +- drivers/ieee1394/hosts.h | 8 - drivers/ieee1394/ieee1394_core.c | 8 - drivers/ieee1394/ieee1394_core.h | 5 +- drivers/ieee1394/ieee1394_transactions.c | 30 --- drivers/ieee1394/ieee1394_transactions.h | 2 - drivers/ieee1394/ohci1394.c | 221 +----------------- drivers/ieee1394/ohci1394.h | 14 -- drivers/ieee1394/pcilynx.c | 16 +- drivers/ieee1394/raw1394-private.h | 5 - drivers/ieee1394/raw1394.c | 176 +------------- drivers/ieee1394/raw1394.h | 4 +- 15 files changed, 48 insertions(+), 528 deletions(-) create mode 100644 Documentation/ABI/removed/raw1394_legacy_isochronous diff --git a/Documentation/ABI/removed/raw1394_legacy_isochronous b/Documentation/ABI/removed/raw1394_legacy_isochronous new file mode 100644 index 000000000000..1b629622d883 --- /dev/null +++ b/Documentation/ABI/removed/raw1394_legacy_isochronous @@ -0,0 +1,16 @@ +What: legacy isochronous ABI of raw1394 (1st generation iso ABI) +Date: June 2007 (scheduled), removed in kernel v2.6.23 +Contact: linux1394-devel@lists.sourceforge.net +Description: + The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have + been deprecated for quite some time. They are very inefficient as they + come with high interrupt load and several layers of callbacks for each + packet. Because of these deficiencies, the video1394 and dv1394 drivers + and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created. + +Users: + libraw1394 users via the long deprecated API raw1394_iso_write, + raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv + + libdc1394, which optionally uses these old libraw1394 calls + alternatively to the more efficient video1394 ABI diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 7d3f205b0ba5..51b369e7fc70 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -49,16 +49,6 @@ Who: Adrian Bunk --------------------------- -What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN -When: June 2007 -Why: Deprecated in favour of the more efficient and robust rawiso interface. - Affected are applications which use the deprecated part of libraw1394 - (raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv, - raw1394_stop_iso_rcv) or bypass libraw1394. -Who: Dan Dennedy , Stefan Richter - ---------------------------- - What: old NCR53C9x driver When: October 2007 Why: Replaced by the much better esp_scsi driver. Actual low-level diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c index 83a493312751..b6425469b6ee 100644 --- a/drivers/ieee1394/highlevel.c +++ b/drivers/ieee1394/highlevel.c @@ -483,37 +483,6 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, return retval; } -/** - * hpsb_listen_channel - enable receving a certain isochronous channel - * - * Reception is handled through the @hl's iso_receive op. - */ -int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel) -{ - if (channel > 63) { - HPSB_ERR("%s called with invalid channel", __FUNCTION__); - return -EINVAL; - } - if (host->iso_listen_count[channel]++ == 0) - return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); - return 0; -} - -/** - * hpsb_unlisten_channel - disable receving a certain isochronous channel - */ -void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel) -{ - if (channel > 63) { - HPSB_ERR("%s called with invalid channel", __FUNCTION__); - return; - } - if (--host->iso_listen_count[channel] == 0) - host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel); -} - static void init_hpsb_highlevel(struct hpsb_host *host) { INIT_LIST_HEAD(&dummy_zero_addr.host_list); @@ -570,20 +539,6 @@ void highlevel_host_reset(struct hpsb_host *host) read_unlock_irqrestore(&hl_irqs_lock, flags); } -void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length) -{ - unsigned long flags; - struct hpsb_highlevel *hl; - int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f; - - read_lock_irqsave(&hl_irqs_lock, flags); - list_for_each_entry(hl, &hl_irqs, irq_list) { - if (hl->iso_receive) - hl->iso_receive(host, channel, data, length); - } - read_unlock_irqrestore(&hl_irqs_lock, flags); -} - void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length) { diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h index 63474f7ee69d..eb9fe321e09a 100644 --- a/drivers/ieee1394/highlevel.h +++ b/drivers/ieee1394/highlevel.h @@ -26,9 +26,7 @@ struct hpsb_address_serve { struct hpsb_highlevel { const char *name; - /* Any of the following pointers can legally be NULL, except for - * iso_receive which can only be NULL when you don't request - * channels. */ + /* Any of the following pointers can legally be NULL. */ /* New host initialized. Will also be called during * hpsb_register_highlevel for all hosts already installed. */ @@ -43,13 +41,6 @@ struct hpsb_highlevel { * You can not expect to be able to do stock hpsb_reads. */ void (*host_reset)(struct hpsb_host *host); - /* An isochronous packet was received. Channel contains the channel - * number for your convenience, it is also contained in the included - * packet header (first quadlet, CRCs are missing). You may get called - * for channel/host combinations you did not request. */ - void (*iso_receive)(struct hpsb_host *host, int channel, - quadlet_t *data, size_t length); - /* A write request was received on either the FCP_COMMAND (direction = * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg * contains the cts field (first byte of data). */ @@ -109,7 +100,6 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags); -void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length); void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length); @@ -125,10 +115,6 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, struct hpsb_address_ops *ops, u64 start, u64 end); int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, u64 start); -int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel); -void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel); void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index 979fd190f60f..e4e8aeb4d778 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h @@ -28,8 +28,6 @@ struct hpsb_host { struct timer_list timeout; unsigned long timeout_interval; - unsigned char iso_listen_count[64]; - int node_count; /* number of identified nodes on this bus */ int selfid_count; /* total number of SelfIDs received */ int nodes_active; /* number of nodes with active link layer */ @@ -99,12 +97,6 @@ enum devctl_cmd { /* Cancel all outstanding async requests without resetting the bus. * Return void. */ CANCEL_REQUESTS, - - /* Start or stop receiving isochronous channel in arg. Return void. - * This acts as an optimization hint, hosts are not required not to - * listen on unrequested channels. */ - ISO_LISTEN_CHANNEL, - ISO_UNLISTEN_CHANNEL }; enum isoctl_cmd { diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 8f71b6a06aa0..0fc8c6e559e4 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1028,11 +1028,6 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, handle_incoming_packet(host, tcode, data, size, write_acked); break; - - case TCODE_ISO_DATA: - highlevel_iso_receive(host, data, size); - break; - case TCODE_CYCLE_START: /* simply ignore this packet if it is passed on */ break; @@ -1316,7 +1311,6 @@ EXPORT_SYMBOL(hpsb_make_streampacket); EXPORT_SYMBOL(hpsb_make_lockpacket); EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); -EXPORT_SYMBOL(hpsb_make_isopacket); EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_write); EXPORT_SYMBOL(hpsb_packet_success); @@ -1327,8 +1321,6 @@ EXPORT_SYMBOL(hpsb_unregister_highlevel); EXPORT_SYMBOL(hpsb_register_addrspace); EXPORT_SYMBOL(hpsb_unregister_addrspace); EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); -EXPORT_SYMBOL(hpsb_listen_channel); -EXPORT_SYMBOL(hpsb_unlisten_channel); EXPORT_SYMBOL(hpsb_get_hostinfo); EXPORT_SYMBOL(hpsb_create_hostinfo); EXPORT_SYMBOL(hpsb_destroy_hostinfo); diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index 11fd324ee045..21d50f73a210 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -24,9 +24,8 @@ struct hpsb_packet { nodeid_t node_id; - /* Async and Iso types should be clear, raw means send-as-is, do not - * CRC! Byte swapping shall still be done in this case. */ - enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type; + /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */ + enum { hpsb_async, hpsb_raw } __attribute__((packed)) type; /* Okay, this is core internal and a no care for hosts. * queued = queued for sending diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 40078ce930c8..c39c70a8aa9f 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -89,18 +89,6 @@ static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, packet->expect_response = 1; } -static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel, - int tag, int sync) -{ - packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_ISO_DATA << 4) | sync; - - packet->header_size = 4; - packet->data_size = length; - packet->type = hpsb_iso; - packet->tcode = TCODE_ISO_DATA; -} - static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) { packet->header[0] = data; @@ -491,24 +479,6 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data) return p; } -struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, - int length, int channel, - int tag, int sync) -{ - struct hpsb_packet *p; - - p = hpsb_alloc_packet(length); - if (!p) - return NULL; - - p->host = host; - fill_iso_packet(p, length, channel, tag, sync); - - p->generation = get_hpsb_generation(host); - - return p; -} - /* * FIXME - these functions should probably read from / write to user space to * avoid in kernel buffers for user space callers diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 86b8ee692ea7..d2d5bc3546d7 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h @@ -19,8 +19,6 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, octlet_t *data, octlet_t arg); struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data); -struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length, - int channel, int tag, int sync); struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length); diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index a75b1446b6ed..5667c8102efc 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -157,7 +157,6 @@ static void dma_trm_reset(struct dma_trm_ctx *d); static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, enum context_type type, int ctx, int num_desc, int buf_size, int split_buf_size, int context_base); -static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d); static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, @@ -520,9 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci) initialize_dma_trm_ctx(&ohci->at_req_context); initialize_dma_trm_ctx(&ohci->at_resp_context); - /* Initialize IR Legacy DMA channel mask */ - ohci->ir_legacy_channels = 0; - /* Accept AR requests from all nodes */ reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); @@ -869,36 +865,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) return -EOVERFLOW; } - /* Decide whether we have an iso, a request, or a response packet */ if (packet->type == hpsb_raw) d = &ohci->at_req_context; - else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) { - /* The legacy IT DMA context is initialized on first - * use. However, the alloc cannot be run from - * interrupt context, so we bail out if that is the - * case. I don't see anyone sending ISO packets from - * interrupt context anyway... */ - - if (ohci->it_legacy_context.ohci == NULL) { - if (in_interrupt()) { - PRINT(KERN_ERR, - "legacy IT context cannot be initialized during interrupt"); - return -EINVAL; - } - - if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context, - DMA_CTX_ISO, 0, IT_NUM_DESC, - OHCI1394_IsoXmitContextBase) < 0) { - PRINT(KERN_ERR, - "error initializing legacy IT context"); - return -ENOMEM; - } - - initialize_dma_trm_ctx(&ohci->it_legacy_context); - } - - d = &ohci->it_legacy_context; - } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) + else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) d = &ohci->at_resp_context; else d = &ohci->at_req_context; @@ -917,9 +886,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) { struct ti_ohci *ohci = host->hostdata; - int retval = 0; - unsigned long flags; - int phy_reg; + int retval = 0, phy_reg; switch (cmd) { case RESET_BUS: @@ -1012,117 +979,6 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) dma_trm_reset(&ohci->at_resp_context); break; - case ISO_LISTEN_CHANNEL: - { - u64 mask; - struct dma_rcv_ctx *d = &ohci->ir_legacy_context; - int ir_legacy_active; - - if (arg<0 || arg>63) { - PRINT(KERN_ERR, - "%s: IS0 listen channel %d is out of range", - __FUNCTION__, arg); - return -EFAULT; - } - - mask = (u64)0x1<IR_channel_lock, flags); - - if (ohci->ISO_channel_usage & mask) { - PRINT(KERN_ERR, - "%s: IS0 listen channel %d is already used", - __FUNCTION__, arg); - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - return -EFAULT; - } - - ir_legacy_active = ohci->ir_legacy_channels; - - ohci->ISO_channel_usage |= mask; - ohci->ir_legacy_channels |= mask; - - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - - if (!ir_legacy_active) { - if (ohci1394_register_iso_tasklet(ohci, - &ohci->ir_legacy_tasklet) < 0) { - PRINT(KERN_ERR, "No IR DMA context available"); - return -EBUSY; - } - - /* the IR context can be assigned to any DMA context - * by ohci1394_register_iso_tasklet */ - d->ctx = ohci->ir_legacy_tasklet.context; - d->ctrlSet = OHCI1394_IsoRcvContextControlSet + - 32*d->ctx; - d->ctrlClear = OHCI1394_IsoRcvContextControlClear + - 32*d->ctx; - d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx; - d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx; - - initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1); - - if (printk_ratelimit()) - DBGMSG("IR legacy activated"); - } - - spin_lock_irqsave(&ohci->IR_channel_lock, flags); - - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, - 1<<(arg-32)); - else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet, - 1<IR_channel_lock, flags); - DBGMSG("Listening enabled on channel %d", arg); - break; - } - case ISO_UNLISTEN_CHANNEL: - { - u64 mask; - - if (arg<0 || arg>63) { - PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is out of range", - __FUNCTION__, arg); - return -EFAULT; - } - - mask = (u64)0x1<IR_channel_lock, flags); - - if (!(ohci->ISO_channel_usage & mask)) { - PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is not used", - __FUNCTION__, arg); - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - return -EFAULT; - } - - ohci->ISO_channel_usage &= ~mask; - ohci->ir_legacy_channels &= ~mask; - - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, - 1<<(arg-32)); - else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, - 1<IR_channel_lock, flags); - DBGMSG("Listening disabled on channel %d", arg); - - if (ohci->ir_legacy_channels == 0) { - stop_dma_rcv_ctx(&ohci->ir_legacy_context); - DBGMSG("ISO legacy receive context stopped"); - } - - break; - } default: PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet", cmd); @@ -2868,22 +2724,6 @@ static void dma_trm_tasklet (unsigned long data) spin_unlock_irqrestore(&d->lock, flags); } -static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d) -{ - if (d->ctrlClear) { - ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); - - if (d->type == DMA_CTX_ISO) { - /* disable interrupts */ - reg_write(d->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << d->ctx); - ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_legacy_tasklet); - } else { - tasklet_kill(&d->task); - } - } -} - - static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) { int i; @@ -3005,18 +2845,11 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, spin_lock_init(&d->lock); - if (type == DMA_CTX_ISO) { - ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, - OHCI_ISO_MULTICHANNEL_RECEIVE, - dma_rcv_tasklet, (unsigned long) d); - } else { - d->ctrlSet = context_base + OHCI1394_ContextControlSet; - d->ctrlClear = context_base + OHCI1394_ContextControlClear; - d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; - - tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d); - } + d->ctrlSet = context_base + OHCI1394_ContextControlSet; + d->ctrlClear = context_base + OHCI1394_ContextControlClear; + d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; + tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d); return 0; } @@ -3097,28 +2930,10 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, spin_lock_init(&d->lock); /* initialize tasklet */ - if (type == DMA_CTX_ISO) { - ohci1394_init_iso_tasklet(&ohci->it_legacy_tasklet, OHCI_ISO_TRANSMIT, - dma_trm_tasklet, (unsigned long) d); - if (ohci1394_register_iso_tasklet(ohci, - &ohci->it_legacy_tasklet) < 0) { - PRINT(KERN_ERR, "No IT DMA context available"); - free_dma_trm_ctx(d); - return -EBUSY; - } - - /* IT can be assigned to any context by register_iso_tasklet */ - d->ctx = ohci->it_legacy_tasklet.context; - d->ctrlSet = OHCI1394_IsoXmitContextControlSet + 16 * d->ctx; - d->ctrlClear = OHCI1394_IsoXmitContextControlClear + 16 * d->ctx; - d->cmdPtr = OHCI1394_IsoXmitCommandPtr + 16 * d->ctx; - } else { - d->ctrlSet = context_base + OHCI1394_ContextControlSet; - d->ctrlClear = context_base + OHCI1394_ContextControlClear; - d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; - tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d); - } - + d->ctrlSet = context_base + OHCI1394_ContextControlSet; + d->ctrlClear = context_base + OHCI1394_ContextControlClear; + d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; + tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d); return 0; } @@ -3344,20 +3159,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->ISO_channel_usage = 0; spin_lock_init(&ohci->IR_channel_lock); - /* Allocate the IR DMA context right here so we don't have - * to do it in interrupt path - note that this doesn't - * waste much memory and avoids the jugglery required to - * allocate it in IRQ path. */ - if (alloc_dma_rcv_ctx(ohci, &ohci->ir_legacy_context, - DMA_CTX_ISO, 0, IR_NUM_DESC, - IR_BUF_SIZE, IR_SPLIT_BUF_SIZE, - OHCI1394_IsoRcvContextBase) < 0) { - FAIL(-ENOMEM, "Cannot allocate IR Legacy DMA context"); - } - - /* We hopefully don't have to pre-allocate IT DMA like we did - * for IR DMA above. Allocate it on-demand and mark inactive. */ - ohci->it_legacy_context.ohci = NULL; spin_lock_init(&ohci->event_lock); /* @@ -3450,8 +3251,6 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) free_dma_rcv_ctx(&ohci->ar_resp_context); free_dma_trm_ctx(&ohci->at_req_context); free_dma_trm_ctx(&ohci->at_resp_context); - free_dma_rcv_ctx(&ohci->ir_legacy_context); - free_dma_trm_ctx(&ohci->it_legacy_context); case OHCI_INIT_HAVE_SELFID_BUFFER: pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h index f1ad539e7c1b..4320bf010495 100644 --- a/drivers/ieee1394/ohci1394.h +++ b/drivers/ieee1394/ohci1394.h @@ -190,23 +190,10 @@ struct ti_ohci { unsigned long ir_multichannel_used; /* ditto */ spinlock_t IR_channel_lock; - /* iso receive (legacy API) */ - u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage; - it only accounts for channels listened to - by the legacy API, so that we can know when - it is safe to free the legacy API context */ - - struct dma_rcv_ctx ir_legacy_context; - struct ohci1394_iso_tasklet ir_legacy_tasklet; - /* iso transmit */ int nb_iso_xmit_ctx; unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ - /* iso transmit (legacy API) */ - struct dma_trm_ctx it_legacy_context; - struct ohci1394_iso_tasklet it_legacy_tasklet; - u64 ISO_channel_usage; /* IEEE-1394 part follows */ @@ -221,7 +208,6 @@ struct ti_ohci { /* Tasklets for iso receive and transmit, used by video1394 * and dv1394 */ - struct list_head iso_tasklet_list; spinlock_t iso_tasklet_list_lock; diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 0742befe9227..d1a5bcdb5e0b 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -477,7 +477,11 @@ static void send_next(struct ti_lynx *lynx, int what) struct lynx_send_data *d; struct hpsb_packet *packet; +#if 0 /* has been removed from ieee1394 core */ d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async); +#else + d = &lynx->async; +#endif if (!list_empty(&d->pcl_queue)) { PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo"); BUG(); @@ -511,9 +515,11 @@ static void send_next(struct ti_lynx *lynx, int what) case hpsb_async: pcl.buffer[0].control |= PCL_CMD_XMT; break; +#if 0 /* has been removed from ieee1394 core */ case hpsb_iso: pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; break; +#endif case hpsb_raw: pcl.buffer[0].control |= PCL_CMD_UNFXMT; break; @@ -542,9 +548,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet) case hpsb_raw: d = &lynx->async; break; +#if 0 /* has been removed from ieee1394 core */ case hpsb_iso: d = &lynx->iso_send; break; +#endif default: PRINT(KERN_ERR, lynx->id, "invalid packet type %d", packet->type); @@ -797,7 +805,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) } break; - +#if 0 /* has been removed from ieee1394 core */ case ISO_LISTEN_CHANNEL: spin_lock_irqsave(&lynx->iso_rcv.lock, flags); @@ -819,7 +827,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags); break; - +#endif default: PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd); retval = -1; @@ -1009,11 +1017,11 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id) pci_unmap_single(lynx->dev, lynx->iso_send.data_dma, packet->data_size, PCI_DMA_TODEVICE); } - +#if 0 /* has been removed from ieee1394 core */ if (!list_empty(&lynx->iso_send.queue)) { send_next(lynx, hpsb_iso); } - +#endif spin_unlock(&lynx->iso_send.queue_lock); if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) { diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h index 50daabf6e5fa..a06aaad5b448 100644 --- a/drivers/ieee1394/raw1394-private.h +++ b/drivers/ieee1394/raw1394-private.h @@ -36,11 +36,6 @@ struct file_info { u8 __user *fcp_buffer; - /* old ISO API */ - u64 listen_channels; - quadlet_t __user *iso_buffer; - size_t iso_buffer_length; - u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ /* new rawiso API */ diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 1dadd5a15ba1..336e5ff4cfcf 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = { static void queue_complete_cb(struct pending_request *req); -#include -static void print_old_iso_deprecation(void) -{ - static pid_t p; - - if (p == current->pid) - return; - p = current->pid; - printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported" - " isochronous request types which will be removed in a next" - " kernel release\n", current->comm); - printk(KERN_WARNING "raw1394: Update your software to use libraw1394's" - " newer interface\n"); -} - static struct pending_request *__alloc_pending_request(gfp_t flags) { struct pending_request *req; @@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host) spin_unlock_irqrestore(&host_info_lock, flags); } -static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, - size_t length) -{ - unsigned long flags; - struct host_info *hi; - struct file_info *fi; - struct pending_request *req, *req_next; - struct iso_block_store *ibs = NULL; - LIST_HEAD(reqs); - - if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) { - HPSB_INFO("dropped iso packet"); - return; - } - - spin_lock_irqsave(&host_info_lock, flags); - hi = find_host_info(host); - - if (hi != NULL) { - list_for_each_entry(fi, &hi->file_info_list, list) { - if (!(fi->listen_channels & (1ULL << channel))) - continue; - - req = __alloc_pending_request(GFP_ATOMIC); - if (!req) - break; - - if (!ibs) { - ibs = kmalloc(sizeof(*ibs) + length, - GFP_ATOMIC); - if (!ibs) { - kfree(req); - break; - } - - atomic_add(length, &iso_buffer_size); - atomic_set(&ibs->refcount, 0); - ibs->data_size = length; - memcpy(ibs->data, data, length); - } - - atomic_inc(&ibs->refcount); - - req->file_info = fi; - req->ibs = ibs; - req->data = ibs->data; - req->req.type = RAW1394_REQ_ISO_RECEIVE; - req->req.generation = get_hpsb_generation(host); - req->req.misc = 0; - req->req.recvb = ptr2int(fi->iso_buffer); - req->req.length = min(length, fi->iso_buffer_length); - - list_add_tail(&req->list, &reqs); - } - } - spin_unlock_irqrestore(&host_info_lock, flags); - - list_for_each_entry_safe(req, req_next, &reqs, list) - queue_complete_req(req); -} - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, int cts, u8 * data, size_t length) { @@ -680,43 +604,6 @@ out_set_card: return 0; } -static void handle_iso_listen(struct file_info *fi, struct pending_request *req) -{ - int channel = req->req.misc; - - if ((channel > 63) || (channel < -64)) { - req->req.error = RAW1394_ERROR_INVALID_ARG; - } else if (channel >= 0) { - /* allocate channel req.misc */ - if (fi->listen_channels & (1ULL << channel)) { - req->req.error = RAW1394_ERROR_ALREADY; - } else { - if (hpsb_listen_channel - (&raw1394_highlevel, fi->host, channel)) { - req->req.error = RAW1394_ERROR_ALREADY; - } else { - fi->listen_channels |= 1ULL << channel; - fi->iso_buffer = int2ptr(req->req.recvb); - fi->iso_buffer_length = req->req.length; - } - } - } else { - /* deallocate channel (one's complement neg) req.misc */ - channel = ~channel; - - if (fi->listen_channels & (1ULL << channel)) { - hpsb_unlisten_channel(&raw1394_highlevel, fi->host, - channel); - fi->listen_channels &= ~(1ULL << channel); - } else { - req->req.error = RAW1394_ERROR_INVALID_ARG; - } - } - - req->req.length = 0; - queue_complete_req(req); -} - static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) { if (req->req.misc) { @@ -890,50 +777,6 @@ static int handle_async_request(struct file_info *fi, return 0; } -static int handle_iso_send(struct file_info *fi, struct pending_request *req, - int channel) -{ - unsigned long flags; - struct hpsb_packet *packet; - - packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, - (req->req.misc >> 16) & 0x3, - req->req.misc & 0xf); - if (!packet) - return -ENOMEM; - - packet->speed_code = req->req.address & 0x3; - - req->packet = packet; - - if (copy_from_user(packet->data, int2ptr(req->req.sendb), - req->req.length)) { - req->req.error = RAW1394_ERROR_MEMFAULT; - req->req.length = 0; - queue_complete_req(req); - return 0; - } - - req->req.length = 0; - hpsb_set_packet_complete_task(packet, - (void (*)(void *))queue_complete_req, - req); - - spin_lock_irqsave(&fi->reqlists_lock, flags); - list_add_tail(&req->list, &fi->req_pending); - spin_unlock_irqrestore(&fi->reqlists_lock, flags); - - /* Update the generation of the packet just before sending. */ - packet->generation = req->req.generation; - - if (hpsb_send_packet(packet) < 0) { - req->req.error = RAW1394_ERROR_SEND_ERROR; - queue_complete_req(req); - } - - return 0; -} - static int handle_async_send(struct file_info *fi, struct pending_request *req) { unsigned long flags; @@ -2317,10 +2160,6 @@ static int state_connected(struct file_info *fi, struct pending_request *req) queue_complete_req(req); return 0; - case RAW1394_REQ_ISO_SEND: - print_old_iso_deprecation(); - return handle_iso_send(fi, req, node); - case RAW1394_REQ_ARM_REGISTER: return arm_register(fi, req); @@ -2336,9 +2175,12 @@ static int state_connected(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_RESET_NOTIFY: return reset_notification(fi, req); + case RAW1394_REQ_ISO_SEND: case RAW1394_REQ_ISO_LISTEN: - print_old_iso_deprecation(); - handle_iso_listen(fi, req); + printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n"); + req->req.error = RAW1394_ERROR_COMPAT; + req->req.misc = RAW1394_KERNELAPI_VERSION; + queue_complete_req(req); return 0; case RAW1394_REQ_FCP_LISTEN: @@ -2965,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file) if (fi->iso_state != RAW1394_ISO_INACTIVE) raw1394_iso_shutdown(fi); - for (i = 0; i < 64; i++) { - if (fi->listen_channels & (1ULL << i)) { - hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i); - } - } - spin_lock_irqsave(&host_info_lock, flags); - fi->listen_channels = 0; fail = 0; /* set address-entries invalid */ @@ -3134,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = { .add_host = add_host, .remove_host = remove_host, .host_reset = host_reset, - .iso_receive = iso_receive, .fcp_request = fcp_request, }; diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h index 7bd22ee1afbb..963ac20373d2 100644 --- a/drivers/ieee1394/raw1394.h +++ b/drivers/ieee1394/raw1394.h @@ -17,11 +17,11 @@ #define RAW1394_REQ_ASYNC_WRITE 101 #define RAW1394_REQ_LOCK 102 #define RAW1394_REQ_LOCK64 103 -#define RAW1394_REQ_ISO_SEND 104 +#define RAW1394_REQ_ISO_SEND 104 /* removed ABI, now a no-op */ #define RAW1394_REQ_ASYNC_SEND 105 #define RAW1394_REQ_ASYNC_STREAM 106 -#define RAW1394_REQ_ISO_LISTEN 200 +#define RAW1394_REQ_ISO_LISTEN 200 /* removed ABI, now a no-op */ #define RAW1394_REQ_FCP_LISTEN 201 #define RAW1394_REQ_RESET_BUS 202 #define RAW1394_REQ_GET_ROM 203 From b8f106570f20a7a98a18a14c2d11d65f581c2808 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 11 May 2007 23:04:08 +0200 Subject: [PATCH 329/551] firewire: fw-sbp2: remove unused struct member cleanup after support of single-buffer requests was dropped Signed-off-by: Stefan Richter Signed-off-by: Kristian Hoegsberg --- drivers/firewire/fw-sbp2.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a98d3915e26f..25f2aa430a30 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -207,7 +207,6 @@ struct sbp2_command_orb { struct sbp2_pointer page_table[SG_ALL]; dma_addr_t page_table_bus; - dma_addr_t request_buffer_bus; }; /* @@ -882,11 +881,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) dma_unmap_single(device->card->device, orb->page_table_bus, sizeof(orb->page_table_bus), DMA_TO_DEVICE); - if (orb->request_buffer_bus != 0) - dma_unmap_single(device->card->device, orb->request_buffer_bus, - sizeof(orb->request_buffer_bus), - DMA_FROM_DEVICE); - orb->cmd->result = result; orb->done(orb->cmd); kfree(orb); From 8a8cea2734808522f02941ea16125810ee42c9c7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 9 Jun 2007 19:26:22 +0200 Subject: [PATCH 330/551] firewire: missing newline in printk Also remove some errno printouts which will be shown by infrastructure code anyway. Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 6 +++--- drivers/firewire/fw-sbp2.c | 2 +- drivers/firewire/fw-topology.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 96c8ac5b86cc..41476abc0693 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -1934,12 +1934,12 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state) free_irq(pdev->irq, ohci); err = pci_save_state(pdev); if (err) { - fw_error("pci_save_state failed with %d", err); + fw_error("pci_save_state failed\n"); return err; } err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); if (err) { - fw_error("pci_set_power_state failed with %d", err); + fw_error("pci_set_power_state failed\n"); return err; } @@ -1955,7 +1955,7 @@ static int pci_resume(struct pci_dev *pdev) pci_restore_state(pdev); err = pci_enable_device(pdev); if (err) { - fw_error("pci_enable_device failed with %d", err); + fw_error("pci_enable_device failed\n"); return err; } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 25f2aa430a30..16e942f72e48 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -985,7 +985,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) * transfer direction not handled. */ if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { - fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command"); + fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n"); cmd->result = DID_ERROR << 16; done(cmd); return 0; diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 7aebb8ae0efa..4e358506d913 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -214,7 +214,7 @@ static struct fw_node *build_tree(struct fw_card *card, node = fw_node_create(q, port_count, card->color); if (node == NULL) { - fw_error("Out of memory while building topology."); + fw_error("Out of memory while building topology.\n"); return NULL; } From 25d83f583b334ac671fbb905c97c374ba34a597a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 9 Jun 2007 19:27:07 +0200 Subject: [PATCH 331/551] firewire: remove unused macro Signed-off-by: Stefan Richter --- drivers/firewire/fw-transaction.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index acdc3be38c61..f54eee4e3803 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -81,7 +81,6 @@ #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) -#define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args) static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) From 24d40125f1f59a6de9d9e6e046676bd60532596c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 18 Jun 2007 19:44:12 +0200 Subject: [PATCH 332/551] firewire: optimize gap count with 1394b leaf nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Table-based gap count optimization cannot be used if 1394b repeater PHYs are present. But it does work with 1394b leaf nodes. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-card.c | 7 +++++-- drivers/firewire/fw-topology.c | 16 ++++++++-------- drivers/firewire/fw-topology.h | 6 ------ drivers/firewire/fw-transaction.h | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 9eb1edacd825..0aeab3218bb6 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -336,8 +336,11 @@ fw_card_bm_work(struct work_struct *work) } pick_me: - /* Now figure out what gap count to set. */ - if (card->topology_type == FW_TOPOLOGY_A && + /* + * Pick a gap count from 1394a table E-1. The table doesn't cover + * the typically much larger 1394b beta repeater delays though. + */ + if (!card->beta_repeaters_present && card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) gap_count = gap_count_table[card->root_node->max_hops]; else diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 4e358506d913..77e3f8276007 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card, struct list_head stack, *h; u32 *next_sid, *end, q; int i, port_count, child_port_count, phy_id, parent_count, stack_depth; - int gap_count, topology_type; + int gap_count; + bool beta_repeaters_present; local_node = NULL; node = NULL; @@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card, phy_id = 0; irm_node = NULL; gap_count = SELF_ID_GAP_COUNT(*sid); - topology_type = 0; + beta_repeaters_present = false; while (sid < end) { next_sid = count_ports(sid, &port_count, &child_port_count); @@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card, if (SELF_ID_CONTENDER(q)) irm_node = node; - if (node->phy_speed == SCODE_BETA) - topology_type |= FW_TOPOLOGY_B; - else - topology_type |= FW_TOPOLOGY_A; - parent_count = 0; for (i = 0; i < port_count; i++) { @@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card, list_add_tail(&node->link, &stack); stack_depth += 1 - child_port_count; + if (node->phy_speed == SCODE_BETA && + parent_count + child_port_count > 1) + beta_repeaters_present = true; + /* * If all PHYs does not report the same gap count * setting, we fall back to 63 which will force a gap @@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card, card->root_node = node; card->irm_node = irm_node; card->gap_count = gap_count; - card->topology_type = topology_type; + card->beta_repeaters_present = beta_repeaters_present; return local_node; } diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index 363b6cbcd0b3..aced9f7db358 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -19,12 +19,6 @@ #ifndef __fw_topology_h #define __fw_topology_h -enum { - FW_TOPOLOGY_A = 0x01, - FW_TOPOLOGY_B = 0x02, - FW_TOPOLOGY_MIXED = 0x03, -}; - enum { FW_NODE_CREATED = 0x00, FW_NODE_UPDATED = 0x01, diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index f54eee4e3803..5abed193f4a6 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -245,7 +245,7 @@ struct fw_card { struct fw_node *irm_node; int color; int gap_count; - int topology_type; + bool beta_repeaters_present; int index; From f1397490017e337446c6a8b0562b584679a604a6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 10 Jun 2007 21:31:36 +0200 Subject: [PATCH 333/551] firewire: support S100B...S400B and link slower than PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a speed probe to determine the speed over 1394b buses and of nodes which report a link speed less than their PHY speed. Log the effective maximum speed of newly created nodes in dmesg. Also, read the config ROM (except bus info block) at the maximum speed rather than S100. This isn't a real optimization though because we still only use quadlet read requests for the entire ROM. The patch also adds support for S1600 and S3200, although such hardware does not exist yet. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-cdev.c | 2 +- drivers/firewire/fw-device.c | 38 ++++++++++++++++++++++++++++++---- drivers/firewire/fw-device.h | 1 + drivers/firewire/fw-sbp2.c | 7 +++---- drivers/firewire/fw-topology.h | 13 ++++++------ 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dbb76427d529..75388641a7d3 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer) request->tcode & 0x1f, device->node->node_id, request->generation, - device->node->max_speed, + device->max_speed, request->offset, response->response.data, request->length, complete_transaction, response); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index c1ce465d9710..2b6586341635 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data) offset = 0xfffff0000400ULL + index * 4; fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, - device->node_id, - device->generation, SCODE_100, + device->node_id, device->generation, device->max_speed, offset, NULL, 4, complete_transaction, &callback_data); wait_for_completion(&callback_data.done); @@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device) u32 stack[16], sp, key; int i, end, length; + device->max_speed = SCODE_100; + /* First read the bus info block. */ for (i = 0; i < 5; i++) { if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) @@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device) return -1; } + device->max_speed = device->node->max_speed; + + /* + * Determine the speed of + * - devices with link speed less than PHY speed, + * - devices with 1394b PHY (unless only connected to 1394a PHYs), + * - all devices if there are 1394b repeaters. + * Note, we cannot use the bus info block's link_spd as starting point + * because some buggy firmwares set it lower than necessary and because + * 1394-1995 nodes do not have the field. + */ + if ((rom[2] & 0x7) < device->max_speed || + device->max_speed == SCODE_BETA || + device->card->beta_repeaters_present) { + u32 dummy; + + /* for S1600 and S3200 */ + if (device->max_speed == SCODE_BETA) + device->max_speed = device->card->link_speed; + + while (device->max_speed > SCODE_100) { + if (read_rom(device, 0, &dummy) == RCODE_COMPLETE) + break; + device->max_speed--; + } + } + /* * Now parse the config rom. The config rom is a recursive * directory structure so we parse it using a stack of @@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work) FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) fw_device_shutdown(&device->work.work); else - fw_notify("created new fw device %s (%d config rom retries)\n", - device->device.bus_id, device->config_rom_retries); + fw_notify("created new fw device %s " + "(%d config rom retries, S%d00)\n", + device->device.bus_id, device->config_rom_retries, + 1 << device->max_speed); /* * Reschedule the IRM work if we just finished reading the diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index af1723eae4ba..d13e6a69707f 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -40,6 +40,7 @@ struct fw_device { struct fw_node *node; int node_id; int generation; + unsigned max_speed; struct fw_card *card; struct device device; struct list_head link; diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 16e942f72e48..851c2da060d2 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -346,8 +346,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, spin_unlock_irqrestore(&device->card->lock, flags); fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, - node_id, generation, - device->node->max_speed, offset, + node_id, generation, device->max_speed, offset, &orb->pointer, sizeof(orb->pointer), complete_transaction, orb); } @@ -1018,8 +1017,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) * if we set this to max_speed + 7, we get the right value. */ orb->request.misc = - COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | - COMMAND_ORB_SPEED(device->node->max_speed) | + COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) | + COMMAND_ORB_SPEED(device->max_speed) | COMMAND_ORB_NOTIFY; if (cmd->sc_data_direction == DMA_FROM_DEVICE) diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index aced9f7db358..da61ec09183e 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -29,19 +29,18 @@ enum { struct fw_port { struct fw_node *node; - unsigned speed : 3; /* S100, S200, ... S3200 */ }; struct fw_node { u16 node_id; u8 color; u8 port_count; - unsigned link_on : 1; - unsigned initiated_reset : 1; - unsigned b_path : 1; - u8 phy_speed : 3; /* As in the self ID packet. */ - u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on - * the path from the local node to this node. */ + u8 link_on : 1; + u8 initiated_reset : 1; + u8 b_path : 1; + u8 phy_speed : 2; /* As in the self ID packet. */ + u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the + * local node to this node. */ u8 max_depth : 4; /* Maximum depth to any leaf node */ u8 max_hops : 4; /* Max hops in this sub tree */ atomic_t ref_count; From dae1a3aa8ebdd30fbba56a8d4e22f92455fb0861 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:39:58 +0200 Subject: [PATCH 334/551] firewire: simplify a struct type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cleanup after "firewire: support S100B...S400B and link slower than PHY" Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-topology.c | 48 ++++++++++++++++------------------ drivers/firewire/fw-topology.h | 6 +---- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 77e3f8276007..39e5cd12aa52 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node) int i; for (i = 0; i < node->port_count; i++) { - if (node->ports[i].node == NULL) + if (node->ports[i] == NULL) continue; - if (node->ports[i].node->max_hops > max_child_hops) - max_child_hops = node->ports[i].node->max_hops; + if (node->ports[i]->max_hops > max_child_hops) + max_child_hops = node->ports[i]->max_hops; - if (node->ports[i].node->max_depth > depths[0]) { + if (node->ports[i]->max_depth > depths[0]) { depths[1] = depths[0]; - depths[0] = node->ports[i].node->max_depth; - } else if (node->ports[i].node->max_depth > depths[1]) - depths[1] = node->ports[i].node->max_depth; + depths[0] = node->ports[i]->max_depth; + } else if (node->ports[i]->max_depth > depths[1]) + depths[1] = node->ports[i]->max_depth; } node->max_depth = depths[0] + 1; @@ -245,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card, break; case SELFID_PORT_CHILD: - node->ports[i].node = child; + node->ports[i] = child; /* * Fix up parent reference for this * child node. */ - child->ports[child->color].node = node; + child->ports[child->color] = node; child->color = card->color; child = fw_node(child->link.next); break; @@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root, node->color = card->color; for (i = 0; i < node->port_count; i++) { - child = node->ports[i].node; + child = node->ports[i]; if (!child) continue; if (child->color == card->color) @@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) struct fw_node *tree; int i; - tree = node1->ports[port].node; - node0->ports[port].node = tree; + tree = node1->ports[port]; + node0->ports[port] = tree; for (i = 0; i < tree->port_count; i++) { - if (tree->ports[i].node == node1) { - tree->ports[i].node = node0; + if (tree->ports[i] == node1) { + tree->ports[i] = node0; break; } } @@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root) card->irm_node = node0; for (i = 0; i < node0->port_count; i++) { - if (node0->ports[i].node && node1->ports[i].node) { + if (node0->ports[i] && node1->ports[i]) { /* * This port didn't change, queue the * connected node for further * investigation. */ - if (node0->ports[i].node->color == card->color) + if (node0->ports[i]->color == card->color) continue; - list_add_tail(&node0->ports[i].node->link, - &list0); - list_add_tail(&node1->ports[i].node->link, - &list1); - } else if (node0->ports[i].node) { + list_add_tail(&node0->ports[i]->link, &list0); + list_add_tail(&node1->ports[i]->link, &list1); + } else if (node0->ports[i]) { /* * The nodes connected here were * unplugged; unref the lost nodes and @@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root) * them. */ - for_each_fw_node(card, node0->ports[i].node, + for_each_fw_node(card, node0->ports[i], report_lost_node); - node0->ports[i].node = NULL; - } else if (node1->ports[i].node) { + node0->ports[i] = NULL; + } else if (node1->ports[i]) { /* * One or more node were connected to * this port. Move the new nodes into @@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root) * callbacks for them. */ move_tree(node0, node1, i); - for_each_fw_node(card, node0->ports[i].node, + for_each_fw_node(card, node0->ports[i], report_found_node); } } diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index da61ec09183e..1b56b4ac7fb2 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h @@ -27,10 +27,6 @@ enum { FW_NODE_LINK_OFF = 0x04, }; -struct fw_port { - struct fw_node *node; -}; - struct fw_node { u16 node_id; u8 color; @@ -51,7 +47,7 @@ struct fw_node { /* Upper layer specific data. */ void *data; - struct fw_port ports[0]; + struct fw_node *ports[0]; }; static inline struct fw_node * From cf47c7a26ca13b944900dce208890c5b6d5f3a14 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:52:08 +0200 Subject: [PATCH 335/551] firewire: fw-sbp2: implement max sectors limit for some old bridges This currently only affects one bridge in the hardwired blacklist. I don't own one of those, hence haven't tested it. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 851c2da060d2..49f7fd52ae87 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1080,7 +1081,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) fw_notify("setting fix_capacity for %s\n", unit->device.bus_id); sdev->fix_capacity = 1; } - + if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) + blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); return 0; } From 79352e9f94cff4078f2ffefac4a41b7f14046fb6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 18 Jun 2007 18:46:49 +0200 Subject: [PATCH 336/551] firewire: fw-sbp2: let SCSI shutdown commands through before logout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This affects of course only the "soft shutdown" case, e.g. "modprobe -r firewire-sbp2", while it doesn't matter for hot unplug. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 49f7fd52ae87..846aad8666f5 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -520,17 +520,15 @@ static int sbp2_agent_reset(struct fw_unit *unit) static void sbp2_reconnect(struct work_struct *work); static struct scsi_host_template scsi_driver_template; -static void -release_sbp2_device(struct kref *kref) +static void release_sbp2_device(struct kref *kref) { struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref); struct Scsi_Host *host = container_of((void *)sd, struct Scsi_Host, hostdata[0]); + scsi_remove_host(host); sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation, SBP2_LOGOUT_REQUEST, sd->login_id, NULL); - - scsi_remove_host(host); fw_core_remove_address_handler(&sd->address_handler); fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id); put_device(&sd->unit->device); From 5cd54c94b0ba45033c126237d3d70c6e7ab52c3f Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Jun 2007 23:55:41 +0200 Subject: [PATCH 337/551] firewire: fw-sbp2: implement nonexclusive login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 846aad8666f5..2c39f19a9ee1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,18 @@ #include "fw-topology.h" #include "fw-device.h" +/* + * So far only bridges from Oxford Semiconductor are known to support + * concurrent logins. Depending on firmware, four or two concurrent logins + * are possible on OXFW911 and newer Oxsemi bridges. + * + * Concurrent logins are useful together with cluster filesystems. + */ +static int sbp2_param_exclusive_login = 1; +module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644); +MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " + "(default = Y, use N for concurrent initiators)"); + /* I don't know why the SCSI stack doesn't define something like this... */ typedef void (*scsi_done_fn_t)(struct scsi_cmnd *); @@ -155,7 +168,7 @@ struct sbp2_orb { #define MANAGEMENT_ORB_LUN(v) ((v)) #define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) #define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) -#define MANAGEMENT_ORB_EXCLUSIVE ((1) << 28) +#define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) #define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) #define MANAGEMENT_ORB_NOTIFY ((1) << 31) @@ -431,14 +444,9 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, orb->request.status_fifo.high = sd->address_handler.offset >> 32; orb->request.status_fifo.low = sd->address_handler.offset; - /* - * FIXME: Yeah, ok this isn't elegant, we hardwire exclusive - * login and 1 second reconnect time. The reconnect setting - * is probably fine, but the exclusive login should be an option. - */ if (function == SBP2_LOGIN_REQUEST) { orb->request.misc |= - MANAGEMENT_ORB_EXCLUSIVE | + MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) | MANAGEMENT_ORB_RECONNECT(0); } From 7ada60e367640fa8a4a349d9b105f235f346238b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 22 Jun 2007 00:20:34 +0200 Subject: [PATCH 338/551] firewire: Document userspace ioctl interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The isochronous packet format is still not documented, but this is a good first step. Signed-off-by: Kristian Høgsberg Signed-off-by: Stefan Richter (format, wording) --- include/linux/firewire-cdev.h | 297 ++++++++++++++++++++++++++++++---- 1 file changed, 264 insertions(+), 33 deletions(-) diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index efbe1fda1a22..1a45d6f41b09 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -30,16 +30,38 @@ #define FW_CDEV_EVENT_REQUEST 0x02 #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 -/* The 'closure' fields are for user space to use. Data passed in the - * 'closure' field for a request will be returned in the corresponding - * event. It's a 64-bit type so that it's a fixed size type big - * enough to hold a pointer on all platforms. */ - +/** + * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types + * @closure: For arbitrary use by userspace + * @type: Discriminates the fw_cdev_event_ types + * + * This struct may be used to access generic members of all fw_cdev_event_ + * types regardless of the specific type. + * + * Data passed in the @closure field for a request will be returned in the + * corresponding event. It is big enough to hold a pointer on all platforms. + * The ioctl used to set @closure depends on the @type of event. + */ struct fw_cdev_event_common { __u64 closure; __u32 type; }; +/** + * struct fw_cdev_event_bus_reset - Sent when a bus reset occurred + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_GET_INFO ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_BUS_RESET + * @node_id: New node ID of this node + * @local_node_id: Node ID of the local node, i.e. of the controller + * @bm_node_id: Node ID of the bus manager + * @irm_node_id: Node ID of the iso resource manager + * @root_node_id: Node ID of the root node + * @generation: New bus generation + * + * This event is sent when the bus the device belongs to goes through a bus + * reset. It provides information about the new bus configuration, such as + * new node ID for this device, new root ID, and others. + */ struct fw_cdev_event_bus_reset { __u64 closure; __u32 type; @@ -51,6 +73,20 @@ struct fw_cdev_event_bus_reset { __u32 generation; }; +/** + * struct fw_cdev_event_response - Sent when a response packet was received + * @closure: See &fw_cdev_event_common; + * set by %FW_CDEV_IOC_SEND_REQUEST ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE + * @rcode: Response code returned by the remote node + * @length: Data length, i.e. the response's payload size in bytes + * @data: Payload data, if any + * + * This event is sent when the stack receives a response to an outgoing request + * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses + * carrying data (read and lock responses) follows immediately and can be + * accessed through the @data field. + */ struct fw_cdev_event_response { __u64 closure; __u32 type; @@ -59,6 +95,25 @@ struct fw_cdev_event_response { __u32 data[0]; }; +/** + * struct fw_cdev_event_request - Sent on incoming request to an address region + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST + * @tcode: Transaction code of the incoming request + * @offset: The offset into the 48-bit per-node address space + * @handle: Reference to the kernel-side pending request + * @length: Data length, i.e. the request's payload size in bytes + * @data: Incoming data, if any + * + * This event is sent when the stack receives an incoming request to an address + * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is + * guaranteed to be completely contained in the specified region. Userspace is + * responsible for sending the response by %FW_CDEV_IOC_SEND_RESPONSE ioctl, + * using the same @handle. + * + * The payload data for requests carrying data (write and lock requests) + * follows immediately and can be accessed through the @data field. + */ struct fw_cdev_event_request { __u64 closure; __u32 type; @@ -69,14 +124,39 @@ struct fw_cdev_event_request { __u32 data[0]; }; +/** + * struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed + * @closure: See &fw_cdev_event_common; + * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT + * @cycle: Cycle counter of the interrupt packet + * @header_length: Total length of following headers, in bytes + * @header: Stripped headers, if any + * + * This event is sent when the controller has completed an &fw_cdev_iso_packet + * with the %FW_CDEV_ISO_INTERRUPT bit set. In the receive case, the headers + * stripped of all packets up until and including the interrupt packet are + * returned in the @header field. + */ struct fw_cdev_event_iso_interrupt { __u64 closure; __u32 type; __u32 cycle; - __u32 header_length; /* Length in bytes of following headers. */ + __u32 header_length; __u32 header[0]; }; +/** + * union fw_cdev_event - Convenience union of fw_cdev_event_ types + * @common: Valid for all types + * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET + * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE + * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST + * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT + * + * Convenience union for userspace use. Events could be read(2) into a char + * buffer and then cast to this union for further processing. + */ union fw_cdev_event { struct fw_cdev_event_common common; struct fw_cdev_event_bus_reset bus_reset; @@ -105,35 +185,47 @@ union fw_cdev_event { */ #define FW_CDEV_VERSION 1 +/** + * struct fw_cdev_get_info - General purpose information ioctl + * @version: The version field is just a running serial number. + * We never break backwards compatibility, but may add more + * structs and ioctls in later revisions. + * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration + * ROM will be copied into that user space address. In either + * case, @rom_length is updated with the actual length of the + * configuration ROM. + * @rom: If non-zero, address of a buffer to be filled by a copy of the + * local node's configuration ROM + * @bus_reset: If non-zero, address of a buffer to be filled by a + * &struct fw_cdev_event_bus_reset with the current state + * of the bus. This does not cause a bus reset to happen. + * @bus_reset_closure: Value of &closure in this and subsequent bus reset events + * @card: The index of the card this device belongs to + */ struct fw_cdev_get_info { - /* The version field is just a running serial number. We - * never break backwards compatibility. Userspace passes in - * the version it expects and the kernel passes back the - * highest version it can provide. Even if the structs in - * this interface are extended in a later version, the kernel - * will not copy back more data than what was present in the - * interface version userspace expects. */ __u32 version; - - /* If non-zero, at most rom_length bytes of config rom will be - * copied into that user space address. In either case, - * rom_length is updated with the actual length of the config - * rom. */ __u32 rom_length; __u64 rom; - - /* If non-zero, a fw_cdev_event_bus_reset struct will be - * copied here with the current state of the bus. This does - * not cause a bus reset to happen. The value of closure in - * this and sub-sequent bus reset events is set to - * bus_reset_closure. */ __u64 bus_reset; __u64 bus_reset_closure; - - /* The index of the card this devices belongs to. */ __u32 card; }; +/** + * struct fw_cdev_send_request - Send an asynchronous request packet + * @tcode: Transaction code of the request + * @length: Length of outgoing payload, in bytes + * @offset: 48-bit offset at destination node + * @closure: Passed back to userspace in the response event + * @data: Userspace pointer to payload + * @generation: The bus generation where packet is valid + * + * Send a request to the device. This ioctl implements all outgoing requests. + * Both quadlet and block request specify the payload as a pointer to the data + * in the @data field. Once the transaction completes, the kernel writes an + * &fw_cdev_event_request event back. The @closure field is passed back to + * user space in the response event. + */ struct fw_cdev_send_request { __u32 tcode; __u32 length; @@ -143,6 +235,19 @@ struct fw_cdev_send_request { __u32 generation; }; +/** + * struct fw_cdev_send_response - Send an asynchronous response packet + * @rcode: Response code as determined by the userspace handler + * @length: Length of outgoing payload, in bytes + * @data: Userspace pointer to payload + * @handle: The handle from the &fw_cdev_event_request + * + * Send a response to an incoming request. By setting up an address range using + * the %FW_CDEV_IOC_ALLOCATE ioctl, userspace can listen for incoming requests. An + * incoming request will generate an %FW_CDEV_EVENT_REQUEST, and userspace must + * send a reply using this ioctl. The event has a handle to the kernel-side + * pending transaction, which should be used with this ioctl. + */ struct fw_cdev_send_response { __u32 rcode; __u32 length; @@ -150,6 +255,21 @@ struct fw_cdev_send_response { __u32 handle; }; +/** + * struct fw_cdev_allocate - Allocate a CSR address range + * @offset: Start offset of the address range + * @closure: To be passed back to userspace in request events + * @length: Length of the address range, in bytes + * @handle: Handle to the allocation, written by the kernel + * + * Allocate an address range in the 48-bit address space on the local node + * (the controller). This allows userspace to listen for requests with an + * offset within that address range. When the kernel receives a request + * within the range, an &fw_cdev_event_request event will be written back. + * The @closure field is passed back to userspace in the response event. + * The @handle field is an out parameter, returning a handle to the allocated + * range to be used for later deallocation of the range. + */ struct fw_cdev_allocate { __u64 offset; __u64 closure; @@ -157,6 +277,11 @@ struct fw_cdev_allocate { __u32 handle; }; +/** + * struct fw_cdev_deallocate - Free an address range allocation + * @handle: Handle to the address range, as returned by the kernel when the + * range was allocated + */ struct fw_cdev_deallocate { __u32 handle; }; @@ -164,10 +289,41 @@ struct fw_cdev_deallocate { #define FW_CDEV_LONG_RESET 0 #define FW_CDEV_SHORT_RESET 1 +/** + * struct fw_cdev_initiate_bus_reset - Initiate a bus reset + * @type: %FW_CDEV_SHORT_RESET or %FW_CDEV_LONG_RESET + * + * Initiate a bus reset for the bus this device is on. The bus reset can be + * either the original (long) bus reset or the arbitrated (short) bus reset + * introduced in 1394a-2000. + */ struct fw_cdev_initiate_bus_reset { - __u32 type; + __u32 type; /* FW_CDEV_SHORT_RESET or FW_CDEV_LONG_RESET */ }; +/** + * struct fw_cdev_add_descriptor - Add contents to the local node's config ROM + * @immediate: If non-zero, immediate key to insert before pointer + * @key: Upper 8 bits of root directory pointer + * @data: Userspace pointer to contents of descriptor block + * @length: Length of descriptor block data, in bytes + * @handle: Handle to the descriptor, written by the kernel + * + * Add a descriptor block and optionally a preceding immediate key to the local + * node's configuration ROM. + * + * The @key field specifies the upper 8 bits of the descriptor root directory + * pointer and the @data and @length fields specify the contents. The @key + * should be of the form 0xXX000000. The offset part of the root directory entry + * will be filled in by the kernel. + * + * If not 0, the @immediate field specifies an immediate key which will be + * inserted before the root directory pointer. + * + * If successful, the kernel adds the descriptor and writes back a handle to the + * kernel-side object to be used for later removal of the descriptor block and + * immediate key. + */ struct fw_cdev_add_descriptor { __u32 immediate; __u32 key; @@ -176,6 +332,14 @@ struct fw_cdev_add_descriptor { __u32 handle; }; +/** + * struct fw_cdev_remove_descriptor - Remove contents from the configuration ROM + * @handle: Handle to the descriptor, as returned by the kernel when the + * descriptor was added + * + * Remove a descriptor block and accompanying immediate key from the local + * node's configuration ROM. + */ struct fw_cdev_remove_descriptor { __u32 handle; }; @@ -183,12 +347,24 @@ struct fw_cdev_remove_descriptor { #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 -#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 - +/** + * struct fw_cdev_create_iso_context - Create a context for isochronous IO + * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE + * @header_size: Header size to strip for receive contexts + * @channel: Channel to bind to + * @speed: Speed to transmit at + * @closure: To be returned in &fw_cdev_event_iso_interrupt + * @handle: Handle to context, written back by kernel + * + * Prior to sending or receiving isochronous I/O, a context must be created. + * The context records information about the transmit or receive configuration + * and typically maps to an underlying hardware resource. A context is set up + * for either sending or receiving. It is bound to a specific isochronous + * channel. + * + * If a context was successfully created, the kernel writes back a handle to the + * context, which must be passed in for subsequent operations on that context. + */ struct fw_cdev_create_iso_context { __u32 type; __u32 header_size; @@ -201,15 +377,49 @@ struct fw_cdev_create_iso_context { #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) #define FW_CDEV_ISO_INTERRUPT (1 << 16) #define FW_CDEV_ISO_SKIP (1 << 17) +#define FW_CDEV_ISO_SYNC (1 << 17) #define FW_CDEV_ISO_TAG(v) ((v) << 18) #define FW_CDEV_ISO_SY(v) ((v) << 20) #define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) +/** + * struct fw_cdev_iso_packet - Isochronous packet + * @control: Contains the header length (8 uppermost bits), the sy field + * (4 bits), the tag field (2 bits), a sync flag (1 bit), + * a skip flag (1 bit), an interrupt flag (1 bit), and the + * payload length (16 lowermost bits) + * @header: Header and payload + * + * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. + * + * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are + * specified by IEEE 1394a and IEC 61883. + * + * FIXME - finish this documentation + */ struct fw_cdev_iso_packet { __u32 control; __u32 header[0]; }; +/** + * struct fw_cdev_queue_iso - Queue isochronous packets for I/O + * @packets: Userspace pointer to packet data + * @data: Pointer into mmap()'ed payload buffer + * @size: Size of packet data in bytes + * @handle: Isochronous context handle + * + * Queue a number of isochronous packets for reception or transmission. + * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, + * which describe how to transmit from or receive into a contiguous region + * of a mmap()'ed payload buffer. As part of the packet descriptors, + * a series of headers can be supplied, which will be prepended to the + * payload during DMA. + * + * The kernel may or may not queue all packets, but will write back updated + * values of the @packets, @data and @size fields, so the ioctl can be + * resubmitted easily. + */ struct fw_cdev_queue_iso { __u64 packets; __u64 data; @@ -217,6 +427,23 @@ struct fw_cdev_queue_iso { __u32 handle; }; +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 +#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 + +/** + * struct fw_cdev_start_iso - Start an isochronous transmission or reception + * @cycle: Cycle in which to start I/O. If @cycle is greater than or + * equal to 0, the I/O will start on that cycle. + * @sync: Determines the value to wait for for receive packets that have + * the %FW_CDEV_ISO_SYNC bit set + * @tags: Tag filter bit mask. Only valid for isochronous reception. + * Determines the tag values for which packets will be accepted. + * Use FW_CDEV_ISO_CONTEXT_MATCH_ macros to set @tags. + * @handle: Isochronous context handle within which to transmit or receive + */ struct fw_cdev_start_iso { __s32 cycle; __u32 sync; @@ -224,6 +451,10 @@ struct fw_cdev_start_iso { __u32 handle; }; +/** + * struct fw_cdev_stop_iso - Stop an isochronous transmission or reception + * @handle: Handle of isochronous context to stop + */ struct fw_cdev_stop_iso { __u32 handle; }; From 6f061487f7d31427d7e8f420f366e5537ae16f43 Mon Sep 17 00:00:00 2001 From: Jay Fenlason Date: Wed, 27 Jun 2007 16:04:33 -0400 Subject: [PATCH 339/551] firewire: fw-sbp2: correctly dereference by container_of MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace a cast with a container_of(). As long as nobody reorders the structure elements, they do the same thing, but container_of() is more readable. Signed-off-by: Stefan Richter (added complete_command_orb) Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 2c39f19a9ee1..1fc1af7f55af 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -395,7 +395,7 @@ static void complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) { struct sbp2_management_orb *orb = - (struct sbp2_management_orb *)base_orb; + container_of(base_orb, struct sbp2_management_orb, base); if (status) memcpy(&orb->status, status, sizeof(*status)); @@ -838,7 +838,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) static void complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) { - struct sbp2_command_orb *orb = (struct sbp2_command_orb *)base_orb; + struct sbp2_command_orb *orb = + container_of(base_orb, struct sbp2_command_orb, base); struct fw_unit *unit = orb->unit; struct fw_device *device = fw_device(unit->device.parent); struct scatterlist *sg; From ffd0db26ddc32cd87097ece9725921f43ad487ee Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:54:24 +0200 Subject: [PATCH 340/551] firewire: fw-sbp2: use correct speed in sbp2_agent_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit noticed by Jay Fenlason Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 1fc1af7f55af..faee586516a5 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -518,7 +518,7 @@ static int sbp2_agent_reset(struct fw_unit *unit) return -ENOMEM; fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, - sd->node_id, sd->generation, SCODE_400, + sd->node_id, sd->generation, device->max_speed, sd->command_block_agent_address + SBP2_AGENT_RESET, &zero, sizeof(zero), complete_agent_reset_write, t); From e7cdf237b2a8b4b566721cfb08e448b454c74ada Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:54:57 +0200 Subject: [PATCH 341/551] firewire: fw-sbp2: memset wants string.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index faee586516a5..491d9484df1b 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include From 9fb2dd12c019965ffd15e5a0727af14488b3a772 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:55:31 +0200 Subject: [PATCH 342/551] firewire: fw-sbp2: correctly align page tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required per SBP-2 clause 5.2. Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 491d9484df1b..212674d723e3 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -220,7 +220,7 @@ struct sbp2_command_orb { scsi_done_fn_t done; struct fw_unit *unit; - struct sbp2_pointer page_table[SG_ALL]; + struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); dma_addr_t page_table_bus; }; From 332ef3310bc37ff29fd4382d6dfb38a787078091 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Jul 2007 13:56:03 +0200 Subject: [PATCH 343/551] firewire: fw-sbp2: add a boundary check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add rudimentary check for the case that the page table overflows due to merging of s/g elements by the IOMMU. This would have lead to overwriting of arbitrary memory. After this change I expect that an offending command will be unsuccessfully retried until the scsi_device is taken offline by SCSI core. It's a border case and not worth to implement a recovery strategy. Signed-off-by: Stefan Richter Acked-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 212674d723e3..c7518ea4c8ee 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -937,6 +937,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) sg_len = sg_dma_len(sg + i); sg_addr = sg_dma_address(sg + i); while (sg_len) { + /* FIXME: This won't get us out of the pinch. */ + if (unlikely(j >= ARRAY_SIZE(orb->page_table))) { + fw_error("page table overflow\n"); + goto fail_page_table; + } l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); orb->page_table[j].low = sg_addr; orb->page_table[j].high = (l << 16); From b4be016ad81af5a83f0be820edf106de883e6ade Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 22:07:34 +0200 Subject: [PATCH 344/551] firewire: fw-sbp2: fix DMA mapping of S/G tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The CPU must not touch the buffer after it was DMA-mapped. - The size argument of dma_unmap_single(...page_table...) was bogus. - Move a comment closer to the code to which it refers to. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index c7518ea4c8ee..a2ddf318a250 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -887,7 +887,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) if (orb->page_table_bus != 0) dma_unmap_single(device->card->device, orb->page_table_bus, - sizeof(orb->page_table_bus), DMA_TO_DEVICE); + sizeof(orb->page_table), DMA_TO_DEVICE); orb->cmd->result = result; orb->done(orb->cmd); @@ -902,7 +902,6 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) struct fw_device *device = fw_device(unit->device.parent); struct scatterlist *sg; int sg_len, l, i, j, count; - size_t size; dma_addr_t sg_addr; sg = (struct scatterlist *)orb->cmd->request_buffer; @@ -951,7 +950,13 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) } } - size = sizeof(orb->page_table[0]) * j; + fw_memcpy_to_be32(orb->page_table, orb->page_table, + sizeof(orb->page_table[0]) * j); + orb->page_table_bus = + dma_map_single(device->card->device, orb->page_table, + sizeof(orb->page_table), DMA_TO_DEVICE); + if (dma_mapping_error(orb->page_table_bus)) + goto fail_page_table; /* * The data_descriptor pointer is the one case where we need @@ -960,20 +965,12 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) * initiator (i.e. us), but data_descriptor can refer to data * on other nodes so we need to put our ID in descriptor.high. */ - - orb->page_table_bus = - dma_map_single(device->card->device, orb->page_table, - size, DMA_TO_DEVICE); - if (dma_mapping_error(orb->page_table_bus)) - goto fail_page_table; orb->request.data_descriptor.high = sd->address_high; orb->request.data_descriptor.low = orb->page_table_bus; orb->request.misc |= COMMAND_ORB_PAGE_TABLE_PRESENT | COMMAND_ORB_DATA_SIZE(j); - fw_memcpy_to_be32(orb->page_table, orb->page_table, size); - return 0; fail_page_table: From 8526392ae816a2c69f57097ba032865523019caa Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 21:04:08 +0200 Subject: [PATCH 345/551] firewire: fw-sbp2: fix DMA mapping of command ORBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU must not touch the buffer after it was DMA-mapped. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a2ddf318a250..f488ff8903fc 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1009,11 +1009,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) /* Initialize rcode to something not RCODE_COMPLETE. */ orb->base.rcode = -1; - orb->base.request_bus = - dma_map_single(device->card->device, &orb->request, - sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) - goto fail_mapping; orb->unit = unit; orb->done = done; @@ -1040,7 +1035,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) - goto fail_map_payload; + goto fail_mapping; fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); @@ -1049,15 +1044,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); orb->base.callback = complete_command_orb; + orb->base.request_bus = + dma_map_single(device->card->device, &orb->request, + sizeof(orb->request), DMA_TO_DEVICE); + if (dma_mapping_error(orb->base.request_bus)) + goto fail_mapping; sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, sd->command_block_agent_address + SBP2_ORB_POINTER); return 0; - fail_map_payload: - dma_unmap_single(device->card->device, orb->base.request_bus, - sizeof(orb->request), DMA_TO_DEVICE); fail_mapping: kfree(orb); fail_alloc: From 7aa484815f8c4defd01366f239b71da5e6b8a791 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Jul 2007 21:04:44 +0200 Subject: [PATCH 346/551] firewire: fw-sbp2: fix DMA mapping of management ORBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU must not touch the buffer after it was DMA-mapped. Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-sbp2.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index f488ff8903fc..7c53be0387fb 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -416,21 +416,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (orb == NULL) return -ENOMEM; - /* - * The sbp2 device is going to send a block read request to - * read out the request from host memory, so map it for dma. - */ - orb->base.request_bus = - dma_map_single(device->card->device, &orb->request, - sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) - goto out; - orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); if (dma_mapping_error(orb->response_bus)) - goto out; + goto fail_mapping_response; orb->request.response.high = 0; orb->request.response.low = orb->response_bus; @@ -456,6 +446,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, init_completion(&orb->done); orb->base.callback = complete_management_orb; + orb->base.request_bus = + dma_map_single(device->card->device, &orb->request, + sizeof(orb->request), DMA_TO_DEVICE); + if (dma_mapping_error(orb->base.request_bus)) + goto fail_mapping_request; + sbp2_send_orb(&orb->base, unit, node_id, generation, sd->management_agent_address); @@ -487,9 +483,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, out: dma_unmap_single(device->card->device, orb->base.request_bus, sizeof(orb->request), DMA_TO_DEVICE); + fail_mapping_request: dma_unmap_single(device->card->device, orb->response_bus, sizeof(orb->response), DMA_FROM_DEVICE); - + fail_mapping_response: if (response) fw_memcpy_from_be32(response, orb->response, sizeof(orb->response)); From f836ac808f031e84d7d73a3540f30f38036bb41e Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 9 May 2007 00:26:15 -0400 Subject: [PATCH 347/551] USB: Add USB_DEVICE_INTERFACE_PROTOCOL macro The USB_DEVICE_INTERFACE_PROTOCOL will allow to match one interface protocol of vendor specific device. This macro is used in patch adding support for xbox360 to xpad.c Signed-off-by: Jan Kratochvil Signed-off-by: Greg Kroah-Hartman Signed-off-by: Dmitry Torokhov --- include/linux/usb.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index 94bd38a6d947..56aa2ee21f1b 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -728,6 +728,22 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor .idVendor = (vend), .idProduct = (prod), \ .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) +/** + * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb + * device with a specific interface protocol + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @pr: bInterfaceProtocol value + * + * This macro is used to create a struct usb_device_id that matches a + * specific interface protocol of devices. + */ +#define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bInterfaceProtocol = (pr) + /** * USB_DEVICE_INFO - macro used to describe a class of usb devices * @cl: bDeviceClass value From c7d9f7eb30dccf601cbdc67d5bd452f54ce90ce4 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 9 May 2007 00:27:37 -0400 Subject: [PATCH 348/551] Input: xpad - add support for Xbox 360 gamepad Xbox 360 gamepad is slightly different then the previous model so it has its own version of process_packet method. Detection of this new device relies on USB_DEVICE_INTERFACE_PROTOCOL macro. This device got vendor specific subclass so it can't be matched with USB_INTERFACE_INFO and we need only one interface protocol from four availaible. It means USB_DEVICE can't be used either. Added xpad360_btn structure with additional buttons for x360 gamepad. Added xtype into xpad_device structure to distinguish between different types of xbox devices. Signed-off-by: Jan Kratochvil Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 151 ++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 34 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 8c8cd95a6989..f21f84a2dfff 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -8,6 +8,7 @@ * Ivan Hawkes * 2005 Dominic Cerquetti * 2006 Adam Buchbinder + * 2007 Jan Kratochvil * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,6 +29,7 @@ * - information from http://euc.jp/periphs/xbox-controller.ja.html * - the iForce driver drivers/char/joystick/iforce.c * - the skeleton-driver drivers/usb/usb-skeleton.c + * - Xbox 360 information http://www.free60.org/wiki/Gamepad * * Thanks to: * - ITO Takayuki for providing essential xpad information on his website @@ -88,6 +90,9 @@ #define MAP_DPAD_TO_AXES 1 #define MAP_DPAD_UNKNOWN -1 +#define XTYPE_XBOX 0 +#define XTYPE_XBOX360 1 + static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); @@ -97,40 +102,42 @@ static const struct xpad_device { u16 idProduct; char *name; u8 dpad_mapping; + u8 xtype; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, - { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, - { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } + { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, + { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } }; static const signed short xpad_btn[] = { @@ -146,6 +153,12 @@ static const signed short xpad_btn_pad[] = { -1 /* terminating entry */ }; +static const signed short xpad360_btn[] = { /* buttons for x360 controller */ + BTN_TL, BTN_TR, /* Button LB/RB */ + BTN_MODE, /* The big X button */ + -1 +}; + static const signed short xpad_abs[] = { ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ @@ -159,8 +172,12 @@ static const signed short xpad_abs_pad[] = { -1 /* terminating entry */ }; +/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only + * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, + * but we need only one of them. */ static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ + { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ { } }; @@ -177,6 +194,7 @@ struct usb_xpad { char phys[65]; /* physical device path */ int dpad_mapping; /* map d-pad to buttons or to axes */ + int xtype; /* type of xbox device */ }; /* @@ -235,6 +253,64 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_sync(dev); } +/* + * xpad360_process_packet + * + * Completes a request by converting the data into events for the + * input subsystem. It is version for xbox 360 controller + * + * The used report descriptor was taken from: + * http://www.free60.org/wiki/Gamepad + */ + +static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +{ + struct input_dev *dev = xpad->dev; + + /* digital pad */ + if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { + input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x01) - !!((data[2] & 0x08) >> 3)); + input_report_abs(dev, ABS_HAT0Y, !!((data[2] & 0x02) >> 1) - !!((data[2] & 0x04) >> 2)); + } else if ( xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS ) { + /* dpad as buttons (right, left, down, up) */ + input_report_key(dev, BTN_RIGHT, (data[2] & 0x01)); + input_report_key(dev, BTN_LEFT, (data[2] & 0x08) >> 3); + input_report_key(dev, BTN_0, (data[2] & 0x02) >> 1); + input_report_key(dev, BTN_1, (data[2] & 0x04) >> 2); + } + + /* start/back buttons */ + input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); + input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); + + /* stick press left/right */ + input_report_key(dev, BTN_THUMBL, data[2] & 0x40); + input_report_key(dev, BTN_THUMBR, data[2] & 0x80); + + /* buttons A,B,X,Y,TL,TR and MODE */ + input_report_key(dev, BTN_A, (data[3] & 0x10) >> 4); + input_report_key(dev, BTN_B, (data[3] & 0x20) >> 5); + input_report_key(dev, BTN_X, (data[3] & 0x40) >> 6); + input_report_key(dev, BTN_Y, (data[3] & 0x80) >> 7); + input_report_key(dev, BTN_TL, data[3] & 0x01 ); + input_report_key(dev, BTN_TR, (data[3] & 0x02) >> 1); + input_report_key(dev, BTN_MODE, (data[3] & 0x04) >> 2); + + /* left stick */ + input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6])); + input_report_abs(dev, ABS_Y, ~(__s16) (((__s16)data[9] << 8) | (__s16)data[8])); + + /* right stick */ + input_report_abs(dev, ABS_RY, ~(__s16) (((__s16)data[13] << 8) | (__s16)data[12])); + input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10])); + + /* triggers left/right */ + input_report_abs(dev, ABS_Z, data[4]); + input_report_abs(dev, ABS_RZ, data[5]); + + input_sync(dev); +} + static void xpad_irq_in(struct urb *urb) { struct usb_xpad *xpad = urb->context; @@ -255,7 +331,10 @@ static void xpad_irq_in(struct urb *urb) goto exit; } - xpad_process_packet(xpad, 0, xpad->idata); + if (xpad->xtype == XTYPE_XBOX360) + xpad360_process_packet(xpad, 0, xpad->idata); + else + xpad_process_packet(xpad, 0, xpad->idata); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); @@ -335,6 +414,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->udev = udev; xpad->dpad_mapping = xpad_device[i].dpad_mapping; + xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = dpad_to_buttons; xpad->dev = input_dev; @@ -356,6 +436,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id /* set up buttons */ for (i = 0; xpad_btn[i] >= 0; i++) set_bit(xpad_btn[i], input_dev->keybit); + if (xpad->xtype == XTYPE_XBOX360) + for (i = 0; xpad360_btn[i] >= 0; i++) + set_bit(xpad360_btn[i], input_dev->keybit); if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) for (i = 0; xpad_btn_pad[i] >= 0; i++) set_bit(xpad_btn_pad[i], input_dev->keybit); From e01a06e8df239de0ffd4ee37d296c7bc3f57e817 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 9 May 2007 00:27:51 -0400 Subject: [PATCH 349/551] Input: xpad - add Xbox360 gamepad rumble support Implementation is using force feedback support for memoryless devices. Signed-off-by: Jan Kratochvil Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/Kconfig | 7 ++ drivers/input/joystick/xpad.c | 125 +++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 4 deletions(-) diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b0023452ec90..12db72d83ea0 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -268,4 +268,11 @@ config JOYSTICK_XPAD To compile this driver as a module, choose M here: the module will be called xpad. +config JOYSTICK_XPAD_FF + bool "X-Box gamepad rumble support" + depends on JOYSTICK_XPAD && INPUT + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you want to take advantage of xbox 360 rumble features. + endif diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f21f84a2dfff..0c04a26b8122 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -191,6 +191,12 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; +#ifdef CONFIG_JOYSTICK_XPAD_FF + struct urb *irq_out; /* urb for interrupt out report */ + unsigned char *odata; /* output data */ + dma_addr_t odata_dma; +#endif + char phys[65]; /* physical device path */ int dpad_mapping; /* map d-pad to buttons or to axes */ @@ -343,7 +349,113 @@ exit: __FUNCTION__, retval); } -static int xpad_open (struct input_dev *dev) +#ifdef CONFIG_JOYSTICK_XPAD_FF +static void xpad_irq_out(struct urb *urb) +{ + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + goto exit; + } + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result %d", + __FUNCTION__, retval); +} + +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +{ + struct usb_xpad *xpad = input_get_drvdata(dev); + + if (effect->type == FF_RUMBLE) { + __u16 strong = effect->u.rumble.strong_magnitude; + __u16 weak = effect->u.rumble.weak_magnitude; + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; + xpad->odata[4] = weak / 256; + xpad->odata[5] = 0x00; + xpad->odata[6] = 0x00; + xpad->odata[7] = 0x00; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + + return 0; +} + +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) +{ + struct usb_endpoint_descriptor *ep_irq_out; + int error = -ENOMEM; + + if (xpad->xtype != XTYPE_XBOX360) + return 0; + + xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, + GFP_ATOMIC, &xpad->odata_dma ); + if (!xpad->idata) + goto fail1; + + xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); + if (!xpad->irq_out) + goto fail2; + + ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; + usb_fill_int_urb(xpad->irq_out, xpad->udev, + usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), + xpad->odata, XPAD_PKT_LEN, + xpad_irq_out, xpad, ep_irq_out->bInterval); + xpad->irq_out->transfer_dma = xpad->odata_dma; + xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); + + error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); + if (error) + goto fail2; + + return 0; + + fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); + fail1: return error; +} + +static void xpad_stop_ff(struct usb_xpad *xpad) +{ + if (xpad->xtype == XTYPE_XBOX360) + usb_kill_urb(xpad->irq_out); +} + +static void xpad_deinit_ff(struct usb_xpad *xpad) +{ + if (xpad->xtype == XTYPE_XBOX360) { + usb_free_urb(xpad->irq_out); + usb_buffer_free(xpad->udev, XPAD_PKT_LEN, + xpad->odata, xpad->odata_dma); + } +} + +#else +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } +static void xpad_stop_ff(struct usb_xpad *xpad) { } +static void xpad_deinit_ff(struct usb_xpad *xpad) { } +#endif + +static int xpad_open(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); @@ -354,11 +466,12 @@ static int xpad_open (struct input_dev *dev) return 0; } -static void xpad_close (struct input_dev *dev) +static void xpad_close(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); usb_kill_urb(xpad->irq_in); + xpad_stop_ff(xpad); } static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) @@ -450,6 +563,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); + error = xpad_init_ff(intf, xpad); + if (error) + goto fail2; + ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -479,10 +596,10 @@ static void xpad_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (xpad) { - usb_kill_urb(xpad->irq_in); input_unregister_device(xpad->dev); + xpad_deinit_ff(xpad); usb_free_urb(xpad->irq_in); - usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, + usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); } From aea6a46122a0ce65a831fd93cac6d2084ac666f9 Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Thu, 10 May 2007 01:47:18 -0400 Subject: [PATCH 350/551] Input: psmouse - add support for Cortron PS/2 Trackballs Cortron PS/2 Trackballs (700-0001A) report the 4th button using the 4th bit of the first packet (yes, it breaks the standard PS/2 protocol). This patch adds an extra protocol to generate BTN_SIDE based on the 4th bit. There's no way to detect those trackballs using any kind of special sequence, thus the protocol must be activated explicitely by writing into 'protocol' sysfs attribute: echo -n "cortps" > /sys/devices/platform/i8042/serio1/protocol Signed-off-by: Aristeu Rozanski Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 29 +++++++++++++++++++++++++++++ drivers/input/mouse/psmouse.h | 1 + 2 files changed, 30 insertions(+) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index f15f695777f8..b9f0fb2530e2 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -177,6 +177,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) packet[1] |= (packet[0] & 0x40) << 1; } +/* + * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first + * byte. + */ + if (psmouse->type == PSMOUSE_CORTRON) { + input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1); + packet[0] |= 0x08; + } + /* * Generic PS/2 Mouse */ @@ -539,6 +548,20 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties) return 0; } +/* + * Cortron PS/2 protocol detection. There's no special way to detect it, so it + * must be forced by sysfs protocol writing. + */ +static int cortron_detect(struct psmouse *psmouse, int set_properties) +{ + if (set_properties) { + psmouse->vendor = "Cortron"; + psmouse->name = "PS/2 Trackball"; + set_bit(BTN_SIDE, psmouse->dev->keybit); + } + + return 0; +} /* * psmouse_extensions() probes for any extensions to the basic PS/2 protocol @@ -739,6 +762,12 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = touchkit_ps2_detect, }, #endif + { + .type = PSMOUSE_CORTRON, + .name = "CortronPS/2", + .alias = "cortps", + .detect = cortron_detect, + }, { .type = PSMOUSE_AUTO, .name = "auto", diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 3964e8acbc54..27a68835b5ba 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -88,6 +88,7 @@ enum psmouse_type { PSMOUSE_LIFEBOOK, PSMOUSE_TRACKPOINT, PSMOUSE_TOUCHKIT_PS2, + PSMOUSE_CORTRON, PSMOUSE_AUTO /* This one should always be last */ }; From 9b40ed088bb14ebed30540b19d5c417dc4d9d528 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:17:12 -0400 Subject: [PATCH 351/551] Input: aiptek - do not try to export associated event device Do not try to export via sysfs associated event device - it does not work when evdev is a module that is loaded after aiptek; also it pokes too deply into input core internals. Userspace should rely on udev to set up permanent device name for the tablet. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 42 ----------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index cc0a498763d8..c4df4f727f1f 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -294,7 +294,6 @@ struct aiptek_features { int modelCode; /* Tablet model code (not unique) */ int firmwareCode; /* prom/eeprom version */ char usbPath[64 + 1]; /* device's physical usb path */ - char inputPath[64 + 1]; /* input device path */ }; struct aiptek_settings { @@ -1414,23 +1413,6 @@ static DEVICE_ATTR(delay, S_IRUGO | S_IWUGO, show_tabletProgrammableDelay, store_tabletProgrammableDelay); -/*********************************************************************** - * support routines for the 'input_path' file. Note that this file - * only displays current setting. - */ -static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct aiptek *aiptek = dev_get_drvdata(dev); - - if (aiptek == NULL) - return 0; - - return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n", - aiptek->features.inputPath); -} - -static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL); - /*********************************************************************** * support routines for the 'event_count' file. Note that this file * only displays current setting. @@ -1896,7 +1878,6 @@ static void aiptek_delete_files(struct device *dev) device_remove_file(dev, &dev_attr_ytilt); device_remove_file(dev, &dev_attr_jitter); device_remove_file(dev, &dev_attr_delay); - device_remove_file(dev, &dev_attr_input_path); device_remove_file(dev, &dev_attr_event_count); device_remove_file(dev, &dev_attr_diagnostic); device_remove_file(dev, &dev_attr_odm_code); @@ -1931,7 +1912,6 @@ static int aiptek_add_files(struct device *dev) (ret = device_create_file(dev, &dev_attr_ytilt)) || (ret = device_create_file(dev, &dev_attr_jitter)) || (ret = device_create_file(dev, &dev_attr_delay)) || - (ret = device_create_file(dev, &dev_attr_input_path)) || (ret = device_create_file(dev, &dev_attr_event_count)) || (ret = device_create_file(dev, &dev_attr_diagnostic)) || (ret = device_create_file(dev, &dev_attr_odm_code)) || @@ -1961,8 +1941,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; struct input_dev *inputdev; - struct input_handle *inputhandle; - struct list_head *node, *next; int i; int speeds[] = { 0, AIPTEK_PROGRAMMABLE_DELAY_50, @@ -2140,21 +2118,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) if (err) goto fail2; - /* We now will look for the evdev device which is mapped to - * the tablet. The partial name is kept in the link list of - * input_handles associated with this input device. - * What identifies an evdev input_handler is that it begins - * with 'event', continues with a digit, and that in turn - * is mapped to input/eventN. - */ - list_for_each_safe(node, next, &inputdev->h_list) { - inputhandle = to_handle(node); - if (strncmp(inputhandle->name, "event", 5) == 0) { - strcpy(aiptek->features.inputPath, inputhandle->name); - break; - } - } - /* Associate this driver's struct with the usb interface. */ usb_set_intfdata(intf, aiptek); @@ -2163,11 +2126,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ aiptek_add_files(&intf->dev); - /* Make sure the evdev module is loaded. Assuming evdev IS a module :-) - */ - if (request_module("evdev") != 0) - info("aiptek: error loading 'evdev' module"); - return 0; fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, From 5c659c62f9f60633a8de17bd17afaa448f1e1d68 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:17:22 -0400 Subject: [PATCH 352/551] Input: aiptek - remove vendor and product attributes from sysfs They are already exported by input core; there is no need to do it twice. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 73 ----------------------------------- 1 file changed, 73 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index c4df4f727f1f..f9a5f872505f 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1022,71 +1022,6 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr */ static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); -/*********************************************************************** - * support routines for the 'product_id' file - */ -static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct aiptek *aiptek = dev_get_drvdata(dev); - - if (aiptek == NULL) - return 0; - - return snprintf(buf, PAGE_SIZE, "0x%04x\n", - aiptek->inputdev->id.product); -} - -static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL); - -/*********************************************************************** - * support routines for the 'vendor_id' file - */ -static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct aiptek *aiptek = dev_get_drvdata(dev); - - if (aiptek == NULL) - return 0; - - return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor); -} - -static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL); - -/*********************************************************************** - * support routines for the 'vendor' file - */ -static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct aiptek *aiptek = dev_get_drvdata(dev); - int retval; - - if (aiptek == NULL) - return 0; - - retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer); - return retval; -} - -static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL); - -/*********************************************************************** - * support routines for the 'product' file - */ -static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct aiptek *aiptek = dev_get_drvdata(dev); - int retval; - - if (aiptek == NULL) - return 0; - - retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product); - return retval; -} - -static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL); - /*********************************************************************** * support routines for the 'pointer_mode' file. Note that this file * both displays current setting and allows reprogramming. @@ -1867,10 +1802,6 @@ static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); static void aiptek_delete_files(struct device *dev) { device_remove_file(dev, &dev_attr_size); - device_remove_file(dev, &dev_attr_product_id); - device_remove_file(dev, &dev_attr_vendor_id); - device_remove_file(dev, &dev_attr_vendor); - device_remove_file(dev, &dev_attr_product); device_remove_file(dev, &dev_attr_pointer_mode); device_remove_file(dev, &dev_attr_coordinate_mode); device_remove_file(dev, &dev_attr_tool_mode); @@ -1901,10 +1832,6 @@ static int aiptek_add_files(struct device *dev) int ret; if ((ret = device_create_file(dev, &dev_attr_size)) || - (ret = device_create_file(dev, &dev_attr_product_id)) || - (ret = device_create_file(dev, &dev_attr_vendor_id)) || - (ret = device_create_file(dev, &dev_attr_vendor)) || - (ret = device_create_file(dev, &dev_attr_product)) || (ret = device_create_file(dev, &dev_attr_pointer_mode)) || (ret = device_create_file(dev, &dev_attr_coordinate_mode)) || (ret = device_create_file(dev, &dev_attr_tool_mode)) || From b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:17:37 -0400 Subject: [PATCH 353/551] Input: aiptek - use attribute group Use attribute group to simplify error handling and reduce code. [Rene: add missing NULL to properly terminate aiptek_attributes] Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 109 +++++++++++++--------------------- 1 file changed, 40 insertions(+), 69 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index f9a5f872505f..088da86f0508 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1795,67 +1795,33 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); -/*********************************************************************** - * This routine removes all existing sysfs files managed by this device - * driver. - */ -static void aiptek_delete_files(struct device *dev) -{ - device_remove_file(dev, &dev_attr_size); - device_remove_file(dev, &dev_attr_pointer_mode); - device_remove_file(dev, &dev_attr_coordinate_mode); - device_remove_file(dev, &dev_attr_tool_mode); - device_remove_file(dev, &dev_attr_xtilt); - device_remove_file(dev, &dev_attr_ytilt); - device_remove_file(dev, &dev_attr_jitter); - device_remove_file(dev, &dev_attr_delay); - device_remove_file(dev, &dev_attr_event_count); - device_remove_file(dev, &dev_attr_diagnostic); - device_remove_file(dev, &dev_attr_odm_code); - device_remove_file(dev, &dev_attr_model_code); - device_remove_file(dev, &dev_attr_firmware_code); - device_remove_file(dev, &dev_attr_stylus_lower); - device_remove_file(dev, &dev_attr_stylus_upper); - device_remove_file(dev, &dev_attr_mouse_left); - device_remove_file(dev, &dev_attr_mouse_middle); - device_remove_file(dev, &dev_attr_mouse_right); - device_remove_file(dev, &dev_attr_wheel); - device_remove_file(dev, &dev_attr_execute); -} +static struct attribute *aiptek_attributes[] = { + &dev_attr_size.attr, + &dev_attr_pointer_mode.attr, + &dev_attr_coordinate_mode.attr, + &dev_attr_tool_mode.attr, + &dev_attr_xtilt.attr, + &dev_attr_ytilt.attr, + &dev_attr_jitter.attr, + &dev_attr_delay.attr, + &dev_attr_event_count.attr, + &dev_attr_diagnostic.attr, + &dev_attr_odm_code.attr, + &dev_attr_model_code.attr, + &dev_attr_firmware_code.attr, + &dev_attr_stylus_lower.attr, + &dev_attr_stylus_upper.attr, + &dev_attr_mouse_left.attr, + &dev_attr_mouse_middle.attr, + &dev_attr_mouse_right.attr, + &dev_attr_wheel.attr, + &dev_attr_execute.attr, + NULL +}; -/*********************************************************************** - * This routine creates the sysfs files managed by this device - * driver. - */ -static int aiptek_add_files(struct device *dev) -{ - int ret; - - if ((ret = device_create_file(dev, &dev_attr_size)) || - (ret = device_create_file(dev, &dev_attr_pointer_mode)) || - (ret = device_create_file(dev, &dev_attr_coordinate_mode)) || - (ret = device_create_file(dev, &dev_attr_tool_mode)) || - (ret = device_create_file(dev, &dev_attr_xtilt)) || - (ret = device_create_file(dev, &dev_attr_ytilt)) || - (ret = device_create_file(dev, &dev_attr_jitter)) || - (ret = device_create_file(dev, &dev_attr_delay)) || - (ret = device_create_file(dev, &dev_attr_event_count)) || - (ret = device_create_file(dev, &dev_attr_diagnostic)) || - (ret = device_create_file(dev, &dev_attr_odm_code)) || - (ret = device_create_file(dev, &dev_attr_model_code)) || - (ret = device_create_file(dev, &dev_attr_firmware_code)) || - (ret = device_create_file(dev, &dev_attr_stylus_lower)) || - (ret = device_create_file(dev, &dev_attr_stylus_upper)) || - (ret = device_create_file(dev, &dev_attr_mouse_left)) || - (ret = device_create_file(dev, &dev_attr_mouse_middle)) || - (ret = device_create_file(dev, &dev_attr_mouse_right)) || - (ret = device_create_file(dev, &dev_attr_wheel)) || - (ret = device_create_file(dev, &dev_attr_execute))) { - err("aiptek: killing own sysfs device files\n"); - aiptek_delete_files(dev); - } - return ret; -} +static struct attribute_group aiptek_attribute_group = { + .attrs = aiptek_attributes, +}; /*********************************************************************** * This routine is called when a tablet has been identified. It basically @@ -2039,25 +2005,30 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) } } - /* Register the tablet as an Input Device - */ - err = input_register_device(aiptek->inputdev); - if (err) - goto fail2; - /* Associate this driver's struct with the usb interface. */ usb_set_intfdata(intf, aiptek); /* Set up the sysfs files */ - aiptek_add_files(&intf->dev); + err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); + if (err) + goto fail3; + + /* Register the tablet as an Input Device + */ + err = input_register_device(aiptek->inputdev); + if (err) + goto fail4; return 0; + fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); + fail3: usb_free_urb(aiptek->urb); fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, aiptek->data_dma); - fail1: input_free_device(inputdev); + fail1: usb_set_intfdata(intf, NULL); + input_free_device(inputdev); kfree(aiptek); return err; } @@ -2077,7 +2048,7 @@ static void aiptek_disconnect(struct usb_interface *intf) */ usb_kill_urb(aiptek->urb); input_unregister_device(aiptek->inputdev); - aiptek_delete_files(&intf->dev); + sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); usb_free_urb(aiptek->urb); usb_buffer_free(interface_to_usbdev(intf), AIPTEK_PACKET_LENGTH, From 02fb6c385c72823af4fac83963a05be9163c73ea Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:17:44 -0400 Subject: [PATCH 354/551] Input: aiptek - do not check for NULL in attribute methods It makes no sense to check for NULL in attribute methods - we do usb_set_intfdata before creating attributes and once attributes have been removed we are guaranteed to not be called. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 101 ---------------------------------- 1 file changed, 101 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 088da86f0508..274c12f4220b 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1006,9 +1006,6 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "%dx%d\n", aiptek->inputdev->absmax[ABS_X] + 1, aiptek->inputdev->absmax[ABS_Y] + 1); @@ -1031,9 +1028,6 @@ static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribut struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.pointerMode) { case AIPTEK_POINTER_ONLY_STYLUS_MODE: s = "stylus"; @@ -1058,8 +1052,6 @@ static ssize_t store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; if (strcmp(buf, "stylus") == 0) { aiptek->newSetting.pointerMode = @@ -1085,9 +1077,6 @@ static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attri struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.coordinateMode) { case AIPTEK_COORDINATE_ABSOLUTE_MODE: s = "absolute"; @@ -1108,8 +1097,6 @@ static ssize_t store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; if (strcmp(buf, "absolute") == 0) { aiptek->newSetting.pointerMode = @@ -1134,9 +1121,6 @@ static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute * struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) { case AIPTEK_TOOL_BUTTON_MOUSE_MODE: s = "mouse"; @@ -1177,8 +1161,6 @@ static ssize_t store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; if (strcmp(buf, "mouse") == 0) { aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE; @@ -1211,9 +1193,6 @@ static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1228,9 +1207,6 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char struct aiptek *aiptek = dev_get_drvdata(dev); int x; - if (aiptek == NULL) - return 0; - if (strcmp(buf, "disable") == 0) { aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; } else { @@ -1253,9 +1229,6 @@ static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1270,9 +1243,6 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char struct aiptek *aiptek = dev_get_drvdata(dev); int y; - if (aiptek == NULL) - return 0; - if (strcmp(buf, "disable") == 0) { aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; } else { @@ -1295,9 +1265,6 @@ static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribut { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay); } @@ -1306,9 +1273,6 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1325,9 +1289,6 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_at { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.programmableDelay); } @@ -1337,9 +1298,6 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1356,9 +1314,6 @@ static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attri { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount); } @@ -1373,9 +1328,6 @@ static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_at struct aiptek *aiptek = dev_get_drvdata(dev); char *retMsg; - if (aiptek == NULL) - return 0; - switch (aiptek->diagnostic) { case AIPTEK_DIAGNOSTIC_NA: retMsg = "no errors\n"; @@ -1415,9 +1367,6 @@ static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribut struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.stylusButtonUpper) { case AIPTEK_STYLUS_UPPER_BUTTON: s = "upper"; @@ -1439,9 +1388,6 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (strcmp(buf, "upper") == 0) { aiptek->newSetting.stylusButtonUpper = AIPTEK_STYLUS_UPPER_BUTTON; @@ -1465,9 +1411,6 @@ static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribut struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.stylusButtonLower) { case AIPTEK_STYLUS_UPPER_BUTTON: s = "upper"; @@ -1489,9 +1432,6 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (strcmp(buf, "upper") == 0) { aiptek->newSetting.stylusButtonLower = AIPTEK_STYLUS_UPPER_BUTTON; @@ -1515,9 +1455,6 @@ static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.mouseButtonLeft) { case AIPTEK_MOUSE_LEFT_BUTTON: s = "left"; @@ -1543,9 +1480,6 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (strcmp(buf, "left") == 0) { aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON; } else if (strcmp(buf, "middle") == 0) { @@ -1569,9 +1503,6 @@ static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribut struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.mouseButtonMiddle) { case AIPTEK_MOUSE_LEFT_BUTTON: s = "left"; @@ -1597,9 +1528,6 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (strcmp(buf, "left") == 0) { aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON; } else if (strcmp(buf, "middle") == 0) { @@ -1625,9 +1553,6 @@ static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute struct aiptek *aiptek = dev_get_drvdata(dev); char *s; - if (aiptek == NULL) - return 0; - switch (aiptek->curSetting.mouseButtonRight) { case AIPTEK_MOUSE_LEFT_BUTTON: s = "left"; @@ -1653,9 +1578,6 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (strcmp(buf, "left") == 0) { aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON; } else if (strcmp(buf, "middle") == 0) { @@ -1679,9 +1601,6 @@ static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *att { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { @@ -1695,9 +1614,6 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); return count; } @@ -1711,11 +1627,6 @@ static DEVICE_ATTR(wheel, */ static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf) { - struct aiptek *aiptek = dev_get_drvdata(dev); - - if (aiptek == NULL) - return 0; - /* There is nothing useful to display, so a one-line manual * is in order... */ @@ -1728,9 +1639,6 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - /* We do not care what you write to this file. Merely the action * of writing to this file triggers a tablet reprogramming. */ @@ -1754,9 +1662,6 @@ static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *a { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode); } @@ -1770,9 +1675,6 @@ static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode); } @@ -1786,9 +1688,6 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at { struct aiptek *aiptek = dev_get_drvdata(dev); - if (aiptek == NULL) - return 0; - return snprintf(buf, PAGE_SIZE, "%04x\n", aiptek->features.firmwareCode); } From cd438a58c89221d8642455d0cc8ec96d3b822f6e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:17:57 -0400 Subject: [PATCH 355/551] Input: aiptek - use maps in attributes Use maps to convert for strings to internal constants and vice versa in aiptek's sysfs attribute methods instead of open-coding it. This results in smaller code that is also easier to maintain. [Rene: fix a typo - stylys instead of stylus] Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 362 +++++++++++++--------------------- 1 file changed, 138 insertions(+), 224 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 274c12f4220b..0c990e61ed73 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -343,6 +343,39 @@ static const int macroKeyEvents[] = { KEY_FRONT, KEY_COPY, KEY_OPEN, KEY_PASTE, 0 }; +/*********************************************************************** + * Map values to strings and back. Every map shoudl have the following + * as its last element: { NULL, AIPTEK_INVALID_VALUE }. + */ +#define AIPTEK_INVALID_VALUE -1 + +struct aiptek_map { + const char *string; + int value; +}; + +static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count) +{ + const struct aiptek_map *p; + + for (p = map; p->string; p++) + if (!strncmp(str, p->string, count)) + return p->value; + + return AIPTEK_INVALID_VALUE; +} + +static const char *map_val_to_str(const struct aiptek_map *map, int val) +{ + const struct aiptek_map *p; + + for (p = map; p->value != AIPTEK_INVALID_VALUE; p++) + if (val == p->value) + return p->string; + + return "unknown"; +} + /*********************************************************************** * Relative reports deliver values in 2's complement format to * deal with negative offsets. @@ -1023,44 +1056,32 @@ static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); * support routines for the 'pointer_mode' file. Note that this file * both displays current setting and allows reprogramming. */ +static struct aiptek_map pointer_mode_map[] = { + { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE }, + { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE }, + { "either", AIPTEK_POINTER_EITHER_MODE }, + { NULL, AIPTEK_INVALID_VALUE } +}; + static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.pointerMode) { - case AIPTEK_POINTER_ONLY_STYLUS_MODE: - s = "stylus"; - break; - - case AIPTEK_POINTER_ONLY_MOUSE_MODE: - s = "mouse"; - break; - - case AIPTEK_POINTER_EITHER_MODE: - s = "either"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(pointer_mode_map, + aiptek->curSetting.pointerMode)); } static ssize_t store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_mode = map_str_to_val(pointer_mode_map, buf, count); - if (strcmp(buf, "stylus") == 0) { - aiptek->newSetting.pointerMode = - AIPTEK_POINTER_ONLY_STYLUS_MODE; - } else if (strcmp(buf, "mouse") == 0) { - aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE; - } else if (strcmp(buf, "either") == 0) { - aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE; - } + if (new_mode == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.pointerMode = new_mode; return count; } @@ -1072,39 +1093,32 @@ static DEVICE_ATTR(pointer_mode, * support routines for the 'coordinate_mode' file. Note that this file * both displays current setting and allows reprogramming. */ + +static struct aiptek_map coordinate_mode_map[] = { + { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE }, + { "relative", AIPTEK_COORDINATE_RELATIVE_MODE }, + { NULL, AIPTEK_INVALID_VALUE } +}; + static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.coordinateMode) { - case AIPTEK_COORDINATE_ABSOLUTE_MODE: - s = "absolute"; - break; - - case AIPTEK_COORDINATE_RELATIVE_MODE: - s = "relative"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(coordinate_mode_map, + aiptek->curSetting.coordinateMode)); } static ssize_t store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_mode = map_str_to_val(coordinate_mode_map, buf, count); - if (strcmp(buf, "absolute") == 0) { - aiptek->newSetting.pointerMode = - AIPTEK_COORDINATE_ABSOLUTE_MODE; - } else if (strcmp(buf, "relative") == 0) { - aiptek->newSetting.pointerMode = - AIPTEK_COORDINATE_RELATIVE_MODE; - } + if (new_mode == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.coordinateMode = new_mode; return count; } @@ -1116,68 +1130,37 @@ static DEVICE_ATTR(coordinate_mode, * support routines for the 'tool_mode' file. Note that this file * both displays current setting and allows reprogramming. */ + +static struct aiptek_map tool_mode_map[] = { + { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE }, + { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE }, + { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE }, + { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE }, + { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE }, + { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE }, + { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE }, + { NULL, AIPTEK_INVALID_VALUE } +}; + static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) { - case AIPTEK_TOOL_BUTTON_MOUSE_MODE: - s = "mouse"; - break; - - case AIPTEK_TOOL_BUTTON_ERASER_MODE: - s = "eraser"; - break; - - case AIPTEK_TOOL_BUTTON_PENCIL_MODE: - s = "pencil"; - break; - - case AIPTEK_TOOL_BUTTON_PEN_MODE: - s = "pen"; - break; - - case AIPTEK_TOOL_BUTTON_BRUSH_MODE: - s = "brush"; - break; - - case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE: - s = "airbrush"; - break; - - case AIPTEK_TOOL_BUTTON_LENS_MODE: - s = "lens"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(tool_mode_map, + aiptek->curSetting.toolMode)); } static ssize_t store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_mode = map_str_to_val(tool_mode_map, buf, count); - if (strcmp(buf, "mouse") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE; - } else if (strcmp(buf, "eraser") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE; - } else if (strcmp(buf, "pencil") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE; - } else if (strcmp(buf, "pen") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE; - } else if (strcmp(buf, "brush") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE; - } else if (strcmp(buf, "airbrush") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE; - } else if (strcmp(buf, "lens") == 0) { - aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE; - } + if (new_mode == AIPTEK_INVALID_VALUE) + return -EINVAL; + aiptek->newSetting.toolMode = new_mode; return count; } @@ -1362,39 +1345,32 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL); * support routines for the 'stylus_upper' file. Note that this file * both displays current setting and allows for setting changing. */ + +static struct aiptek_map stylus_button_map[] = { + { "upper", AIPTEK_STYLUS_UPPER_BUTTON }, + { "lower", AIPTEK_STYLUS_LOWER_BUTTON }, + { NULL, AIPTEK_INVALID_VALUE } +}; + static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.stylusButtonUpper) { - case AIPTEK_STYLUS_UPPER_BUTTON: - s = "upper"; - break; - - case AIPTEK_STYLUS_LOWER_BUTTON: - s = "lower"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(stylus_button_map, + aiptek->curSetting.stylusButtonUpper)); } static ssize_t store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_button = map_str_to_val(stylus_button_map, buf, count); - if (strcmp(buf, "upper") == 0) { - aiptek->newSetting.stylusButtonUpper = - AIPTEK_STYLUS_UPPER_BUTTON; - } else if (strcmp(buf, "lower") == 0) { - aiptek->newSetting.stylusButtonUpper = - AIPTEK_STYLUS_LOWER_BUTTON; - } + if (new_button == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.stylusButtonUpper = new_button; return count; } @@ -1406,39 +1382,26 @@ static DEVICE_ATTR(stylus_upper, * support routines for the 'stylus_lower' file. Note that this file * both displays current setting and allows for setting changing. */ + static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.stylusButtonLower) { - case AIPTEK_STYLUS_UPPER_BUTTON: - s = "upper"; - break; - - case AIPTEK_STYLUS_LOWER_BUTTON: - s = "lower"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(stylus_button_map, + aiptek->curSetting.stylusButtonLower)); } static ssize_t store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_button = map_str_to_val(stylus_button_map, buf, count); - if (strcmp(buf, "upper") == 0) { - aiptek->newSetting.stylusButtonLower = - AIPTEK_STYLUS_UPPER_BUTTON; - } else if (strcmp(buf, "lower") == 0) { - aiptek->newSetting.stylusButtonLower = - AIPTEK_STYLUS_LOWER_BUTTON; - } + if (new_button == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.stylusButtonLower = new_button; return count; } @@ -1450,43 +1413,33 @@ static DEVICE_ATTR(stylus_lower, * support routines for the 'mouse_left' file. Note that this file * both displays current setting and allows for setting changing. */ + +static struct aiptek_map mouse_button_map[] = { + { "left", AIPTEK_MOUSE_LEFT_BUTTON }, + { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON }, + { "right", AIPTEK_MOUSE_RIGHT_BUTTON }, + { NULL, AIPTEK_INVALID_VALUE } +}; + static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.mouseButtonLeft) { - case AIPTEK_MOUSE_LEFT_BUTTON: - s = "left"; - break; - - case AIPTEK_MOUSE_MIDDLE_BUTTON: - s = "middle"; - break; - - case AIPTEK_MOUSE_RIGHT_BUTTON: - s = "right"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(mouse_button_map, + aiptek->curSetting.mouseButtonLeft)); } static ssize_t store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_button = map_str_to_val(mouse_button_map, buf, count); - if (strcmp(buf, "left") == 0) { - aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON; - } else if (strcmp(buf, "middle") == 0) { - aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON; - } else if (strcmp(buf, "right") == 0) { - aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON; - } + if (new_button == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.mouseButtonLeft = new_button; return count; } @@ -1501,42 +1454,22 @@ static DEVICE_ATTR(mouse_left, static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.mouseButtonMiddle) { - case AIPTEK_MOUSE_LEFT_BUTTON: - s = "left"; - break; - - case AIPTEK_MOUSE_MIDDLE_BUTTON: - s = "middle"; - break; - - case AIPTEK_MOUSE_RIGHT_BUTTON: - s = "right"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(mouse_button_map, + aiptek->curSetting.mouseButtonMiddle)); } static ssize_t store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_button = map_str_to_val(mouse_button_map, buf, count); - if (strcmp(buf, "left") == 0) { - aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON; - } else if (strcmp(buf, "middle") == 0) { - aiptek->newSetting.mouseButtonMiddle = - AIPTEK_MOUSE_MIDDLE_BUTTON; - } else if (strcmp(buf, "right") == 0) { - aiptek->newSetting.mouseButtonMiddle = - AIPTEK_MOUSE_RIGHT_BUTTON; - } + if (new_button == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.mouseButtonMiddle = new_button; return count; } @@ -1551,41 +1484,22 @@ static DEVICE_ATTR(mouse_middle, static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf) { struct aiptek *aiptek = dev_get_drvdata(dev); - char *s; - switch (aiptek->curSetting.mouseButtonRight) { - case AIPTEK_MOUSE_LEFT_BUTTON: - s = "left"; - break; - - case AIPTEK_MOUSE_MIDDLE_BUTTON: - s = "middle"; - break; - - case AIPTEK_MOUSE_RIGHT_BUTTON: - s = "right"; - break; - - default: - s = "unknown"; - break; - } - return snprintf(buf, PAGE_SIZE, "%s\n", s); + return snprintf(buf, PAGE_SIZE, "%s\n", + map_val_to_str(mouse_button_map, + aiptek->curSetting.mouseButtonRight)); } static ssize_t store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aiptek *aiptek = dev_get_drvdata(dev); + int new_button = map_str_to_val(mouse_button_map, buf, count); - if (strcmp(buf, "left") == 0) { - aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON; - } else if (strcmp(buf, "middle") == 0) { - aiptek->newSetting.mouseButtonRight = - AIPTEK_MOUSE_MIDDLE_BUTTON; - } else if (strcmp(buf, "right") == 0) { - aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON; - } + if (new_button == AIPTEK_INVALID_VALUE) + return -EINVAL; + + aiptek->newSetting.mouseButtonRight = new_button; return count; } From 37767b66ed61ee37f0d8f40523f74c31bc187d1d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:18:08 -0400 Subject: [PATCH 356/551] Input: aiptek - kill aiptek_convert_from_2s_complement() There is no reason to do that, just tell the compiler that we are dealing with signed values in buffer, that's it. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 0c990e61ed73..3a5e0aafa115 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -376,26 +376,6 @@ static const char *map_val_to_str(const struct aiptek_map *map, int val) return "unknown"; } -/*********************************************************************** - * Relative reports deliver values in 2's complement format to - * deal with negative offsets. - */ -static int aiptek_convert_from_2s_complement(unsigned char c) -{ - int ret; - unsigned char b = c; - int negate = 0; - - if ((b & 0x80) != 0) { - b = ~b; - b--; - negate = 1; - } - ret = b; - ret = (negate == 1) ? -ret : ret; - return ret; -} - /*********************************************************************** * aiptek_irq can receive one of six potential reports. * The documentation for each is in the body of the function. @@ -473,8 +453,8 @@ static void aiptek_irq(struct urb *urb) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; } else { - x = aiptek_convert_from_2s_complement(data[2]); - y = aiptek_convert_from_2s_complement(data[3]); + x = (signed char) data[2]; + y = (signed char) data[3]; /* jitterable keeps track of whether any button has been pressed. * We're also using it to remap the physical mouse button mask From 33936fa603f2524a7dde08d22637d0989a4e8fdd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 May 2007 00:18:15 -0400 Subject: [PATCH 357/551] Input: aiptek - use array to list all buttons When setting up input device use an array to list all the buttons instead of setting every bit separately. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 3a5e0aafa115..86e48930dfa2 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -329,6 +329,13 @@ struct aiptek { unsigned char *data; /* incoming packet data */ }; +static const int buttonEvents[] = { + BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, + BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, + BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH, + BTN_STYLUS, BTN_STYLUS2, +}; + /* * Permit easy lookup of keyboard events to send, versus * the bitmap which comes from the tablet. This hides the @@ -1728,26 +1735,14 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) inputdev->relbit[0] |= (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC)); - inputdev->keybit[LONG(BTN_LEFT)] |= - (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE)); - - inputdev->keybit[LONG(BTN_DIGI)] |= - (BIT(BTN_TOOL_PEN) | - BIT(BTN_TOOL_RUBBER) | - BIT(BTN_TOOL_PENCIL) | - BIT(BTN_TOOL_AIRBRUSH) | - BIT(BTN_TOOL_BRUSH) | - BIT(BTN_TOOL_MOUSE) | - BIT(BTN_TOOL_LENS) | - BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2)); - inputdev->mscbit[0] = BIT(MSC_SERIAL); - /* Programming the tablet macro keys needs to be done with a for loop - * as the keycodes are discontiguous. - */ + /* Set up key and button codes */ + for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i) + __set_bit(buttonEvents[i], inputdev->keybit); + for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) - set_bit(macroKeyEvents[i], inputdev->keybit); + __set_bit(macroKeyEvents[i], inputdev->keybit); /* * Program the input device coordinate capacities. We do not yet From 2fe574167be6a61d5f37c496da01c4a7daa73f4d Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:18:24 -0400 Subject: [PATCH 358/551] Input: aiptek - correct documentation on reports Small fix that corrects the documentation on the report byte format produced by the mouse Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 86e48930dfa2..86a750e88fbb 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -112,7 +112,7 @@ * (returned as Report 3 - absolute coordinates from the mouse) * * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 - * byte0 0 0 0 0 0 0 1 0 + * byte0 0 0 0 0 0 0 1 1 * byte1 X7 X6 X5 X4 X3 X2 X1 X0 * byte2 X15 X14 X13 X12 X11 X10 X9 X8 * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 @@ -134,7 +134,7 @@ * (returned as Report 5 - macrokeys from the mouse) * * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 - * byte0 0 0 0 0 0 1 0 0 + * byte0 0 0 0 0 0 1 0 1 * byte1 0 0 0 BS2 BS Tip IR DV * byte2 0 0 0 0 0 0 1 0 * byte3 0 0 0 K4 K3 K2 K1 K0 From fe981f2340edffcb6aad2203d8f14c9bef0e67e3 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:31:24 -0400 Subject: [PATCH 359/551] Input: aiptek - correct the proximity and validity checks Calculation of proximity bit and of data valid bits were reversed for stylus reports. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 86a750e88fbb..5aa8abf7ec85 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -508,8 +508,8 @@ static void aiptek_irq(struct urb *urb) y = le16_to_cpu(get_unaligned((__le16 *) (data + 3))); z = le16_to_cpu(get_unaligned((__le16 *) (data + 6))); - p = (data[5] & 0x01) != 0 ? 1 : 0; - dv = (data[5] & 0x02) != 0 ? 1 : 0; + dv = (data[5] & 0x01) != 0 ? 1 : 0; + p = (data[5] & 0x02) != 0 ? 1 : 0; tip = (data[5] & 0x04) != 0 ? 1 : 0; /* Use jitterable to re-arrange button masks @@ -587,8 +587,8 @@ static void aiptek_irq(struct urb *urb) jitterable = data[5] & 0x1c; - p = (data[5] & 0x01) != 0 ? 1 : 0; - dv = (data[5] & 0x02) != 0 ? 1 : 0; + dv = (data[5] & 0x01) != 0 ? 1 : 0; + p = (data[5] & 0x02) != 0 ? 1 : 0; left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; @@ -634,8 +634,8 @@ static void aiptek_irq(struct urb *urb) else if (data[0] == 4) { jitterable = data[1] & 0x18; - p = (data[1] & 0x01) != 0 ? 1 : 0; - dv = (data[1] & 0x02) != 0 ? 1 : 0; + dv = (data[1] & 0x01) != 0 ? 1 : 0; + p = (data[1] & 0x02) != 0 ? 1 : 0; tip = (data[1] & 0x04) != 0 ? 1 : 0; bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; @@ -684,8 +684,8 @@ static void aiptek_irq(struct urb *urb) else if (data[0] == 5) { jitterable = data[1] & 0x1c; - p = (data[1] & 0x01) != 0 ? 1 : 0; - dv = (data[1] & 0x02) != 0 ? 1 : 0; + dv = (data[1] & 0x01) != 0 ? 1 : 0; + p = (data[1] & 0x02) != 0 ? 1 : 0; left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; From ce0982edaec2c46dc9ec466e03f1fe94ee0862d8 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:31:45 -0400 Subject: [PATCH 360/551] Input: aiptek - fixed mouse button defines Mouse button defines tested the wrong bits, now fixed Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 5aa8abf7ec85..147ed340e6e1 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -264,9 +264,9 @@ /* Mouse button programming */ -#define AIPTEK_MOUSE_LEFT_BUTTON 0x01 -#define AIPTEK_MOUSE_RIGHT_BUTTON 0x02 -#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x04 +#define AIPTEK_MOUSE_LEFT_BUTTON 0x04 +#define AIPTEK_MOUSE_RIGHT_BUTTON 0x08 +#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10 /* Stylus button programming */ From 0038cae0ffd72b75699010bd112655dc2615e2fd Mon Sep 17 00:00:00 2001 From: Mark Vytlacil Date: Mon, 21 May 2007 00:31:50 -0400 Subject: [PATCH 361/551] Input: aiptek - fix relative mode parsing Corrections to relative mode, was looking at wrong byte Signed-off-by: Mark Vytlacil Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 147ed340e6e1..c18287724a1e 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -470,18 +470,20 @@ static void aiptek_irq(struct urb *urb) * that a non-zero value indicates that one or more * mouse button was pressed.) */ - jitterable = data[5] & 0x07; + jitterable = data[1] & 0x07; - left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; - right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; - middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; + left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0; + right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0; + middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0; input_report_key(inputdev, BTN_LEFT, left); input_report_key(inputdev, BTN_MIDDLE, middle); input_report_key(inputdev, BTN_RIGHT, right); + + input_report_abs(inputdev, ABS_MISC, + 1 | AIPTEK_REPORT_TOOL_UNKNOWN); input_report_rel(inputdev, REL_X, x); input_report_rel(inputdev, REL_Y, y); - input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN); /* Wheel support is in the form of a single-event * firing. From 1a54f49e8989462cfc9cab0c377b2d4e60e5b70a Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:31:55 -0400 Subject: [PATCH 362/551] Input: aiptek - use set_bit instead of bitwise or Have to use set_bit since some bit values are over 32, and bitwise or won't work on these. To be safe for the future too, use set_bit for all input dev capabilities Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index c18287724a1e..8c62afea5a52 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -329,6 +329,19 @@ struct aiptek { unsigned char *data; /* incoming packet data */ }; +static const int eventTypes[] = { + EV_KEY, EV_ABS, EV_REL, EV_MSC, +}; + +static const int absEvents[] = { + ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y, + ABS_WHEEL, ABS_MISC, +}; + +static const int relEvents[] = { + REL_X, REL_Y, REL_WHEEL, +}; + static const int buttonEvents[] = { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, @@ -1727,17 +1740,16 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Now program the capacities of the tablet, in terms of being * an input device. */ - inputdev->evbit[0] |= BIT(EV_KEY) - | BIT(EV_ABS) - | BIT(EV_REL) - | BIT(EV_MSC); + for (i = 0; i < ARRAY_SIZE(eventTypes); ++i) + __set_bit(eventTypes[i], inputdev->evbit); - inputdev->absbit[0] |= BIT(ABS_MISC); + for (i = 0; i < ARRAY_SIZE(absEvents); ++i) + __set_bit(absEvents[i], inputdev->absbit); - inputdev->relbit[0] |= - (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC)); + for (i = 0; i < ARRAY_SIZE(relEvents); ++i) + __set_bit(relEvents[i], inputdev->relbit); - inputdev->mscbit[0] = BIT(MSC_SERIAL); + __set_bit(MSC_SERIAL, inputdev->mscbit); /* Set up key and button codes */ for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i) From 6125a400354c4a02b9dad0e5d8128f9dc08cfd51 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:31:59 -0400 Subject: [PATCH 363/551] Input: aiptek - put sensible warnings in probe Added warnings to the points where the tablet probe may fail Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 8c62afea5a52..7fb15af33c49 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1670,17 +1670,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); inputdev = input_allocate_device(); - if (!aiptek || !inputdev) + if (!aiptek || !inputdev) { + warn("aiptek: cannot allocate memory or input device"); goto fail1; + } aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, GFP_ATOMIC, &aiptek->data_dma); - if (!aiptek->data) + if (!aiptek->data) { + warn("aiptek: cannot allocate usb buffer"); goto fail1; + } aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!aiptek->urb) + if (!aiptek->urb) { + warn("aiptek: cannot allocate urb"); goto fail2; + } aiptek->inputdev = inputdev; aiptek->usbdev = usbdev; @@ -1807,6 +1813,13 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) } } + /* Murphy says that some day someone will have a tablet that fails the + above test. That's you, Frederic Rodrigo */ + if (i == ARRAY_SIZE(speeds)) { + info("input: Aiptek tried all speeds, no sane response"); + goto fail2; + } + /* Associate this driver's struct with the usb interface. */ usb_set_intfdata(intf, aiptek); @@ -1814,15 +1827,18 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Set up the sysfs files */ err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); - if (err) + if (err) { + warn("aiptek: cannot create sysfs group err: %d", err); goto fail3; + } /* Register the tablet as an Input Device */ err = input_register_device(aiptek->inputdev); - if (err) + if (err) { + warn("aiptek: input_register_device returned err: %d", err); goto fail4; - + } return 0; fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); From da9fda434cde76dfb8174548a63b685b4ac00a9c Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:32:03 -0400 Subject: [PATCH 364/551] Input: aiptek - use only absolute misc reports To get an on - off reporting for proximity, absolute misc reports are used. The mixture of absolute and relative reports is awkward Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 7fb15af33c49..c7db623682de 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -417,6 +417,9 @@ static const char *map_val_to_str(const struct aiptek_map *map, int val) * Proximity. Why two events? I thought it interesting to know if the * Proximity event occurred while the tablet was in absolute or relative * mode. + * Update: REL_MISC proved not to be such a good idea. With REL_MISC you + * get an event transmitted each time. ABS_MISC works better, since it + * can be set and re-set. Thus, only using ABS_MISC from now on. * * Other tablets use the notion of a certain minimum stylus pressure * to infer proximity. While that could have been done, that is yet @@ -639,7 +642,7 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; } } - input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); + input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); input_sync(inputdev); } } From b3b6cf1d47508a04de859d357789a3fc0cf8c690 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:32:07 -0400 Subject: [PATCH 365/551] Input: aiptek - correct the tool switching code Now the old tool is remembered, and reset when a new tool is selected via the sysfs files. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 94 +++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index c7db623682de..0c78dc4ed5cf 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -218,15 +218,9 @@ #define AIPTEK_WHEEL_DISABLE (-10101) /* ToolCode values, which BTW are 0x140 .. 0x14f - * We have things set up such that if TOOL_BUTTON_FIRED_BIT is - * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx. - * - * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will - * get reset. + * We have things set up such that if the tool button has changed, + * the tools get reset. */ -#define TOOL_BUTTON(x) ((x) & 0x14f) -#define TOOL_BUTTON_FIRED(x) ((x) & 0x200) -#define TOOL_BUTTON_FIRED_BIT 0x200 /* toolMode codes */ #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN @@ -326,6 +320,9 @@ struct aiptek { int inDelay; /* jitter: in jitter delay? */ unsigned long endDelay; /* jitter: time when delay ends */ int previousJitterable; /* jitterable prev value */ + + int lastMacro; /* macro key to reset */ + int previousToolMode; /* pen, pencil, brush, etc. tool */ unsigned char *data; /* incoming packet data */ }; @@ -542,16 +539,18 @@ static void aiptek_irq(struct urb *urb) * all 'bad' reports... */ if (dv != 0) { - /* If we've not already sent a tool_button_?? code, do - * so now. Then set FIRED_BIT so it won't be resent unless - * the user forces FIRED_BIT off. + /* If the selected tool changed, reset the old + * tool key, and set the new one. */ - if (TOOL_BUTTON_FIRED - (aiptek->curSetting.toolMode) == 0) { + if (aiptek->previousToolMode != + aiptek->curSetting.toolMode) { + input_report_key(inputdev, + aiptek->previousToolMode, 0); input_report_key(inputdev, - TOOL_BUTTON(aiptek->curSetting.toolMode), + aiptek->curSetting.toolMode, 1); - aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; + aiptek->previousToolMode = + aiptek->curSetting.toolMode; } if (p != 0) { @@ -612,16 +611,18 @@ static void aiptek_irq(struct urb *urb) middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; if (dv != 0) { - /* If we've not already sent a tool_button_?? code, do - * so now. Then set FIRED_BIT so it won't be resent unless - * the user forces FIRED_BIT off. + /* If the selected tool changed, reset the old + * tool key, and set the new one. */ - if (TOOL_BUTTON_FIRED - (aiptek->curSetting.toolMode) == 0) { + if (aiptek->previousToolMode != + aiptek->curSetting.toolMode) { + input_report_key(inputdev, + aiptek->previousToolMode, 0); input_report_key(inputdev, - TOOL_BUTTON(aiptek->curSetting.toolMode), + aiptek->curSetting.toolMode, 1); - aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; + aiptek->previousToolMode = + aiptek->curSetting.toolMode; } if (p != 0) { @@ -662,15 +663,18 @@ static void aiptek_irq(struct urb *urb) z = le16_to_cpu(get_unaligned((__le16 *) (data + 4))); if (dv != 0) { - /* If we've not already sent a tool_button_?? code, do - * so now. Then set FIRED_BIT so it won't be resent unless - * the user forces FIRED_BIT off. + /* If the selected tool changed, reset the old + * tool key, and set the new one. */ - if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { + if (aiptek->previousToolMode != + aiptek->curSetting.toolMode) { + input_report_key(inputdev, + aiptek->previousToolMode, 0); input_report_key(inputdev, - TOOL_BUTTON(aiptek->curSetting.toolMode), + aiptek->curSetting.toolMode, 1); - aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; + aiptek->previousToolMode = + aiptek->curSetting.toolMode; } if (p != 0) { @@ -710,15 +714,18 @@ static void aiptek_irq(struct urb *urb) macro = data[3]; if (dv != 0) { - /* If we've not already sent a tool_button_?? code, do - * so now. Then set FIRED_BIT so it won't be resent unless - * the user forces FIRED_BIT off. + /* If the selected tool changed, reset the old + * tool key, and set the new one. */ - if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { + if (aiptek->previousToolMode != + aiptek->curSetting.toolMode) { + input_report_key(inputdev, + aiptek->previousToolMode, 0); input_report_key(inputdev, - TOOL_BUTTON(aiptek->curSetting.toolMode), + aiptek->curSetting.toolMode, 1); - aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; + aiptek->previousToolMode = + aiptek->curSetting.toolMode; } if (p != 0) { @@ -762,15 +769,18 @@ static void aiptek_irq(struct urb *urb) 0); } - /* If we've not already sent a tool_button_?? code, do - * so now. Then set FIRED_BIT so it won't be resent unless - * the user forces FIRED_BIT off. - */ - if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { + /* If the selected tool changed, reset the old + tool key, and set the new one. + */ + if (aiptek->previousToolMode != + aiptek->curSetting.toolMode) { + input_report_key(inputdev, + aiptek->previousToolMode, 0); input_report_key(inputdev, - TOOL_BUTTON(aiptek->curSetting. - toolMode), 1); - aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; + aiptek->curSetting.toolMode, + 1); + aiptek->previousToolMode = + aiptek->curSetting.toolMode; } input_report_key(inputdev, macroKeyEvents[macro], 1); From 0112db36ef95e5632db071297f7df130725c47b9 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:32:12 -0400 Subject: [PATCH 366/551] Input: aiptek - tolerate newlines in sysfs files Now echo "some value" > /sys/......./somefile is also acceptable. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 0c78dc4ed5cf..54c8d6f49833 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -375,8 +375,11 @@ static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t { const struct aiptek_map *p; + if (str[count - 1] == '\n') + count--; + for (p = map; p->string; p++) - if (!strncmp(str, p->string, count)) + if (!strncmp(str, p->string, count)) return p->value; return AIPTEK_INVALID_VALUE; From 1e7b3faed1793e7637a774240ae22541c5ba6ca0 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:32:17 -0400 Subject: [PATCH 367/551] Input: aiptek - rework the function key code Function keys (also called macro keys) code corrected. Using a lastMacro variable to keep track of key currently pressed. This ensures proper resetting when dragging the pen in the drawing area or to another key. Also suppress sending pressure reports when over the macro key area. Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 107 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 54c8d6f49833..292eb507e5d3 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -509,6 +509,11 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.wheel); aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; } + if (aiptek->lastMacro != -1) { + input_report_key(inputdev, + macroKeyEvents[aiptek->lastMacro], 0); + aiptek->lastMacro = -1; + } input_sync(inputdev); } } @@ -589,6 +594,11 @@ static void aiptek_irq(struct urb *urb) } } input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); + if (aiptek->lastMacro != -1) { + input_report_key(inputdev, + macroKeyEvents[aiptek->lastMacro], 0); + aiptek->lastMacro = -1; + } input_sync(inputdev); } } @@ -647,6 +657,11 @@ static void aiptek_irq(struct urb *urb) } } input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); + if (aiptek->lastMacro != -1) { + input_report_key(inputdev, + macroKeyEvents[aiptek->lastMacro], 0); + aiptek->lastMacro = -1; + } input_sync(inputdev); } } @@ -662,10 +677,10 @@ static void aiptek_irq(struct urb *urb) bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; - macro = data[3]; + macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1; z = le16_to_cpu(get_unaligned((__le16 *) (data + 4))); - if (dv != 0) { + if (dv) { /* If the selected tool changed, reset the old * tool key, and set the new one. */ @@ -679,30 +694,20 @@ static void aiptek_irq(struct urb *urb) aiptek->previousToolMode = aiptek->curSetting.toolMode; } - - if (p != 0) { - input_report_key(inputdev, BTN_TOUCH, tip); - input_report_key(inputdev, BTN_STYLUS, bs); - input_report_key(inputdev, BTN_STYLUS2, pck); - input_report_abs(inputdev, ABS_PRESSURE, z); - } - - /* For safety, we're sending key 'break' codes for the - * neighboring macro keys. - */ - if (macro > 0) { - input_report_key(inputdev, - macroKeyEvents[macro - 1], 0); - } - if (macro < 25) { - input_report_key(inputdev, - macroKeyEvents[macro + 1], 0); - } - input_report_key(inputdev, macroKeyEvents[macro], p); - input_report_abs(inputdev, ABS_MISC, - p | AIPTEK_REPORT_TOOL_STYLUS); - input_sync(inputdev); } + + if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { + input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); + aiptek->lastMacro = -1; + } + + if (macro != -1 && macro != aiptek->lastMacro) { + input_report_key(inputdev, macroKeyEvents[macro], 1); + aiptek->lastMacro = macro; + } + input_report_abs(inputdev, ABS_MISC, + p | AIPTEK_REPORT_TOOL_STYLUS); + input_sync(inputdev); } /* Report 5s come from the macro keys when pressed by mouse */ @@ -714,46 +719,35 @@ static void aiptek_irq(struct urb *urb) left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; - macro = data[3]; + macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0; - if (dv != 0) { + if (dv) { /* If the selected tool changed, reset the old * tool key, and set the new one. */ if (aiptek->previousToolMode != aiptek->curSetting.toolMode) { - input_report_key(inputdev, + input_report_key(inputdev, aiptek->previousToolMode, 0); - input_report_key(inputdev, - aiptek->curSetting.toolMode, - 1); - aiptek->previousToolMode = - aiptek->curSetting.toolMode; + input_report_key(inputdev, + aiptek->curSetting.toolMode, 1); + aiptek->previousToolMode = aiptek->curSetting.toolMode; } - - if (p != 0) { - input_report_key(inputdev, BTN_LEFT, left); - input_report_key(inputdev, BTN_MIDDLE, middle); - input_report_key(inputdev, BTN_RIGHT, right); - } - - /* For safety, we're sending key 'break' codes for the - * neighboring macro keys. - */ - if (macro > 0) { - input_report_key(inputdev, - macroKeyEvents[macro - 1], 0); - } - if (macro < 25) { - input_report_key(inputdev, - macroKeyEvents[macro + 1], 0); - } - - input_report_key(inputdev, macroKeyEvents[macro], 1); - input_report_rel(inputdev, ABS_MISC, - p | AIPTEK_REPORT_TOOL_MOUSE); - input_sync(inputdev); } + + if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { + input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); + aiptek->lastMacro = -1; + } + + if (macro != -1 && macro != aiptek->lastMacro) { + input_report_key(inputdev, macroKeyEvents[macro], 1); + aiptek->lastMacro = macro; + } + + input_report_abs(inputdev, ABS_MISC, + p | AIPTEK_REPORT_TOOL_MOUSE); + input_sync(inputdev); } /* We have no idea which tool can generate a report 6. Theoretically, * neither need to, having been given reports 4 & 5 for such use. @@ -1710,6 +1704,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) aiptek->inDelay = 0; aiptek->endDelay = 0; aiptek->previousJitterable = 0; + aiptek->lastMacro = -1; /* Set up the curSettings struct. Said struct contains the current * programmable parameters. The newSetting struct contains changes From 5035522d1a6b55f95e7e01c209b57f5d89f88b16 Mon Sep 17 00:00:00 2001 From: Rene van Paassen Date: Mon, 21 May 2007 00:32:21 -0400 Subject: [PATCH 368/551] Input: aiptek - update driver version Update credits and version number to 2.3 Signed-off-by: Rene van Paassen Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 292eb507e5d3..94683f58c9e1 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -82,8 +82,8 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.5 (May-15-2004)" -#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio" +#define DRIVER_VERSION "v2.3 (May 2, 2007)" +#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen" #define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)" /* From a4da16d3838669d7fb096ea5d1e4917e5ca4dc16 Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Mon, 21 May 2007 00:46:22 -0400 Subject: [PATCH 369/551] Input: wriston - reduce polling frequency Reduces the polling frequency from 10 Hz to 2 Hz, which should be less a burden for laptops wrt energy saving. As it is multimedia keys, 500ms (maximum) of latency should be still fine for the user. In order to keep fluent the feeling when the user is pressing several keys in a raw (such as changing the volume), the frequency is increased for a short duration after a key is pressed. Signed-off-by: Eric Piel Signed-off-by: Dmitry Torokhov --- drivers/input/misc/wistron_btns.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 961aad7a0476..320262aa4c17 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,9 +38,10 @@ */ #define MAX_POLL_ITERATIONS 64 -#define POLL_FREQUENCY 10 /* Number of polls per second */ +#define POLL_FREQUENCY 2 /* Number of polls per second when idle */ +#define POLL_FREQUENCY_BURST 10 /* Polls per second when a key was recently pressed */ -#if POLL_FREQUENCY > HZ +#if POLL_FREQUENCY_BURST > HZ #error "POLL_FREQUENCY too high" #endif @@ -1079,6 +1081,8 @@ static void handle_key(u8 code) static void poll_bios(unsigned long discard) { + static unsigned long jiffies_last_press; + unsigned long jiffies_now = jiffies; u8 qlen; u16 val; @@ -1087,11 +1091,17 @@ static void poll_bios(unsigned long discard) if (qlen == 0) break; val = bios_pop_queue(); - if (val != 0 && !discard) + if (val != 0 && !discard) { handle_key((u8)val); + jiffies_last_press = jiffies_now; + } } - mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); + /* Increase precision if user is currently pressing keys (< 2s ago) */ + if (time_after(jiffies_last_press, jiffies_now - (HZ * 2))) + mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY_BURST); + else + mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY); } static int __devinit wistron_probe(struct platform_device *dev) From 389679d8faa38bb6d069d9e1805f15e3cb9a6d7f Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Mon, 21 May 2007 00:46:31 -0400 Subject: [PATCH 370/551] Input: wistron - add LED support Add support to wistron_btns for leds that come with the multimedia keys. Mail and wifi leds are supported, on laptops which have them. Depending on the laptop, wifi subsystem may control just the led, or both the led and the wifi card. Wifi led interface is activated only for the former type of laptops, as the latter type is already managed. Leds are controled by the interface in /sys/class/leds. Signed-off-by: Eric Piel Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 5 +- drivers/input/misc/wistron_btns.c | 88 ++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 88e29074ac90..4326f536f849 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -65,9 +65,12 @@ config INPUT_COBALT_BTNS config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 + select NEW_LEDS + select LEDS_CLASS help Say Y here for support of Winstron laptop button interface, used on - laptops of various brands, including Acer and Fujitsu-Siemens. + laptops of various brands, including Acer and Fujitsu-Siemens. If + available, mail and wifi leds will be controlable via /sys/class/leds. To compile this driver as a module, choose M here: the module will be called wistron_btns. diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 320262aa4c17..d58ddcab601f 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * Number of attempts to read data from queue per poll; @@ -48,11 +49,12 @@ /* BIOS subsystem IDs */ #define WIFI 0x35 #define BLUETOOTH 0x34 +#define MAIL_LED 0x31 MODULE_AUTHOR("Miloslav Trmac "); MODULE_DESCRIPTION("Wistron laptop button driver"); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.2"); +MODULE_VERSION("0.3"); static int force; /* = 0; */ module_param(force, bool, 0); @@ -253,6 +255,7 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; static const struct key_entry *keymap; /* = NULL; Current key map */ static int have_wifi; static int have_bluetooth; +static int have_leds; static int __init dmi_matched(struct dmi_system_id *dmi) { @@ -265,6 +268,8 @@ static int __init dmi_matched(struct dmi_system_id *dmi) else if (key->type == KE_BLUETOOTH) have_bluetooth = 1; } + have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED); + return 1; } @@ -1030,6 +1035,83 @@ static void report_switch(unsigned code, int value) input_sync(input_dev); } + + /* led management */ +static void wistron_mail_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0); +} + +/* same as setting up wifi card, but for laptops on which the led is managed */ +static void wistron_wifi_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0); +} + +static struct led_classdev wistron_mail_led = { + .name = "mail:green", + .brightness_set = wistron_mail_led_set, +}; + +static struct led_classdev wistron_wifi_led = { + .name = "wifi:red", + .brightness_set = wistron_wifi_led_set, +}; + +static void __devinit wistron_led_init(struct device *parent) +{ + if (have_leds & FE_WIFI_LED) { + u16 wifi = bios_get_default_setting(WIFI); + if (wifi & 1) { + wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF; + if (led_classdev_register(parent, &wistron_wifi_led)) + have_leds &= ~FE_WIFI_LED; + else + bios_set_state(WIFI, wistron_wifi_led.brightness); + + } else + have_leds &= ~FE_WIFI_LED; + } + + if (have_leds & FE_MAIL_LED) { + /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */ + wistron_mail_led.brightness = LED_OFF; + if (led_classdev_register(parent, &wistron_mail_led)) + have_leds &= ~FE_MAIL_LED; + else + bios_set_state(MAIL_LED, wistron_mail_led.brightness); + } +} + +static void __devexit wistron_led_remove(void) +{ + if (have_leds & FE_MAIL_LED) + led_classdev_unregister(&wistron_mail_led); + + if (have_leds & FE_WIFI_LED) + led_classdev_unregister(&wistron_wifi_led); +} + +static inline void wistron_led_suspend(void) +{ + if (have_leds & FE_MAIL_LED) + led_classdev_suspend(&wistron_mail_led); + + if (have_leds & FE_WIFI_LED) + led_classdev_suspend(&wistron_wifi_led); +} + +static inline void wistron_led_resume(void) +{ + if (have_leds & FE_MAIL_LED) + led_classdev_resume(&wistron_mail_led); + + if (have_leds & FE_WIFI_LED) + led_classdev_resume(&wistron_wifi_led); +} + /* Driver core */ static int wifi_enabled; @@ -1135,6 +1217,7 @@ static int __devinit wistron_probe(struct platform_device *dev) bios_set_state(BLUETOOTH, bluetooth_enabled); } + wistron_led_init(&dev->dev); poll_bios(1); /* Flush stale event queue and arm timer */ return 0; @@ -1143,6 +1226,7 @@ static int __devinit wistron_probe(struct platform_device *dev) static int __devexit wistron_remove(struct platform_device *dev) { del_timer_sync(&poll_timer); + wistron_led_remove(); input_unregister_device(input_dev); bios_detach(); @@ -1160,6 +1244,7 @@ static int wistron_suspend(struct platform_device *dev, pm_message_t state) if (have_bluetooth) bios_set_state(BLUETOOTH, 0); + wistron_led_suspend(); return 0; } @@ -1171,6 +1256,7 @@ static int wistron_resume(struct platform_device *dev) if (have_bluetooth) bios_set_state(BLUETOOTH, bluetooth_enabled); + wistron_led_resume(); poll_bios(1); return 0; From c2554c91425a86e5d0409a76b7ddcb328362f08b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 22 May 2007 23:48:39 -0400 Subject: [PATCH 371/551] Input: wistron - convert to use input-polldev Switch to using input-polldev skeleton instead of implementing polling loop by itself. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 1 + drivers/input/misc/wistron_btns.c | 200 +++++++++++++++--------------- 2 files changed, 102 insertions(+), 99 deletions(-) diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 4326f536f849..9b26574f1466 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -65,6 +65,7 @@ config INPUT_COBALT_BTNS config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 + select INPUT_POLLDEV select NEW_LEDS select LEDS_CLASS help diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index d58ddcab601f..622630f051a5 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,23 +28,13 @@ #include #include #include -#include #include #include #include -/* - * Number of attempts to read data from queue per poll; - * the queue can hold up to 31 entries - */ -#define MAX_POLL_ITERATIONS 64 - -#define POLL_FREQUENCY 2 /* Number of polls per second when idle */ -#define POLL_FREQUENCY_BURST 10 /* Polls per second when a key was recently pressed */ - -#if POLL_FREQUENCY_BURST > HZ -#error "POLL_FREQUENCY too high" -#endif +/* How often we poll keys - msecs */ +#define POLL_INTERVAL_DEFAULT 500 /* when idle */ +#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */ /* BIOS subsystem IDs */ #define WIFI 0x35 @@ -973,66 +963,23 @@ static int __init select_keymap(void) /* Input layer interface */ -static struct input_dev *input_dev; +static struct input_polled_dev *wistron_idev; +static unsigned long jiffies_last_press; +static int wifi_enabled; +static int bluetooth_enabled; -static int __devinit setup_input_dev(void) +static void report_key(struct input_dev *dev, unsigned int keycode) { - const struct key_entry *key; - int error; - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - input_dev->name = "Wistron laptop buttons"; - input_dev->phys = "wistron/input0"; - input_dev->id.bustype = BUS_HOST; - input_dev->cdev.dev = &wistron_device->dev; - - for (key = keymap; key->type != KE_END; key++) { - switch (key->type) { - case KE_KEY: - set_bit(EV_KEY, input_dev->evbit); - set_bit(key->keycode, input_dev->keybit); - break; - - case KE_SW: - set_bit(EV_SW, input_dev->evbit); - set_bit(key->sw.code, input_dev->swbit); - break; - - default: - ; - } - } - - /* reads information flags on KE_END */ - if (key->code & FE_UNTESTED) - printk(KERN_WARNING "Untested laptop multimedia keys, " - "please report success or failure to eric.piel" - "@tremplin-utc.net\n"); - - error = input_register_device(input_dev); - if (error) { - input_free_device(input_dev); - return error; - } - - return 0; + input_report_key(dev, keycode, 1); + input_sync(dev); + input_report_key(dev, keycode, 0); + input_sync(dev); } -static void report_key(unsigned keycode) +static void report_switch(struct input_dev *dev, unsigned int code, int value) { - input_report_key(input_dev, keycode, 1); - input_sync(input_dev); - input_report_key(input_dev, keycode, 0); - input_sync(input_dev); -} - -static void report_switch(unsigned code, int value) -{ - input_report_switch(input_dev, code, value); - input_sync(input_dev); + input_report_switch(dev, code, value); + input_sync(dev); } @@ -1112,15 +1059,6 @@ static inline void wistron_led_resume(void) led_classdev_resume(&wistron_wifi_led); } - /* Driver core */ - -static int wifi_enabled; -static int bluetooth_enabled; - -static void poll_bios(unsigned long); - -static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0); - static void handle_key(u8 code) { const struct key_entry *key; @@ -1129,11 +1067,12 @@ static void handle_key(u8 code) if (code == key->code) { switch (key->type) { case KE_KEY: - report_key(key->keycode); + report_key(wistron_idev->input, key->keycode); break; case KE_SW: - report_switch(key->sw.code, key->sw.value); + report_switch(wistron_idev->input, + key->sw.code, key->sw.value); break; case KE_WIFI: @@ -1152,19 +1091,19 @@ static void handle_key(u8 code) case KE_END: break; + default: BUG(); } + jiffies_last_press = jiffies; return; } } printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); } -static void poll_bios(unsigned long discard) +static void poll_bios(bool discard) { - static unsigned long jiffies_last_press; - unsigned long jiffies_now = jiffies; u8 qlen; u16 val; @@ -1173,24 +1112,85 @@ static void poll_bios(unsigned long discard) if (qlen == 0) break; val = bios_pop_queue(); - if (val != 0 && !discard) { + if (val != 0 && !discard) handle_key((u8)val); - jiffies_last_press = jiffies_now; + } +} + +static void wistron_flush(struct input_polled_dev *dev) +{ + /* Flush stale event queue */ + poll_bios(true); +} + +static void wistron_poll(struct input_polled_dev *dev) +{ + poll_bios(false); + + /* Increase poll frequency if user is currently pressing keys (< 2s ago) */ + if (time_before(jiffies, jiffies_last_press + 2 * HZ)) + dev->poll_interval = POLL_INTERVAL_BURST; + else + dev->poll_interval = POLL_INTERVAL_DEFAULT; +} + +static int __devinit setup_input_dev(void) +{ + const struct key_entry *key; + struct input_dev *input_dev; + int error; + + wistron_idev = input_allocate_polled_device(); + if (!wistron_idev) + return -ENOMEM; + + wistron_idev->flush = wistron_flush; + wistron_idev->poll = wistron_poll; + wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; + + input_dev = wistron_idev->input; + input_dev->name = "Wistron laptop buttons"; + input_dev->phys = "wistron/input0"; + input_dev->id.bustype = BUS_HOST; + input_dev->cdev.dev = &wistron_device->dev; + + for (key = keymap; key->type != KE_END; key++) { + switch (key->type) { + case KE_KEY: + set_bit(EV_KEY, input_dev->evbit); + set_bit(key->keycode, input_dev->keybit); + break; + + case KE_SW: + set_bit(EV_SW, input_dev->evbit); + set_bit(key->sw.code, input_dev->swbit); + break; + + default: + break; } } - /* Increase precision if user is currently pressing keys (< 2s ago) */ - if (time_after(jiffies_last_press, jiffies_now - (HZ * 2))) - mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY_BURST); - else - mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY); + /* reads information flags on KE_END */ + if (key->code & FE_UNTESTED) + printk(KERN_WARNING "Untested laptop multimedia keys, " + "please report success or failure to eric.piel" + "@tremplin-utc.net\n"); + + error = input_register_polled_device(wistron_idev); + if (error) { + input_free_polled_device(wistron_idev); + return error; + } + + return 0; } +/* Driver core */ + static int __devinit wistron_probe(struct platform_device *dev) { - int err = setup_input_dev(); - if (err) - return err; + int err; bios_attach(); cmos_address = bios_get_cmos_address(); @@ -1218,16 +1218,20 @@ static int __devinit wistron_probe(struct platform_device *dev) } wistron_led_init(&dev->dev); - poll_bios(1); /* Flush stale event queue and arm timer */ + err = setup_input_dev(); + if (err) { + bios_detach(); + return err; + } return 0; } static int __devexit wistron_remove(struct platform_device *dev) { - del_timer_sync(&poll_timer); wistron_led_remove(); - input_unregister_device(input_dev); + input_unregister_polled_device(wistron_idev); + input_free_polled_device(wistron_idev); bios_detach(); return 0; @@ -1236,8 +1240,6 @@ static int __devexit wistron_remove(struct platform_device *dev) #ifdef CONFIG_PM static int wistron_suspend(struct platform_device *dev, pm_message_t state) { - del_timer_sync(&poll_timer); - if (have_wifi) bios_set_state(WIFI, 0); @@ -1257,7 +1259,7 @@ static int wistron_resume(struct platform_device *dev) bios_set_state(BLUETOOTH, bluetooth_enabled); wistron_led_resume(); - poll_bios(1); + poll_bios(true); return 0; } From d63219a10126b878abbbffdf4c5bcf29ef756b7f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 14 Jun 2007 23:31:45 -0400 Subject: [PATCH 372/551] Input: wistron - add support for querying/changing keymap Implement getkeycode and setkeycode methods for the device so EVIOCGKEYCODE and EVIOCSKEYCODE ioctls will work. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/wistron_btns.c | 125 +++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 622630f051a5..60121f10f8d9 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -242,7 +242,7 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; #define FE_WIFI_LED 0x02 #define FE_UNTESTED 0x80 -static const struct key_entry *keymap; /* = NULL; Current key map */ +static struct key_entry *keymap; /* = NULL; Current key map */ static int have_wifi; static int have_bluetooth; static int have_leds; @@ -1059,47 +1059,64 @@ static inline void wistron_led_resume(void) led_classdev_resume(&wistron_wifi_led); } +static struct key_entry *wistron_get_entry_by_scancode(int code) +{ + struct key_entry *key; + + for (key = keymap; key->type != KE_END; key++) + if (code == key->code) + return key; + + return NULL; +} + +static struct key_entry *wistron_get_entry_by_keycode(int keycode) +{ + struct key_entry *key; + + for (key = keymap; key->type != KE_END; key++) + if (key->type == KE_KEY && keycode == key->keycode) + return key; + + return NULL; +} + static void handle_key(u8 code) { - const struct key_entry *key; + const struct key_entry *key = wistron_get_entry_by_scancode(code); - for (key = keymap; key->type != KE_END; key++) { - if (code == key->code) { - switch (key->type) { - case KE_KEY: - report_key(wistron_idev->input, key->keycode); - break; + if (key) { + switch (key->type) { + case KE_KEY: + report_key(wistron_idev->input, key->keycode); + break; - case KE_SW: - report_switch(wistron_idev->input, - key->sw.code, key->sw.value); - break; + case KE_SW: + report_switch(wistron_idev->input, + key->sw.code, key->sw.value); + break; - case KE_WIFI: - if (have_wifi) { - wifi_enabled = !wifi_enabled; - bios_set_state(WIFI, wifi_enabled); - } - break; - - case KE_BLUETOOTH: - if (have_bluetooth) { - bluetooth_enabled = !bluetooth_enabled; - bios_set_state(BLUETOOTH, bluetooth_enabled); - } - break; - - case KE_END: - break; - - default: - BUG(); + case KE_WIFI: + if (have_wifi) { + wifi_enabled = !wifi_enabled; + bios_set_state(WIFI, wifi_enabled); } - jiffies_last_press = jiffies; - return; + break; + + case KE_BLUETOOTH: + if (have_bluetooth) { + bluetooth_enabled = !bluetooth_enabled; + bios_set_state(BLUETOOTH, bluetooth_enabled); + } + break; + + default: + BUG(); } - } - printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); + jiffies_last_press = jiffies; + } else + printk(KERN_NOTICE + "wistron_btns: Unknown key code %02X\n", code); } static void poll_bios(bool discard) @@ -1134,6 +1151,39 @@ static void wistron_poll(struct input_polled_dev *dev) dev->poll_interval = POLL_INTERVAL_DEFAULT; } +static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) +{ + const struct key_entry *key = wistron_get_entry_by_scancode(scancode); + + if (key && key->type == KE_KEY) { + *keycode = key->keycode; + return 0; + } + + return -EINVAL; +} + +static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) +{ + struct key_entry *key; + int old_keycode; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + key = wistron_get_entry_by_scancode(scancode); + if (key && key->type == KE_KEY) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (!wistron_get_entry_by_keycode(old_keycode)) + clear_bit(old_keycode, dev->keybit); + return 0; + } + + return -EINVAL; +} + static int __devinit setup_input_dev(void) { const struct key_entry *key; @@ -1152,7 +1202,10 @@ static int __devinit setup_input_dev(void) input_dev->name = "Wistron laptop buttons"; input_dev->phys = "wistron/input0"; input_dev->id.bustype = BUS_HOST; - input_dev->cdev.dev = &wistron_device->dev; + input_dev->dev.parent = &wistron_device->dev; + + input_dev->getkeycode = wistron_getkeycode; + input_dev->setkeycode = wistron_setkeycode; for (key = keymap; key->type != KE_END; key++) { switch (key->type) { From 9657d75c5f0f7d0a9cb507521d3ad1436aea28c9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 14 Jun 2007 23:32:24 -0400 Subject: [PATCH 373/551] Input: convert from class devices to standard devices Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 84 ++++++------- drivers/input/input.c | 136 ++++++++++---------- drivers/input/joydev.c | 84 +++++++------ drivers/input/mousedev.c | 260 +++++++++++++++++++++------------------ drivers/input/tsdev.c | 88 ++++++------- include/linux/input.h | 20 +-- 6 files changed, 354 insertions(+), 318 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index be6b93c20f60..ab4b2d9b5327 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -30,6 +30,7 @@ struct evdev { wait_queue_head_t wait; struct evdev_client *grab; struct list_head client_list; + struct device dev; }; struct evdev_client { @@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id) return input_flush_device(&evdev->handle, file); } -static void evdev_free(struct evdev *evdev) +static void evdev_free(struct device *dev) { + struct evdev *evdev = container_of(dev, struct evdev, dev); + evdev_table[evdev->minor] = NULL; kfree(evdev); } @@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--evdev->open) { - if (evdev->exist) - input_close_device(&evdev->handle); - else - evdev_free(evdev); - } + if (!--evdev->open && evdev->exist) + input_close_device(&evdev->handle); + + put_device(&evdev->dev); return 0; } @@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file) if (!evdev || !evdev->exist) return -ENODEV; + get_device(&evdev->dev); + client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); - if (!client) - return -ENOMEM; + if (!client) { + error = -ENOMEM; + goto err_put_evdev; + } client->evdev = evdev; list_add_tail(&client->node, &evdev->client_list); if (!evdev->open++ && evdev->exist) { error = input_open_device(&evdev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } + if (error) + goto err_free_client; } file->private_data = client; return 0; + + err_free_client: + list_del(&client->node); + kfree(client); + err_put_evdev: + put_device(&evdev->dev); + return error; } #ifdef CONFIG_COMPAT @@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { struct evdev *evdev; - struct class_device *cdev; - dev_t devt; int minor; int error; @@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, evdev->handle.name = evdev->name; evdev->handle.handler = handler; evdev->handle.private = evdev; - sprintf(evdev->name, "event%d", minor); + snprintf(evdev->name, sizeof(evdev->name), "event%d", minor); + + snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id), + "event%d", minor); + evdev->dev.class = &input_class; + evdev->dev.parent = &dev->dev; + evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); + evdev->dev.release = evdev_free; + device_initialize(&evdev->dev); evdev_table[minor] = evdev; - devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, evdev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_evdev; - } - - /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, evdev->name); + error = device_add(&evdev->dev); if (error) - goto err_cdev_destroy; + goto err_free_evdev; error = input_register_handle(&evdev->handle); if (error) - goto err_remove_link; + goto err_delete_evdev; return 0; - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, evdev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); + err_delete_evdev: + device_del(&evdev->dev); err_free_evdev: - kfree(evdev); - evdev_table[minor] = NULL; + put_device(&evdev->dev); return error; } @@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle) struct evdev_client *client; input_unregister_handle(handle); + device_del(&evdev->dev); - sysfs_remove_link(&input_class.subsys.kobj, evdev->name); - class_device_destroy(&input_class, - MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; if (evdev->open) { @@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle) list_for_each_entry(client, &evdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&evdev->wait); - } else - evdev_free(evdev); + } + + put_device(&evdev->dev); } static const struct input_device_id evdev_ids[] = { diff --git a/drivers/input/input.c b/drivers/input/input.c index ccd8abafcb70..75b4d2a83dd9 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -442,7 +442,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han printk(KERN_ERR "input: failed to attach handler %s to device %s, " "error: %d\n", - handler->name, kobject_name(&dev->cdev.kobj), error); + handler->name, kobject_name(&dev->dev.kobj), error); return error; } @@ -527,7 +527,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, static int input_devices_seq_show(struct seq_file *seq, void *v) { struct input_dev *dev = container_of(v, struct input_dev, node); - const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); + const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); struct input_handle *handle; seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", @@ -682,15 +682,17 @@ static inline int input_proc_init(void) { return 0; } static inline void input_proc_exit(void) { } #endif -#define INPUT_DEV_STRING_ATTR_SHOW(name) \ -static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - \ - return scnprintf(buf, PAGE_SIZE, "%s\n", \ - input_dev->name ? input_dev->name : ""); \ -} \ -static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL); +#define INPUT_DEV_STRING_ATTR_SHOW(name) \ +static ssize_t input_dev_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + \ + return scnprintf(buf, PAGE_SIZE, "%s\n", \ + input_dev->name ? input_dev->name : ""); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL) INPUT_DEV_STRING_ATTR_SHOW(name); INPUT_DEV_STRING_ATTR_SHOW(phys); @@ -744,7 +746,9 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id, return len; } -static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) +static ssize_t input_dev_show_modalias(struct device *dev, + struct device_attribute *attr, + char *buf) { struct input_dev *id = to_input_dev(dev); ssize_t len; @@ -753,13 +757,13 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) return min_t(int, len, PAGE_SIZE); } -static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); +static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); static struct attribute *input_dev_attrs[] = { - &class_device_attr_name.attr, - &class_device_attr_phys.attr, - &class_device_attr_uniq.attr, - &class_device_attr_modalias.attr, + &dev_attr_name.attr, + &dev_attr_phys.attr, + &dev_attr_uniq.attr, + &dev_attr_modalias.attr, NULL }; @@ -767,13 +771,15 @@ static struct attribute_group input_dev_attr_group = { .attrs = input_dev_attrs, }; -#define INPUT_DEV_ID_ATTR(name) \ -static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ -} \ -static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); +#define INPUT_DEV_ID_ATTR(name) \ +static ssize_t input_dev_show_id_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL) INPUT_DEV_ID_ATTR(bustype); INPUT_DEV_ID_ATTR(vendor); @@ -781,10 +787,10 @@ INPUT_DEV_ID_ATTR(product); INPUT_DEV_ID_ATTR(version); static struct attribute *input_dev_id_attrs[] = { - &class_device_attr_bustype.attr, - &class_device_attr_vendor.attr, - &class_device_attr_product.attr, - &class_device_attr_version.attr, + &dev_attr_bustype.attr, + &dev_attr_vendor.attr, + &dev_attr_product.attr, + &dev_attr_version.attr, NULL }; @@ -813,15 +819,17 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, return len; } -#define INPUT_DEV_CAP_ATTR(ev, bm) \ -static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ -{ \ - struct input_dev *input_dev = to_input_dev(dev); \ - int len = input_print_bitmap(buf, PAGE_SIZE, \ - input_dev->bm##bit, ev##_MAX, 1); \ - return min_t(int, len, PAGE_SIZE); \ -} \ -static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); +#define INPUT_DEV_CAP_ATTR(ev, bm) \ +static ssize_t input_dev_show_cap_##bm(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct input_dev *input_dev = to_input_dev(dev); \ + int len = input_print_bitmap(buf, PAGE_SIZE, \ + input_dev->bm##bit, ev##_MAX, 1); \ + return min_t(int, len, PAGE_SIZE); \ +} \ +static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) INPUT_DEV_CAP_ATTR(EV, ev); INPUT_DEV_CAP_ATTR(KEY, key); @@ -834,15 +842,15 @@ INPUT_DEV_CAP_ATTR(FF, ff); INPUT_DEV_CAP_ATTR(SW, sw); static struct attribute *input_dev_caps_attrs[] = { - &class_device_attr_ev.attr, - &class_device_attr_key.attr, - &class_device_attr_rel.attr, - &class_device_attr_abs.attr, - &class_device_attr_msc.attr, - &class_device_attr_led.attr, - &class_device_attr_snd.attr, - &class_device_attr_ff.attr, - &class_device_attr_sw.attr, + &dev_attr_ev.attr, + &dev_attr_key.attr, + &dev_attr_rel.attr, + &dev_attr_abs.attr, + &dev_attr_msc.attr, + &dev_attr_led.attr, + &dev_attr_snd.attr, + &dev_attr_ff.attr, + &dev_attr_sw.attr, NULL }; @@ -858,9 +866,9 @@ static struct attribute_group *input_dev_attr_groups[] = { NULL }; -static void input_dev_release(struct class_device *class_dev) +static void input_dev_release(struct device *device) { - struct input_dev *dev = to_input_dev(class_dev); + struct input_dev *dev = to_input_dev(device); input_ff_destroy(dev); kfree(dev); @@ -947,10 +955,10 @@ static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_ind return err; \ } while (0) -static int input_dev_uevent(struct class_device *cdev, char **envp, +static int input_dev_uevent(struct device *device, char **envp, int num_envp, char *buffer, int buffer_size) { - struct input_dev *dev = to_input_dev(cdev); + struct input_dev *dev = to_input_dev(device); int i = 0; int len = 0; @@ -988,10 +996,14 @@ static int input_dev_uevent(struct class_device *cdev, char **envp, return 0; } +static struct device_type input_dev_type = { + .groups = input_dev_attr_groups, + .release = input_dev_release, + .uevent = input_dev_uevent, +}; + struct class input_class = { - .name = "input", - .release = input_dev_release, - .uevent = input_dev_uevent, + .name = "input", }; EXPORT_SYMBOL_GPL(input_class); @@ -1010,9 +1022,9 @@ struct input_dev *input_allocate_device(void) dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { - dev->cdev.class = &input_class; - dev->cdev.groups = input_dev_attr_groups; - class_device_initialize(&dev->cdev); + dev->dev.type = &input_dev_type; + dev->dev.class = &input_class; + device_initialize(&dev->dev); mutex_init(&dev->mutex); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); @@ -1131,17 +1143,17 @@ int input_register_device(struct input_dev *dev) list_add_tail(&dev->node, &input_dev_list); - snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), + snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); - if (!dev->cdev.dev) - dev->cdev.dev = dev->dev.parent; + if (dev->cdev.dev) + dev->dev.parent = dev->cdev.dev; - error = class_device_add(&dev->cdev); + error = device_add(&dev->dev); if (error) return error; - path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); + path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); printk(KERN_INFO "input: %s as %s\n", dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); kfree(path); @@ -1173,7 +1185,7 @@ void input_unregister_device(struct input_dev *dev) list_del_init(&dev->node); - class_device_unregister(&dev->cdev); + device_unregister(&dev->dev); input_wakeup_procfs_readers(); } diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 10e3b7bc925f..a9a0180bfd46 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -43,6 +43,8 @@ struct joydev { struct input_handle handle; wait_queue_head_t wait; struct list_head client_list; + struct device dev; + struct js_corr corr[ABS_MAX + 1]; struct JS_DATA_SAVE_TYPE glue; int nabs; @@ -138,8 +140,10 @@ static int joydev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } -static void joydev_free(struct joydev *joydev) +static void joydev_free(struct device *dev) { + struct joydev *joydev = container_of(dev, struct joydev, dev); + joydev_table[joydev->minor] = NULL; kfree(joydev); } @@ -154,12 +158,10 @@ static int joydev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--joydev->open) { - if (joydev->exist) - input_close_device(&joydev->handle); - else - joydev_free(joydev); - } + if (!--joydev->open && joydev->exist) + input_close_device(&joydev->handle); + + put_device(&joydev->dev); return 0; } @@ -178,24 +180,32 @@ static int joydev_open(struct inode *inode, struct file *file) if (!joydev || !joydev->exist) return -ENODEV; + get_device(&joydev->dev); + client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); - if (!client) - return -ENOMEM; + if (!client) { + error = -ENOMEM; + goto err_put_joydev; + } client->joydev = joydev; list_add_tail(&client->node, &joydev->client_list); if (!joydev->open++ && joydev->exist) { error = input_open_device(&joydev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } + if (error) + goto err_free_client; } file->private_data = client; return 0; + + err_free_client: + list_del(&client->node); + kfree(client); + err_put_joydev: + put_device(&joydev->dev); + return error; } static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) @@ -481,8 +491,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { struct joydev *joydev; - struct class_device *cdev; - dev_t devt; int i, j, t, minor; int error; @@ -505,7 +513,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->handle.name = joydev->name; joydev->handle.handler = handler; joydev->handle.private = joydev; - sprintf(joydev->name, "js%d", minor); + snprintf(joydev->name, sizeof(joydev->name), "js%d", minor); for (i = 0; i < ABS_MAX + 1; i++) if (test_bit(i, dev->absbit)) { @@ -547,36 +555,30 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); } + snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id), + "js%d", minor); + joydev->dev.class = &input_class; + joydev->dev.parent = &dev->dev; + joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); + joydev->dev.release = joydev_free; + device_initialize(&joydev->dev); + joydev_table[minor] = joydev; - devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, joydev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_joydev; - } - - /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, joydev->name); + error = device_add(&joydev->dev); if (error) - goto err_cdev_destroy; + goto err_free_joydev; error = input_register_handle(&joydev->handle); if (error) - goto err_remove_link; + goto err_delete_joydev; return 0; - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, joydev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); + err_delete_joydev: + device_del(&joydev->dev); err_free_joydev: - joydev_table[minor] = NULL; - kfree(joydev); + put_device(&joydev->dev); return error; } @@ -587,9 +589,8 @@ static void joydev_disconnect(struct input_handle *handle) struct joydev_client *client; input_unregister_handle(handle); + device_del(&joydev->dev); - sysfs_remove_link(&input_class.subsys.kobj, joydev->name); - class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; if (joydev->open) { @@ -597,8 +598,9 @@ static void joydev_disconnect(struct input_handle *handle) list_for_each_entry(client, &joydev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&joydev->wait); - } else - joydev_free(joydev); + } + + put_device(&joydev->dev); } static const struct input_device_id joydev_blacklist[] = { diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 3f4866d8d18c..9173916b8be5 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -64,6 +64,7 @@ struct mousedev { wait_queue_head_t wait; struct list_head client_list; struct input_handle handle; + struct device dev; struct list_head mixdev_node; int mixdev_open; @@ -112,7 +113,7 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; static struct input_handler mousedev_handler; static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; -static struct mousedev mousedev_mix; +static struct mousedev *mousedev_mix; static LIST_HEAD(mousedev_mix_list); #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) @@ -218,10 +219,10 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int if (value) { set_bit(index, &mousedev->packet.buttons); - set_bit(index, &mousedev_mix.packet.buttons); + set_bit(index, &mousedev_mix->packet.buttons); } else { clear_bit(index, &mousedev->packet.buttons); - clear_bit(index, &mousedev_mix.packet.buttons); + clear_bit(index, &mousedev_mix->packet.buttons); } } @@ -287,11 +288,11 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) * motion packet so we won't mess current position. */ set_bit(0, &mousedev->packet.buttons); - set_bit(0, &mousedev_mix.packet.buttons); - mousedev_notify_readers(mousedev, &mousedev_mix.packet); - mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet); + set_bit(0, &mousedev_mix->packet.buttons); + mousedev_notify_readers(mousedev, &mousedev_mix->packet); + mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet); clear_bit(0, &mousedev->packet.buttons); - clear_bit(0, &mousedev_mix.packet.buttons); + clear_bit(0, &mousedev_mix->packet.buttons); } mousedev->touch = mousedev->pkt_count = 0; mousedev->frac_dx = 0; @@ -343,7 +344,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig } mousedev_notify_readers(mousedev, &mousedev->packet); - mousedev_notify_readers(&mousedev_mix, &mousedev->packet); + mousedev_notify_readers(mousedev_mix, &mousedev->packet); mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; mousedev->packet.abs_event = 0; @@ -362,8 +363,10 @@ static int mousedev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } -static void mousedev_free(struct mousedev *mousedev) +static void mousedev_free(struct device *dev) { + struct mousedev *mousedev = container_of(dev, struct mousedev, dev); + mousedev_table[mousedev->minor] = NULL; kfree(mousedev); } @@ -372,15 +375,16 @@ static int mixdev_add_device(struct mousedev *mousedev) { int error; - if (mousedev_mix.open) { + if (mousedev_mix->open) { error = input_open_device(&mousedev->handle); if (error) return error; mousedev->open++; - mousedev->mixdev_open++; + mousedev->mixdev_open = 1; } + get_device(&mousedev->dev); list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); return 0; @@ -395,36 +399,40 @@ static void mixdev_remove_device(struct mousedev *mousedev) } list_del_init(&mousedev->mixdev_node); + put_device(&mousedev->dev); } static void mixdev_open_devices(void) { struct mousedev *mousedev; + if (mousedev_mix->open++) + return; + list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { - if (mousedev->exist && !mousedev->open) { - if (input_open_device(&mousedev->handle)) - continue; + if (!mousedev->mixdev_open) { + if (!mousedev->open && mousedev->exist) + if (input_open_device(&mousedev->handle)) + continue; mousedev->open++; - mousedev->mixdev_open++; + mousedev->mixdev_open = 1; } } } static void mixdev_close_devices(void) { - struct mousedev *mousedev, *next; + struct mousedev *mousedev; - list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { + if (--mousedev_mix->open) + return; + + list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { if (mousedev->mixdev_open) { mousedev->mixdev_open = 0; - if (!--mousedev->open) { - if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); - } + if (!--mousedev->open && mousedev->exist) + input_close_device(&mousedev->handle); } } } @@ -439,14 +447,12 @@ static int mousedev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--mousedev->open) { - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_close_devices(); - else if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); - } + if (mousedev->minor == MOUSEDEV_MIX) + mixdev_close_devices(); + else if (!--mousedev->open && mousedev->exist) + input_close_device(&mousedev->handle); + + put_device(&mousedev->dev); return 0; } @@ -473,9 +479,13 @@ static int mousedev_open(struct inode *inode, struct file *file) if (!mousedev) return -ENODEV; + get_device(&mousedev->dev); + client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); - if (!client) - return -ENOMEM; + if (!client) { + error = -ENOMEM; + goto err_put_mousedev; + } spin_lock_init(&client->packet_lock); client->pos_x = xres / 2; @@ -483,21 +493,23 @@ static int mousedev_open(struct inode *inode, struct file *file) client->mousedev = mousedev; list_add_tail(&client->node, &mousedev->client_list); - if (!mousedev->open++) { - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_open_devices(); - else if (mousedev->exist) { - error = input_open_device(&mousedev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } - } + if (mousedev->minor == MOUSEDEV_MIX) + mixdev_open_devices(); + else if (!mousedev->open++ && mousedev->exist) { + error = input_open_device(&mousedev->handle); + if (error) + goto err_free_client; } file->private_data = client; return 0; + + err_free_client: + list_del(&client->node); + kfree(client); + err_put_mousedev: + put_device(&mousedev->dev); + return error; } static inline int mousedev_limit_delta(int delta, int limit) @@ -680,12 +692,80 @@ static const struct file_operations mousedev_fops = { .fasync = mousedev_fasync, }; +static struct mousedev *mousedev_create(struct input_dev *dev, + struct input_handler *handler, + int minor) +{ + struct mousedev *mousedev; + int error; + + mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); + if (!mousedev) { + error = -ENOMEM; + goto err_out; + } + + INIT_LIST_HEAD(&mousedev->client_list); + INIT_LIST_HEAD(&mousedev->mixdev_node); + init_waitqueue_head(&mousedev->wait); + + if (minor == MOUSEDEV_MIX) + strlcpy(mousedev->name, "mice", sizeof(mousedev->name)); + else + snprintf(mousedev->name, sizeof(mousedev->name), + "mouse%d", minor); + + mousedev->minor = minor; + mousedev->exist = 1; + mousedev->handle.dev = dev; + mousedev->handle.name = mousedev->name; + mousedev->handle.handler = handler; + mousedev->handle.private = mousedev; + + strlcpy(mousedev->dev.bus_id, mousedev->name, + sizeof(mousedev->dev.bus_id)); + mousedev->dev.class = &input_class; + if (dev) + mousedev->dev.parent = &dev->dev; + mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor); + mousedev->dev.release = mousedev_free; + device_initialize(&mousedev->dev); + + mousedev_table[minor] = mousedev; + + error = device_add(&mousedev->dev); + if (error) + goto err_free_mousedev; + + return mousedev; + + err_free_mousedev: + put_device(&mousedev->dev); + err_out: + return ERR_PTR(error); +} + +static void mousedev_destroy(struct mousedev *mousedev) +{ + struct mousedev_client *client; + + device_del(&mousedev->dev); + mousedev->exist = 0; + + if (mousedev->open) { + input_close_device(&mousedev->handle); + list_for_each_entry(client, &mousedev->client_list, node) + kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&mousedev->wait); + } + + put_device(&mousedev->dev); +} + static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { struct mousedev *mousedev; - struct class_device *cdev; - dev_t devt; int minor; int error; @@ -695,42 +775,13 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev return -ENFILE; } - mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); - if (!mousedev) - return -ENOMEM; - - INIT_LIST_HEAD(&mousedev->client_list); - INIT_LIST_HEAD(&mousedev->mixdev_node); - init_waitqueue_head(&mousedev->wait); - - mousedev->minor = minor; - mousedev->exist = 1; - mousedev->handle.dev = dev; - mousedev->handle.name = mousedev->name; - mousedev->handle.handler = handler; - mousedev->handle.private = mousedev; - sprintf(mousedev->name, "mouse%d", minor); - - mousedev_table[minor] = mousedev; - - devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, mousedev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_mousedev; - } - - /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, mousedev->name); - if (error) - goto err_cdev_destroy; + mousedev = mousedev_create(dev, handler, minor); + if (IS_ERR(mousedev)) + return PTR_ERR(mousedev); error = input_register_handle(&mousedev->handle); if (error) - goto err_remove_link; + goto err_delete_mousedev; error = mixdev_add_device(mousedev); if (error) @@ -740,37 +791,18 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev err_unregister_handle: input_unregister_handle(&mousedev->handle); - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); - err_free_mousedev: - mousedev_table[minor] = NULL; - kfree(mousedev); + err_delete_mousedev: + device_unregister(&mousedev->dev); return error; } static void mousedev_disconnect(struct input_handle *handle) { struct mousedev *mousedev = handle->private; - struct mousedev_client *client; - - input_unregister_handle(handle); - - sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); - class_device_destroy(&input_class, - MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); - mousedev->exist = 0; mixdev_remove_device(mousedev); - - if (mousedev->open) { - input_close_device(handle); - list_for_each_entry(client, &mousedev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); - wake_up_interruptible(&mousedev->wait); - } else - mousedev_free(mousedev); + input_unregister_handle(handle); + mousedev_destroy(mousedev); } static const struct input_device_id mousedev_ids[] = { @@ -822,25 +854,16 @@ static int psaux_registered; static int __init mousedev_init(void) { - struct class_device *cdev; int error; + mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX); + if (IS_ERR(mousedev_mix)) + return PTR_ERR(mousedev_mix); + error = input_register_handler(&mousedev_handler); - if (error) + if (error) { + mousedev_destroy(mousedev_mix); return error; - - memset(&mousedev_mix, 0, sizeof(struct mousedev)); - INIT_LIST_HEAD(&mousedev_mix.client_list); - init_waitqueue_head(&mousedev_mix.wait); - mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; - mousedev_mix.exist = 1; - mousedev_mix.minor = MOUSEDEV_MIX; - - cdev = class_device_create(&input_class, NULL, - MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice"); - if (IS_ERR(cdev)) { - input_unregister_handler(&mousedev_handler); - return PTR_ERR(cdev); } #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -863,9 +886,8 @@ static void __exit mousedev_exit(void) if (psaux_registered) misc_deregister(&psaux_mouse); #endif - class_device_destroy(&input_class, - MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); + mousedev_destroy(mousedev_mix); } module_init(mousedev_init); diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 2db364898e15..4cd5bbc44cca 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -109,9 +109,11 @@ struct tsdev { int open; int minor; char name[8]; + struct input_handle handle; wait_queue_head_t wait; struct list_head client_list; - struct input_handle handle; + struct device dev; + int x, y, pressure; struct ts_calibration cal; }; @@ -163,9 +165,13 @@ static int tsdev_open(struct inode *inode, struct file *file) if (!tsdev || !tsdev->exist) return -ENODEV; + get_device(&tsdev->dev); + client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); - if (!client) - return -ENOMEM; + if (!client) { + error = -ENOMEM; + goto err_put_tsdev; + } client->tsdev = tsdev; client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; @@ -173,19 +179,25 @@ static int tsdev_open(struct inode *inode, struct file *file) if (!tsdev->open++ && tsdev->exist) { error = input_open_device(&tsdev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } + if (error) + goto err_free_client; } file->private_data = client; return 0; + + err_free_client: + list_del(&client->node); + kfree(client); + err_put_tsdev: + put_device(&tsdev->dev); + return error; } -static void tsdev_free(struct tsdev *tsdev) +static void tsdev_free(struct device *dev) { + struct tsdev *tsdev = container_of(dev, struct tsdev, dev); + tsdev_table[tsdev->minor] = NULL; kfree(tsdev); } @@ -200,12 +212,10 @@ static int tsdev_release(struct inode *inode, struct file *file) list_del(&client->node); kfree(client); - if (!--tsdev->open) { - if (tsdev->exist) - input_close_device(&tsdev->handle); - else - tsdev_free(tsdev); - } + if (!--tsdev->open && tsdev->exist) + input_close_device(&tsdev->handle); + + put_device(&tsdev->dev); return 0; } @@ -388,8 +398,6 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id) { struct tsdev *tsdev; - struct class_device *cdev; - dev_t devt; int minor, delta; int error; @@ -407,14 +415,13 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, INIT_LIST_HEAD(&tsdev->client_list); init_waitqueue_head(&tsdev->wait); - sprintf(tsdev->name, "ts%d", minor); - tsdev->exist = 1; tsdev->minor = minor; tsdev->handle.dev = dev; tsdev->handle.name = tsdev->name; tsdev->handle.handler = handler; tsdev->handle.private = tsdev; + snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor); /* Precompute the rough calibration matrix */ delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1; @@ -429,36 +436,30 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, tsdev->cal.yscale = (yres << 8) / delta; tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8); + snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id), + "ts%d", minor); + tsdev->dev.class = &input_class; + tsdev->dev.parent = &dev->dev; + tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor); + tsdev->dev.release = tsdev_free; + device_initialize(&tsdev->dev); + tsdev_table[minor] = tsdev; - devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, tsdev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_tsdev; - } - - /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, tsdev->name); + error = device_add(&tsdev->dev); if (error) - goto err_cdev_destroy; + goto err_free_tsdev; error = input_register_handle(&tsdev->handle); if (error) - goto err_remove_link; + goto err_delete_tsdev; return 0; - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); + err_delete_tsdev: + device_del(&tsdev->dev); err_free_tsdev: - tsdev_table[minor] = NULL; - kfree(tsdev); + put_device(&tsdev->dev); return error; } @@ -468,10 +469,8 @@ static void tsdev_disconnect(struct input_handle *handle) struct tsdev_client *client; input_unregister_handle(handle); + device_del(&tsdev->dev); - sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); - class_device_destroy(&input_class, - MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; if (tsdev->open) { @@ -479,8 +478,9 @@ static void tsdev_disconnect(struct input_handle *handle) list_for_each_entry(client, &tsdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); wake_up_interruptible(&tsdev->wait); - } else - tsdev_free(tsdev); + } + + put_device(&tsdev->dev); } static const struct input_device_id tsdev_ids[] = { diff --git a/include/linux/input.h b/include/linux/input.h index d8521c72f69f..18c98b543030 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -981,15 +981,15 @@ struct input_dev { struct mutex mutex; /* serializes open and close operations */ unsigned int users; - struct class_device cdev; + struct device dev; union { /* temporarily so while we switching to struct device */ - struct device *parent; - } dev; + struct device *dev; + } cdev; struct list_head h_list; struct list_head node; }; -#define to_input_dev(d) container_of(d, struct input_dev, cdev) +#define to_input_dev(d) container_of(d, struct input_dev, dev) /* * Verify that we are in sync with input_device_id mod_devicetable.h #defines @@ -1096,22 +1096,22 @@ struct input_handle { struct list_head h_node; }; -#define to_dev(n) container_of(n,struct input_dev,node) -#define to_handler(n) container_of(n,struct input_handler,node) -#define to_handle(n) container_of(n,struct input_handle,d_node) -#define to_handle_h(n) container_of(n,struct input_handle,h_node) +#define to_dev(n) container_of(n, struct input_dev, node) +#define to_handler(n) container_of(n, struct input_handler, node) +#define to_handle(n) container_of(n, struct input_handle, d_node) +#define to_handle_h(n) container_of(n, struct input_handle, h_node) struct input_dev *input_allocate_device(void); void input_free_device(struct input_dev *dev); static inline struct input_dev *input_get_device(struct input_dev *dev) { - return to_input_dev(class_device_get(&dev->cdev)); + return to_input_dev(get_device(&dev->dev)); } static inline void input_put_device(struct input_dev *dev) { - class_device_put(&dev->cdev); + put_device(&dev->dev); } static inline void *input_get_drvdata(struct input_dev *dev) From 5f5655023f2814969b744c1e07494666587243aa Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 14 Jun 2007 23:32:35 -0400 Subject: [PATCH 374/551] Input: add gpio-mouse driver Adds support for simulating a mouse using GPIO lines. The driver needs an appropriate platform device to be created by architecture code. The driver has been tested on AT32AP7000 microprocessor using the ATSTK1000 development board. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/Kconfig | 16 +++ drivers/input/mouse/Makefile | 1 + drivers/input/mouse/gpio_mouse.c | 196 +++++++++++++++++++++++++++++++ include/linux/gpio_mouse.h | 61 ++++++++++ 4 files changed, 274 insertions(+) create mode 100644 drivers/input/mouse/gpio_mouse.c create mode 100644 include/linux/gpio_mouse.h diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 50e06e8dd05d..7bbea097cda2 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -216,4 +216,20 @@ config MOUSE_HIL help Say Y here to support HIL pointers. +config MOUSE_GPIO + tristate "GPIO mouse" + depends on GENERIC_GPIO + select INPUT_POLLDEV + help + This driver simulates a mouse on GPIO lines of various CPUs (and some + other chips). + + Say Y here if your device has buttons or a simple joystick connected + directly to GPIO lines. Your board-specific setup logic must also + provide a platform device and platform data saying which GPIOs are + used. + + To compile this driver as a module, choose M here: the + module will be called gpio_mouse. + endif diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index aa4ba878533f..9e6e36330820 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_MOUSE_PS2) += psmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o +obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o psmouse-objs := psmouse-base.o synaptics.o diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c new file mode 100644 index 000000000000..0936d6ba015c --- /dev/null +++ b/drivers/input/mouse/gpio_mouse.c @@ -0,0 +1,196 @@ +/* + * Driver for simulating a mouse on GPIO lines. + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include + +/* + * Timer function which is run every scan_ms ms when the device is opened. + * The dev input varaible is set to the the input_dev pointer. + */ +static void gpio_mouse_scan(struct input_polled_dev *dev) +{ + struct gpio_mouse_platform_data *gpio = dev->private; + struct input_dev *input = dev->input; + int x, y; + + if (gpio->bleft >= 0) + input_report_key(input, BTN_LEFT, + gpio_get_value(gpio->bleft) ^ gpio->polarity); + if (gpio->bmiddle >= 0) + input_report_key(input, BTN_MIDDLE, + gpio_get_value(gpio->bmiddle) ^ gpio->polarity); + if (gpio->bright >= 0) + input_report_key(input, BTN_RIGHT, + gpio_get_value(gpio->bright) ^ gpio->polarity); + + x = (gpio_get_value(gpio->right) ^ gpio->polarity) + - (gpio_get_value(gpio->left) ^ gpio->polarity); + y = (gpio_get_value(gpio->down) ^ gpio->polarity) + - (gpio_get_value(gpio->up) ^ gpio->polarity); + + input_report_rel(input, REL_X, x); + input_report_rel(input, REL_Y, y); + input_sync(input); +} + +static int __init gpio_mouse_probe(struct platform_device *pdev) +{ + struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; + struct input_polled_dev *input_poll; + struct input_dev *input; + int pin, i; + int error; + + if (!pdata) { + dev_err(&pdev->dev, "no platform data\n"); + error = -ENXIO; + goto out; + } + + if (pdata->scan_ms < 0) { + dev_err(&pdev->dev, "invalid scan time\n"); + error = -EINVAL; + goto out; + } + + for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { + pin = pdata->pins[i]; + + if (pin < 0) { + + if (i <= GPIO_MOUSE_PIN_RIGHT) { + /* Mouse direction is required. */ + dev_err(&pdev->dev, + "missing GPIO for directions\n"); + error = -EINVAL; + goto out_free_gpios; + } + + if (i == GPIO_MOUSE_PIN_BLEFT) + dev_dbg(&pdev->dev, "no left button defined\n"); + + } else { + error = gpio_request(pin, "gpio_mouse"); + if (error) { + dev_err(&pdev->dev, "fail %d pin (%d idx)\n", + pin, i); + goto out_free_gpios; + } + + gpio_direction_input(pin); + } + } + + input_poll = input_allocate_polled_device(); + if (!input_poll) { + dev_err(&pdev->dev, "not enough memory for input device\n"); + error = -ENOMEM; + goto out_free_gpios; + } + + platform_set_drvdata(pdev, input_poll); + + /* set input-polldev handlers */ + input_poll->private = pdata; + input_poll->poll = gpio_mouse_scan; + input_poll->poll_interval = pdata->scan_ms; + + input = input_poll->input; + input->name = pdev->name; + input->id.bustype = BUS_HOST; + input->dev.parent = &pdev->dev; + + input_set_capability(input, EV_REL, REL_X); + input_set_capability(input, EV_REL, REL_Y); + if (pdata->bleft >= 0) + input_set_capability(input, EV_KEY, BTN_LEFT); + if (pdata->bmiddle >= 0) + input_set_capability(input, EV_KEY, BTN_MIDDLE); + if (pdata->bright >= 0) + input_set_capability(input, EV_KEY, BTN_RIGHT); + + error = input_register_polled_device(input_poll); + if (error) { + dev_err(&pdev->dev, "could not register input device\n"); + goto out_free_polldev; + } + + dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n", + pdata->scan_ms, + pdata->bleft < 0 ? "" : "left ", + pdata->bmiddle < 0 ? "" : "middle ", + pdata->bright < 0 ? "" : "right"); + + return 0; + + out_free_polldev: + input_free_polled_device(input_poll); + platform_set_drvdata(pdev, NULL); + + out_free_gpios: + while (--i >= 0) { + pin = pdata->pins[i]; + if (pin) + gpio_free(pin); + } + out: + return error; +} + +static int __devexit gpio_mouse_remove(struct platform_device *pdev) +{ + struct input_polled_dev *input = platform_get_drvdata(pdev); + struct gpio_mouse_platform_data *pdata = input->private; + int pin, i; + + input_unregister_polled_device(input); + input_free_polled_device(input); + + for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { + pin = pdata->pins[i]; + if (pin >= 0) + gpio_free(pin); + } + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +struct platform_driver gpio_mouse_device_driver = { + .remove = __devexit_p(gpio_mouse_remove), + .driver = { + .name = "gpio_mouse", + } +}; + +static int __init gpio_mouse_init(void) +{ + return platform_driver_probe(&gpio_mouse_device_driver, + gpio_mouse_probe); +} +module_init(gpio_mouse_init); + +static void __exit gpio_mouse_exit(void) +{ + platform_driver_unregister(&gpio_mouse_device_driver); +} +module_exit(gpio_mouse_exit); + +MODULE_AUTHOR("Hans-Christian Egtvedt "); +MODULE_DESCRIPTION("GPIO mouse driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/gpio_mouse.h b/include/linux/gpio_mouse.h new file mode 100644 index 000000000000..44ed7aa14d85 --- /dev/null +++ b/include/linux/gpio_mouse.h @@ -0,0 +1,61 @@ +/* + * Driver for simulating a mouse on GPIO lines. + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _GPIO_MOUSE_H +#define _GPIO_MOUSE_H + +#define GPIO_MOUSE_POLARITY_ACT_HIGH 0x00 +#define GPIO_MOUSE_POLARITY_ACT_LOW 0x01 + +#define GPIO_MOUSE_PIN_UP 0 +#define GPIO_MOUSE_PIN_DOWN 1 +#define GPIO_MOUSE_PIN_LEFT 2 +#define GPIO_MOUSE_PIN_RIGHT 3 +#define GPIO_MOUSE_PIN_BLEFT 4 +#define GPIO_MOUSE_PIN_BMIDDLE 5 +#define GPIO_MOUSE_PIN_BRIGHT 6 +#define GPIO_MOUSE_PIN_MAX 7 + +/** + * struct gpio_mouse_platform_data + * @scan_ms: integer in ms specifying the scan periode. + * @polarity: Pin polarity, active high or low. + * @up: GPIO line for up value. + * @down: GPIO line for down value. + * @left: GPIO line for left value. + * @right: GPIO line for right value. + * @bleft: GPIO line for left button. + * @bmiddle: GPIO line for middle button. + * @bright: GPIO line for right button. + * + * This struct must be added to the platform_device in the board code. + * It is used by the gpio_mouse driver to setup GPIO lines and to + * calculate mouse movement. + */ +struct gpio_mouse_platform_data { + int scan_ms; + int polarity; + + union { + struct { + int up; + int down; + int left; + int right; + + int bleft; + int bmiddle; + int bright; + }; + int pins[GPIO_MOUSE_PIN_MAX]; + }; +}; + +#endif /* _GPIO_MOUSE_H */ From 7ecfbfd3d000a5d6787cf3369228e7f0082b8758 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 14 Jun 2007 23:32:48 -0400 Subject: [PATCH 375/551] Input: wacom - add support for the new Bamboo tablets Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom.h | 8 ++++-- drivers/input/tablet/wacom_sys.c | 6 ++++ drivers/input/tablet/wacom_wac.c | 47 ++++++++++++++++++++++++++++---- drivers/input/tablet/wacom_wac.h | 1 + 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index ef01a807ec0f..6542edb6f76e 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -11,7 +11,7 @@ * Copyright (c) 2000 Daniel Egger * Copyright (c) 2001 Frederic Lepied * Copyright (c) 2004 Panagiotis Issaris - * Copyright (c) 2002-2006 Ping Cheng + * Copyright (c) 2002-2007 Ping Cheng * * ChangeLog: * v0.1 (vp) - Initial release @@ -62,8 +62,9 @@ * - Minor data report fix * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code + * - and wacom_wac.c deals with Wacom specific code * - Support Intuos3 4x6 + * v1.47 (pc) - Added support for Bamboo */ /* @@ -84,7 +85,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.46" +#define DRIVER_VERSION "v1.47" #define DRIVER_AUTHOR "Vojtech Pavlik " #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" #define DRIVER_LICENSE "GPL" @@ -123,6 +124,7 @@ extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wa extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); +extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern __u16 wacom_le16_to_cpu(unsigned char *data); extern __u16 wacom_be16_to_cpu(unsigned char *data); extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 83bddef66067..064e123c9b76 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -138,6 +138,12 @@ static void wacom_close(struct input_dev *dev) usb_kill_urb(wacom->irq); } +void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) +{ + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); + input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); +} + void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { input_dev->evbit[0] |= BIT(EV_MSC); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 7661f03a2db2..fc03ba256f4c 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -178,7 +178,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4) { + if (wacom->features->type == WACOM_G4 || + wacom->features->type == WACOM_MO) { rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); wacom_report_rel(wcombo, REL_WHEEL, -rw); } else @@ -190,7 +191,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) id = CURSOR_DEVICE_ID; wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4) + if (wacom->features->type == WACOM_G4 || + wacom->features->type == WACOM_MO) wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); else wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); @@ -226,7 +228,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) } /* send pad data */ - if (wacom->features->type == WACOM_G4) { + switch (wacom->features->type) { + case WACOM_G4: if (data[7] & 0xf8) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 1; @@ -247,6 +250,33 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_abs(wcombo, ABS_MISC, 0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } + break; + case WACOM_MO: + if ((data[7] & 0xf8) || (data[8] & 0x80)) { + wacom_input_sync(wcombo); /* sync last event */ + wacom->id[1] = 1; + wacom->serial[1] = (data[7] & 0xf8); + wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); + wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); + wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); + wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); + wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); + wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); + wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); + wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); + } else if (wacom->id[1]) { + wacom_input_sync(wcombo); /* sync last event */ + wacom->id[1] = 0; + wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); + wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); + wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); + wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); + wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); + wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); + wacom_report_abs(wcombo, ABS_MISC, 0); + wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); + } + break; } return 1; } @@ -331,7 +361,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_EXTRA, 0); wacom_report_abs(wcombo, ABS_THROTTLE, 0); wacom_report_abs(wcombo, ABS_RZ, 0); - } else { + } else { wacom_report_abs(wcombo, ABS_PRESSURE, 0); wacom_report_abs(wcombo, ABS_TILT_X, 0); wacom_report_abs(wcombo, ABS_TILT_Y, 0); @@ -423,9 +453,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) return result-1; /* Only large I3 and I1 & I2 support Lense Cursor */ - if((wacom->tool[idx] == BTN_TOOL_LENS) + if ((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S))) + || (wacom->features->type == INTUOS3S))) return 0; /* Cintiq doesn't send data when RDY bit isn't set */ @@ -517,6 +547,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) break; case WACOM_G4: case GRAPHIRE: + case WACOM_MO: return (wacom_graphire_irq(wacom_wac, wcombo)); break; case PTU: @@ -538,6 +569,8 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { switch (wacom_wac->features->type) { + case WACOM_MO: + input_dev_mo(input_dev, wacom_wac); case WACOM_G4: input_dev_g4(input_dev, wacom_wac); /* fall through */ @@ -579,6 +612,7 @@ static struct wacom_features wacom_features[] = { { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, + { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, @@ -627,6 +661,7 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index a5e12e8756de..a302e229bb8a 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -25,6 +25,7 @@ enum { INTUOS3, INTUOS3L, CINTIQ, + WACOM_MO, MAX_TYPE }; From 5ec1f7f3e4a4896062dc6a64d38036588733bc23 Mon Sep 17 00:00:00 2001 From: Andi Drebes Date: Thu, 14 Jun 2007 23:33:01 -0400 Subject: [PATCH 376/551] Input: grip-mp - use ARRAY_SIZE Signed-off-by: Andi Drebes Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/grip_mp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 555319e6378c..4ed3a3eadf19 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -320,10 +320,10 @@ static int multiport_io(struct gameport* gameport, int sendflags, int sendcode, static int dig_mode_start(struct gameport *gameport, u32 *packet) { - int i, seq_len = sizeof(init_seq)/sizeof(int); + int i; int flags, tries = 0, bads = 0; - for (i = 0; i < seq_len; i++) { /* Send magic sequence */ + for (i = 0; i < ARRAY_SIZE(init_seq); i++) { /* Send magic sequence */ if (init_seq[i]) gameport_trigger(gameport); udelay(GRIP_INIT_DELAY); From 2e8335a629e48a753642772a5fe758c12d2e48bf Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 14 Jun 2007 23:33:13 -0400 Subject: [PATCH 377/551] Input: xpad - fix check for succesful usb_buffer_alloc Signed-off-by: Jan Kratochvil Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 0c04a26b8122..067ed8d1f8a7 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -407,7 +407,7 @@ static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, GFP_ATOMIC, &xpad->odata_dma ); - if (!xpad->idata) + if (!xpad->odata) goto fail1; xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); From 6426b333a7365035ede9744faa24bdc5682fad8a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 14 Jun 2007 23:33:26 -0400 Subject: [PATCH 378/551] Input: xpad - make xpad_play_effect() static xpad_play_effect() does not need to be global. Signed-off-by: Adrian Bunk Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 067ed8d1f8a7..de4fa8c80137 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -376,7 +376,8 @@ exit: __FUNCTION__, retval); } -int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +static int xpad_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) { struct usb_xpad *xpad = input_get_drvdata(dev); From ae91d10aab2762f81733e9194cb56eff99c8d808 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 14 Jun 2007 23:49:55 -0400 Subject: [PATCH 379/551] Input: xpad - fix report for dpad and inverted Y and RY axes on xbox 360 Make the driver report Y/RY up as positive value and down as negative. Also make DPAD mapping the same as classic xpad. Reported-by: Brian Magnuson Tested-by: Jan Kratochvil Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index de4fa8c80137..244089c52650 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -236,8 +236,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { input_report_key(dev, BTN_LEFT, data[2] & 0x04); input_report_key(dev, BTN_RIGHT, data[2] & 0x08); - input_report_key(dev, BTN_0, data[2] & 0x01); // up - input_report_key(dev, BTN_1, data[2] & 0x02); // down + input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ + input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ } /* start/back buttons and stick press left/right */ @@ -275,40 +275,40 @@ static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char /* digital pad */ if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { - input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x01) - !!((data[2] & 0x08) >> 3)); - input_report_abs(dev, ABS_HAT0Y, !!((data[2] & 0x02) >> 1) - !!((data[2] & 0x04) >> 2)); - } else if ( xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS ) { + input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); + input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); + } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (right, left, down, up) */ - input_report_key(dev, BTN_RIGHT, (data[2] & 0x01)); - input_report_key(dev, BTN_LEFT, (data[2] & 0x08) >> 3); - input_report_key(dev, BTN_0, (data[2] & 0x02) >> 1); - input_report_key(dev, BTN_1, (data[2] & 0x04) >> 2); + input_report_key(dev, BTN_LEFT, data[2] & 0x04); + input_report_key(dev, BTN_RIGHT, data[2] & 0x08); + input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ + input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ } /* start/back buttons */ - input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); - input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); + input_report_key(dev, BTN_START, data[2] & 0x10); + input_report_key(dev, BTN_BACK, data[2] & 0x20); /* stick press left/right */ input_report_key(dev, BTN_THUMBL, data[2] & 0x40); input_report_key(dev, BTN_THUMBR, data[2] & 0x80); /* buttons A,B,X,Y,TL,TR and MODE */ - input_report_key(dev, BTN_A, (data[3] & 0x10) >> 4); - input_report_key(dev, BTN_B, (data[3] & 0x20) >> 5); - input_report_key(dev, BTN_X, (data[3] & 0x40) >> 6); - input_report_key(dev, BTN_Y, (data[3] & 0x80) >> 7); - input_report_key(dev, BTN_TL, data[3] & 0x01 ); - input_report_key(dev, BTN_TR, (data[3] & 0x02) >> 1); - input_report_key(dev, BTN_MODE, (data[3] & 0x04) >> 2); + input_report_key(dev, BTN_A, data[3] & 0x10); + input_report_key(dev, BTN_B, data[3] & 0x20); + input_report_key(dev, BTN_X, data[3] & 0x40); + input_report_key(dev, BTN_Y, data[3] & 0x80); + input_report_key(dev, BTN_TL, data[3] & 0x01); + input_report_key(dev, BTN_TR, data[3] & 0x02); + input_report_key(dev, BTN_MODE, data[3] & 0x04); /* left stick */ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6])); - input_report_abs(dev, ABS_Y, ~(__s16) (((__s16)data[9] << 8) | (__s16)data[8])); + input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8])); /* right stick */ - input_report_abs(dev, ABS_RY, ~(__s16) (((__s16)data[13] << 8) | (__s16)data[12])); input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10])); + input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12])); /* triggers left/right */ input_report_abs(dev, ABS_Z, data[4]); From 1e2831db01c0726ec046e69719a10d7696b283fb Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 14 Jun 2007 23:58:51 -0400 Subject: [PATCH 380/551] Input: ppc-beep - switch to using input_dev->dev.parent In preparation for struct class_device -> struct device input core conversion, switch to using input_dev->dev.parent when specifying device position in sysfs tree. Also, do not access input_dev->private directly, use helpers. Signed-off-by: Dmitry Torokhov --- sound/ppc/beep.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index 5f38f670102c..a1aa89f2faf3 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c @@ -118,7 +118,7 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, default: return -1; } - chip = dev->private; + chip = input_get_drvdata(dev); if (! chip || (beep = chip->beep) == NULL) return -1; @@ -239,8 +239,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip) input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = snd_pmac_beep_event; - input_dev->private = chip; - input_dev->cdev.dev = &chip->pdev->dev; + input_dev->dev.parent = &chip->pdev->dev; + input_set_drvdata(input_dev, chip); beep->dev = input_dev; beep->buf = dmabuf; @@ -251,8 +251,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip) err = snd_ctl_add(chip->card, beep_ctl); if (err < 0) goto fail1; - - chip->beep = beep; + + chip->beep = beep; err = input_register_device(beep->dev); if (err) From df561fcd445c9cf9f4fff98ea795a0e72b7dc1e1 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 3 Jul 2007 01:55:03 -0400 Subject: [PATCH 381/551] Input: usbtouchscreen - add support for IRTOUCHSYSTEMS touchscreens This patch adds support for IRTOUCHSYSTEMS (or UNITOP) infrared touchscreens. The touchscreen sends data in 8-byte packets. BYTE 0 - unknown meaning, seen only one value: 0x54 BYTE 1 - unknown meaning, 3 lowest bits indicate touch state values seen: 0x81, 0x82 or 0x83 bit 0 = set if the screen is touched and was not touched before (touch bit 1 = set if the screen is touched and was touched (dragging) bit 2 = set if the touch was ended (release) BYTES 2 and 3 - X position, high-order-byte first, range = 0 to 0x0FFF BYTES 4 and 5 - Y position, high-order-byte first, range = 0 to 0x0FFF BYTE 6 - unknown meaning, seen only one value: 0xFF BYTE 7 - unknown meaning, seen only one value: 0x00 Signed-off-by: Ondrej Zary Signed-off-by: Daniel Ritz Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 6 ++++ drivers/input/touchscreen/usbtouchscreen.c | 33 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index e5cca9bd0406..69371779806a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -177,6 +177,7 @@ config TOUCHSCREEN_USB_COMPOSITE - some other eTurboTouch - Gunze AHL61 - DMC TSC-10/25 + - IRTOUCHSYSTEMS/UNITOP Have a look at for a usage description and the required user-space stuff. @@ -219,4 +220,9 @@ config TOUCHSCREEN_USB_DMC_TSC10 bool "DMC TSC-10/25 device support" if EMBEDDED depends on TOUCHSCREEN_USB_COMPOSITE +config TOUCHSCREEN_USB_IRTOUCH + default y + bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED + depends on TOUCHSCREEN_USB_COMPOSITE + endif diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index e3f22852bd09..b407028ffc59 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -9,6 +9,7 @@ * - eTurboTouch * - Gunze AHL61 * - DMC TSC-10/25 + * - IRTOUCHSYSTEMS/UNITOP * * Copyright (C) 2004-2006 by Daniel Ritz * Copyright (C) by Todd E. Johnson (mtouchusb.c) @@ -110,6 +111,7 @@ enum { DEVTYPE_ETURBO, DEVTYPE_GUNZE, DEVTYPE_DMC_TSC10, + DEVTYPE_IRTOUCH, }; static struct usb_device_id usbtouch_devices[] = { @@ -150,6 +152,11 @@ static struct usb_device_id usbtouch_devices[] = { {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10}, #endif +#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH + {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, + {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, +#endif + {} }; @@ -415,6 +422,21 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) #endif +/***************************************************************************** + * IRTOUCH Part + */ +#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH +static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) +{ + dev->x = (pkt[3] << 8) | pkt[2]; + dev->y = (pkt[5] << 8) | pkt[4]; + dev->touch = (pkt[1] & 0x03) ? 1 : 0; + + return 1; +} +#endif + + /***************************************************************************** * the different device descriptors */ @@ -504,6 +526,17 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .read_data = dmc_tsc10_read_data, }, #endif + +#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH + [DEVTYPE_IRTOUCH] = { + .min_xc = 0x0, + .max_xc = 0x0fff, + .min_yc = 0x0, + .max_yc = 0x0fff, + .rept_size = 8, + .read_data = irtouch_read_data, + }, +#endif }; From 72a42f242cad8f393bb2556f4cc5175c6cea9892 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 3 Jul 2007 01:55:18 -0400 Subject: [PATCH 382/551] Input: atkbd - change mapping for e032 from KEY_WWW to KEY_HOMEPAGE WWW/Homepage key on Microsoft-compatible keyboards generates KEY_WWW when connected via PS/2 port but KEY_HOMEPAGE when connected via USB. This patch changes mapping in atkbd to match one in HID driver. Signed-off-by: Hans de Goede Acked-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/char/keyboard.c | 4 ++-- drivers/input/keyboard/atkbd.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 1b094509b1d2..90965b4def5c 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1005,8 +1005,8 @@ static const unsigned short x86_keycodes[256] = 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, - 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, - 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114, + 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361, + 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114, 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116, 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307, 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 9950fcb33650..41fc3d03b6eb 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, - 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, + 159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142, 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, @@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = { 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183, 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0, - 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168, + 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168, 148,149,147,140 }; From 2f1d076a220bf57270020a1e756a9f34108b9338 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 10 Jul 2007 00:38:18 -0400 Subject: [PATCH 383/551] Input: update MAINTAINERS to explicitly mention touchscreens Signed-off-by: Robert P. J. Day Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2c1dfb271613..bc272bf0ff97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1856,7 +1856,7 @@ W: http://www.openib.org/ T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git S: Supported -INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS +INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS P: Dmitry Torokhov M: dmitry.torokhov@gmail.com M: dtor@mail.ru From 4f179f71607382888c5ce5385a4ee136e1a2002a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 10 Jul 2007 00:38:31 -0400 Subject: [PATCH 384/551] Input: serio_raw - shut up errorneous warning drivers/input/serio/serio_raw.c: In function 'serio_raw_read': drivers/input/serio/serio_raw.c:163: warning: 'c' may be used uninitialized in this function Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio_raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 887357666c68..0403622ae267 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -160,7 +160,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t cou { struct serio_raw_list *list = file->private_data; struct serio_raw *serio_raw = list->serio_raw; - char c; + char uninitialized_var(c); ssize_t retval = 0; if (!serio_raw->serio) From 744c9c33eaa062f716c6ae0bcb022b47c3af8b73 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 10 Jul 2007 00:38:39 -0400 Subject: [PATCH 385/551] Input: pxa27x_keyboard - fix compile error Signed-off-by: Mike Rapoport Acked-by: Rodolfo Giometti Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pxa27x_keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c index f9e82c9ca421..ebe5eacf2990 100644 --- a/drivers/input/keyboard/pxa27x_keyboard.c +++ b/drivers/input/keyboard/pxa27x_keyboard.c @@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev) KPREC = pdata->reg_kprec; /* Enable unit clock */ - pxa_set_cken(CKEN19_KEYPAD, 1); + pxa_set_cken(CKEN_KEYPAD, 1); } mutex_unlock(&input_dev->mutex); From 65f88f89c94d877794a6006f210d75d2974a182e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 10 Jul 2007 00:43:06 -0400 Subject: [PATCH 386/551] Input: tsdev - fix broken usec-to-millisecs conversion Noted by Fengwei Yin Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/tsdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 4cd5bbc44cca..d2f882e98e5e 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -371,7 +371,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, int x, y, tmp; do_gettimeofday(&time); - client->event[client->head].millisecs = time.tv_usec / 100; + client->event[client->head].millisecs = time.tv_usec / 1000; client->event[client->head].pressure = tsdev->pressure; x = tsdev->x; From 7deeed13170e634adc4552ff94588d6301a3da83 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 19 Jun 2007 09:05:21 +0200 Subject: [PATCH 387/551] [TRIVIAL PATCH] Kill blk_congestion_wait() stub for !CONFIG_BLOCK blk_congestion_wait() doesn't exist anymore, but there's still a stub in blkdev.h for the !CONFIG_BLOCK case. Kill it. Signed-off-by: Benjamin Gilbert Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index db5b00a792f5..fae138bd2207 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -868,11 +868,6 @@ void kblockd_flush_work(struct work_struct *work); */ #define buffer_heads_over_limit 0 -static inline long blk_congestion_wait(int rw, long timeout) -{ - return io_schedule_timeout(timeout); -} - static inline long nr_blockdev_pages(void) { return 0; From 32eef964110985c5845472e07fa0a18838a970c4 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Jun 2007 09:09:27 +0200 Subject: [PATCH 388/551] blk_hw_contig_segment(): bad segment size checks Two bugs in there: - The virt oversize check should use the current bio hardware back size and the next bio front size, not the same bio. Spotted by Neil Brown. - The segment size check should add hw front sizes, not total bio sizes. Spotted by James Bottomley Acked-by: James Bottomley Acked-by: NeilBrown Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index c99b46354859..3e7801e49033 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -1304,9 +1304,9 @@ static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) blk_recount_segments(q, nxt); if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || - BIOVEC_VIRT_OVERSIZE(bio->bi_hw_front_size + bio->bi_hw_back_size)) + BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) return 0; - if (bio->bi_size + nxt->bi_size > q->max_segment_size) + if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size) return 0; return 1; From 554988d6fe369719ae5b41255c577569ecf47c30 Mon Sep 17 00:00:00 2001 From: Dave Young Date: Tue, 19 Jun 2007 09:14:26 +0200 Subject: [PATCH 389/551] [PATCH] cdrom_sysctl_info fix Fix the cdrom_sysctl_info possible buffer overwrite bug. Also fix the locking of accessing topCdromPtr pointer. Signed-off-by: Dave Young Signed-off-by: Jens Axboe --- drivers/cdrom/cdrom.c | 216 ++++++++++++++++++++++++------------------ 1 file changed, 125 insertions(+), 91 deletions(-) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 3625a05bc3d3..aa5468f487ba 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -302,7 +302,7 @@ module_param(lockdoor, bool, 0); module_param(check_media_type, bool, 0); module_param(mrw_format_restart, bool, 0); -static DEFINE_SPINLOCK(cdrom_lock); +static DEFINE_MUTEX(cdrom_mutex); static const char *mrw_format_status[] = { "not mrw", @@ -438,10 +438,10 @@ int register_cdrom(struct cdrom_device_info *cdi) cdo->generic_packet = cdrom_dummy_generic_packet; cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); - spin_lock(&cdrom_lock); + mutex_lock(&cdrom_mutex); cdi->next = topCdromPtr; topCdromPtr = cdi; - spin_unlock(&cdrom_lock); + mutex_unlock(&cdrom_mutex); return 0; } #undef ENSURE @@ -452,7 +452,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) cdinfo(CD_OPEN, "entering unregister_cdrom\n"); prev = NULL; - spin_lock(&cdrom_lock); + mutex_lock(&cdrom_mutex); cdi = topCdromPtr; while (cdi && cdi != unreg) { prev = cdi; @@ -460,7 +460,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) } if (cdi == NULL) { - spin_unlock(&cdrom_lock); + mutex_unlock(&cdrom_mutex); return -2; } if (prev) @@ -468,7 +468,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) else topCdromPtr = cdi->next; - spin_unlock(&cdrom_lock); + mutex_unlock(&cdrom_mutex); if (cdi->exit) cdi->exit(cdi); @@ -3289,103 +3289,137 @@ static struct cdrom_sysctl_settings { int check; /* check media type */ } cdrom_sysctl_settings; +enum cdrom_print_option { + CTL_NAME, + CTL_SPEED, + CTL_SLOTS, + CTL_CAPABILITY +}; + +static int cdrom_print_info(const char *header, int val, char *info, + int *pos, enum cdrom_print_option option) +{ + const int max_size = sizeof(cdrom_sysctl_settings.info); + struct cdrom_device_info *cdi; + int ret; + + ret = scnprintf(info + *pos, max_size - *pos, header); + if (!ret) + return 1; + + *pos += ret; + + for (cdi = topCdromPtr; cdi; cdi = cdi->next) { + switch (option) { + case CTL_NAME: + ret = scnprintf(info + *pos, max_size - *pos, + "\t%s", cdi->name); + break; + case CTL_SPEED: + ret = scnprintf(info + *pos, max_size - *pos, + "\t%d", cdi->speed); + break; + case CTL_SLOTS: + ret = scnprintf(info + *pos, max_size - *pos, + "\t%d", cdi->capacity); + break; + case CTL_CAPABILITY: + ret = scnprintf(info + *pos, max_size - *pos, + "\t%d", CDROM_CAN(val) != 0); + break; + default: + printk(KERN_INFO "cdrom: invalid option%d\n", option); + return 1; + } + if (!ret) + return 1; + *pos += ret; + } + + return 0; +} + static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) { - int pos; - struct cdrom_device_info *cdi; + int pos; char *info = cdrom_sysctl_settings.info; + const int max_size = sizeof(cdrom_sysctl_settings.info); if (!*lenp || (*ppos && !write)) { *lenp = 0; return 0; } + mutex_lock(&cdrom_mutex); + pos = sprintf(info, "CD-ROM information, " VERSION "\n"); - pos += sprintf(info+pos, "\ndrive name:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%s", cdi->name); - - pos += sprintf(info+pos, "\ndrive speed:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", cdi->speed); - - pos += sprintf(info+pos, "\ndrive # of slots:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", cdi->capacity); - - pos += sprintf(info+pos, "\nCan close tray:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0); - - pos += sprintf(info+pos, "\nCan open tray:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0); - - pos += sprintf(info+pos, "\nCan lock tray:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0); - - pos += sprintf(info+pos, "\nCan change speed:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0); - - pos += sprintf(info+pos, "\nCan select disk:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0); - - pos += sprintf(info+pos, "\nCan read multisession:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0); - - pos += sprintf(info+pos, "\nCan read MCN:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0); - - pos += sprintf(info+pos, "\nReports media changed:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0); - - pos += sprintf(info+pos, "\nCan play audio:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0); - - pos += sprintf(info+pos, "\nCan write CD-R:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0); - - pos += sprintf(info+pos, "\nCan write CD-RW:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0); - - pos += sprintf(info+pos, "\nCan read DVD:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0); - - pos += sprintf(info+pos, "\nCan write DVD-R:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0); - - pos += sprintf(info+pos, "\nCan write DVD-RAM:"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0); - - pos += sprintf(info+pos, "\nCan read MRW:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0); - - pos += sprintf(info+pos, "\nCan write MRW:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0); - - pos += sprintf(info+pos, "\nCan write RAM:\t"); - for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) - pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0); - - strcpy(info+pos,"\n\n"); - - return proc_dostring(ctl, write, filp, buffer, lenp, ppos); + if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME)) + goto done; + if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED)) + goto done; + if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS)) + goto done; + if (cdrom_print_info("\nCan close tray:\t", + CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan open tray:\t", + CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan lock tray:\t", + CDC_LOCK, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan change speed:", + CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan select disk:", + CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan read multisession:", + CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan read MCN:\t", + CDC_MCN, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nReports media changed:", + CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan play audio:\t", + CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write CD-R:\t", + CDC_CD_R, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write CD-RW:", + CDC_CD_RW, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan read DVD:\t", + CDC_DVD, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write DVD-R:", + CDC_DVD_R, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write DVD-RAM:", + CDC_DVD_RAM, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan read MRW:\t", + CDC_MRW, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write MRW:\t", + CDC_MRW_W, info, &pos, CTL_CAPABILITY)) + goto done; + if (cdrom_print_info("\nCan write RAM:\t", + CDC_RAM, info, &pos, CTL_CAPABILITY)) + goto done; + if (!scnprintf(info + pos, max_size - pos, "\n\n")) + goto done; +doit: + mutex_unlock(&cdrom_mutex); + return proc_dostring(ctl, write, filp, buffer, lenp, ppos); +done: + printk(KERN_INFO "cdrom: info buffer too small\n"); + goto doit; } /* Unfortunately, per device settings are not implemented through From f4b09303d00212ead0619db58d8ec8a0a7a94882 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Jun 2007 09:18:13 +0200 Subject: [PATCH 390/551] [BLOCK] drop unnecessary bvec rewinding from flush_dry_bio_endio Barrier bios are completed twice - once after the barrier write itself is done and again after the whole sequence is complete. flush_dry_bio_endio() is for the first completion. It doesn't really complete the bio. It rewinds bvec and resets bio so that it can be completed again when the whole barrier sequence is complete. The bvec rewinding code has the following problems. 1. The rewinding code is wrong because filesystems may pass bvec with non zero bv_offset. 2. The block layer doesn't guarantee anything about the state of bvec array on request completion. bv_offset and len are updated iff __end_that_request_first() completes the bvec partially. Because of #2, #1 doesn't really matter (nobody cares whether bvec is re-wound correctly or not) but then again by not doing unwinding at all, we'll always give back the same bvec to the caller as full bvec completion doesn't alter bvecs and the final completion is always full completion. Drop unnecessary rewinding code. This is spotted by Neil Brown. Signed-off-by: Tejun Heo Cc: Neil Brown Signed-off-by: Jens Axboe --- block/ll_rw_blk.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 3e7801e49033..ef42bb2b12b6 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -527,8 +527,6 @@ int blk_do_ordered(request_queue_t *q, struct request **rqp) static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) { request_queue_t *q = bio->bi_private; - struct bio_vec *bvec; - int i; /* * This is dry run, restore bio_sector and size. We'll finish @@ -540,13 +538,6 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) if (bio->bi_size) return 1; - /* Rewind bvec's */ - bio->bi_idx = 0; - bio_for_each_segment(bvec, bio, i) { - bvec->bv_len += bvec->bv_offset; - bvec->bv_offset = 0; - } - /* Reset bio */ set_bit(BIO_UPTODATE, &bio->bi_flags); bio->bi_size = q->bi_size; From c2bcf3b8978c291e1b7f6499475c8403a259d4d6 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Jun 2007 19:13:36 +0200 Subject: [PATCH 391/551] [PATCH] Remove acsi.c Originally from Boaz Harrosh It hasn't been working in 2.5 or 2.6 ever, since it's still buffer_head based. Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 33 +- drivers/block/Makefile | 1 - drivers/block/acsi.c | 1825 ---------------------------------------- 3 files changed, 1 insertion(+), 1858 deletions(-) delete mode 100644 drivers/block/acsi.c diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index b4c8319138b2..d6ad7b3ea0dc 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -56,40 +56,9 @@ config AMIGA_Z2RAM To compile this driver as a module, choose M here: the module will be called z2ram. -config ATARI_ACSI - tristate "Atari ACSI support" - depends on ATARI && BROKEN - ---help--- - This enables support for the Atari ACSI interface. The driver - supports hard disks and CD-ROMs, which have 512-byte sectors, or can - be switched to that mode. Due to the ACSI command format, only disks - up to 1 GB are supported. Special support for certain ACSI to SCSI - adapters, which could relax that, isn't included yet. The ACSI - driver is also the basis for certain other drivers for devices - attached to the ACSI bus: Atari SLM laser printer, BioNet-100 - Ethernet, and PAMsNet Ethernet. If you want to use one of these - devices, you need ACSI support, too. - - To compile this driver as a module, choose M here: the - module will be called acsi. - -comment "Some devices (e.g. CD jukebox) support multiple LUNs" - depends on ATARI && ATARI_ACSI - -config ACSI_MULTI_LUN - bool "Probe all LUNs on each ACSI device" - depends on ATARI_ACSI - help - If you have a ACSI device that supports more than one LUN (Logical - Unit Number), e.g. a CD jukebox, you should say Y here so that all - will be found by the ACSI driver. An ACSI device with multiple LUNs - acts logically like multiple ACSI devices. The vast majority of ACSI - devices have only one LUN, and so most people can say N here and - should in fact do so, because it is safer. - config ATARI_SLM tristate "Atari SLM laser printer support" - depends on ATARI && ATARI_ACSI!=n + depends on ATARI help If you have an Atari SLM laser printer, say Y to include support for it in the kernel. Otherwise, say N. This driver is also available as diff --git a/drivers/block/Makefile b/drivers/block/Makefile index dd88e33c1eb1..e5f98acc5d52 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o -obj-$(CONFIG_ATARI_ACSI) += acsi.o obj-$(CONFIG_ATARI_SLM) += acsi_slm.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += rd.o diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c deleted file mode 100644 index e3d9152e231a..000000000000 --- a/drivers/block/acsi.c +++ /dev/null @@ -1,1825 +0,0 @@ -/* - * acsi.c -- Device driver for Atari ACSI hard disks - * - * Copyright 1994 Roman Hodek - * - * Some parts are based on hd.c by Linus Torvalds - * - * 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. - * - */ - -/* - * Still to in this file: - * - If a command ends with an error status (!= 0), the following - * REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by - * polling the _IRQ signal (not interrupt-driven). This should be - * avoided in future because it takes up a non-neglectible time in - * the interrupt service routine while interrupts are disabled. - * Maybe a timer interrupt will get lost :-( - */ - -/* - * General notes: - * - * - All ACSI devices (disks, CD-ROMs, ...) use major number 28. - * Minors are organized like it is with SCSI: The upper 4 bits - * identify the device, the lower 4 bits the partition. - * The device numbers (the upper 4 bits) are given in the same - * order as the devices are found on the bus. - * - Up to 8 LUNs are supported for each target (if CONFIG_ACSI_MULTI_LUN - * is defined), but only a total of 16 devices (due to minor - * numbers...). Note that Atari allows only a maximum of 4 targets - * (i.e. controllers, not devices) on the ACSI bus! - * - A optimizing scheme similar to SCSI scatter-gather is implemented. - * - Removable media are supported. After a medium change to device - * is reinitialized (partition check etc.). Also, if the device - * knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should - * be locked and unlocked when mounting the first or unmounting the - * last filesystem on the device. The code is untested, because I - * don't have a removable hard disk. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for SCSI_IOCTL_GET_IDLUN */ -#include -#include /* for HDIO_GETGEO */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void (*do_acsi)(void) = NULL; -static struct request_queue *acsi_queue; -#define QUEUE (acsi_queue) -#define CURRENT elv_next_request(acsi_queue) - -#define DEBUG -#undef DEBUG_DETECT -#undef NO_WRITE - -#define MAX_ERRORS 8 /* Max read/write errors/sector */ -#define MAX_LUN 8 /* Max LUNs per target */ -#define MAX_DEV 16 - -#define ACSI_BUFFER_SIZE (16*1024) /* "normal" ACSI buffer size */ -#define ACSI_BUFFER_MINSIZE (2048) /* min. buf size if ext. DMA */ -#define ACSI_BUFFER_SIZE_ORDER 2 /* order size for above */ -#define ACSI_BUFFER_MINSIZE_ORDER 0 /* order size for above */ -#define ACSI_BUFFER_SECTORS (ACSI_BUFFER_SIZE/512) - -#define ACSI_BUFFER_ORDER \ - (ATARIHW_PRESENT(EXTD_DMA) ? \ - ACSI_BUFFER_MINSIZE_ORDER : \ - ACSI_BUFFER_SIZE_ORDER) - -#define ACSI_TIMEOUT (4*HZ) - -/* minimum delay between two commands */ - -#define COMMAND_DELAY 500 - -typedef enum { - NONE, HARDDISK, CDROM -} ACSI_TYPE; - -struct acsi_info_struct { - ACSI_TYPE type; /* type of device */ - unsigned target; /* target number */ - unsigned lun; /* LUN in target controller */ - unsigned removable : 1; /* Flag for removable media */ - unsigned read_only : 1; /* Flag for read only devices */ - unsigned old_atari_disk : 1; /* Is an old Atari disk */ - unsigned changed : 1; /* Medium has been changed */ - unsigned long size; /* #blocks */ - int access_count; -} acsi_info[MAX_DEV]; - -/* - * SENSE KEYS - */ - -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e - - -/* - * DEVICE TYPES - */ - -#define TYPE_DISK 0x00 -#define TYPE_TAPE 0x01 -#define TYPE_WORM 0x04 -#define TYPE_ROM 0x05 -#define TYPE_MOD 0x07 -#define TYPE_NO_LUN 0x7f - -/* The data returned by MODE SENSE differ between the old Atari - * hard disks and SCSI disks connected to ACSI. In the following, both - * formats are defined and some macros to operate on them potably. - */ - -typedef struct { - unsigned long dummy[2]; - unsigned long sector_size; - unsigned char format_code; -#define ATARI_SENSE_FORMAT_FIX 1 -#define ATARI_SENSE_FORMAT_CHNG 2 - unsigned char cylinders_h; - unsigned char cylinders_l; - unsigned char heads; - unsigned char reduced_h; - unsigned char reduced_l; - unsigned char precomp_h; - unsigned char precomp_l; - unsigned char landing_zone; - unsigned char steprate; - unsigned char type; -#define ATARI_SENSE_TYPE_FIXCHNG_MASK 4 -#define ATARI_SENSE_TYPE_SOFTHARD_MASK 8 -#define ATARI_SENSE_TYPE_FIX 4 -#define ATARI_SENSE_TYPE_CHNG 0 -#define ATARI_SENSE_TYPE_SOFT 0 -#define ATARI_SENSE_TYPE_HARD 8 - unsigned char sectors; -} ATARI_SENSE_DATA; - -#define ATARI_CAPACITY(sd) \ - (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \ - (sd).heads * (sd).sectors) - - -typedef struct { - unsigned char dummy1; - unsigned char medium_type; - unsigned char dummy2; - unsigned char descriptor_size; - unsigned long block_count; - unsigned long sector_size; - /* Page 0 data */ - unsigned char page_code; - unsigned char page_size; - unsigned char page_flags; - unsigned char qualifier; -} SCSI_SENSE_DATA; - -#define SCSI_CAPACITY(sd) ((sd).block_count & 0xffffff) - - -typedef union { - ATARI_SENSE_DATA atari; - SCSI_SENSE_DATA scsi; -} SENSE_DATA; - -#define SENSE_TYPE_UNKNOWN 0 -#define SENSE_TYPE_ATARI 1 -#define SENSE_TYPE_SCSI 2 - -#define SENSE_TYPE(sd) \ - (((sd).atari.dummy[0] == 8 && \ - ((sd).atari.format_code == 1 || \ - (sd).atari.format_code == 2)) ? SENSE_TYPE_ATARI : \ - ((sd).scsi.dummy1 >= 11) ? SENSE_TYPE_SCSI : \ - SENSE_TYPE_UNKNOWN) - -#define CAPACITY(sd) \ - (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \ - ATARI_CAPACITY((sd).atari) : \ - SCSI_CAPACITY((sd).scsi)) - -#define SECTOR_SIZE(sd) \ - (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \ - (sd).atari.sector_size : \ - (sd).scsi.sector_size & 0xffffff) - -/* Default size if capacity cannot be determined (1 GByte) */ -#define DEFAULT_SIZE 0x1fffff - -#define CARTRCH_STAT(aip,buf) \ - (aip->old_atari_disk ? \ - (((buf)[0] & 0x7f) == 0x28) : \ - ((((buf)[0] & 0x70) == 0x70) ? \ - (((buf)[2] & 0x0f) == 0x06) : \ - (((buf)[0] & 0x0f) == 0x06))) \ - -/* These two are also exported to other drivers that work on the ACSI bus and - * need an ST-RAM buffer. */ -char *acsi_buffer; -unsigned long phys_acsi_buffer; - -static int NDevices; - -static int CurrentNReq; -static int CurrentNSect; -static char *CurrentBuffer; - -static DEFINE_SPINLOCK(acsi_lock); - - -#define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT) -#define CLEAR_TIMER() del_timer(&acsi_timer) - -static unsigned long STramMask; -#define STRAM_ADDR(a) (((a) & STramMask) == 0) - - - -/* ACSI commands */ - -static char tur_cmd[6] = { 0x00, 0, 0, 0, 0, 0 }; -static char modesense_cmd[6] = { 0x1a, 0, 0, 0, 24, 0 }; -static char modeselect_cmd[6] = { 0x15, 0, 0, 0, 12, 0 }; -static char inquiry_cmd[6] = { 0x12, 0, 0, 0,255, 0 }; -static char reqsense_cmd[6] = { 0x03, 0, 0, 0, 4, 0 }; -static char read_cmd[6] = { 0x08, 0, 0, 0, 0, 0 }; -static char write_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 }; -static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 }; - -#define CMDSET_TARG_LUN(cmd,targ,lun) \ - do { \ - cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \ - cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \ - } while(0) - -#define CMDSET_BLOCK(cmd,blk) \ - do { \ - unsigned long __blk = (blk); \ - cmd[3] = __blk; __blk >>= 8; \ - cmd[2] = __blk; __blk >>= 8; \ - cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f); \ - } while(0) - -#define CMDSET_LEN(cmd,len) \ - do { \ - cmd[4] = (len); \ - } while(0) - -/* ACSI errors (from REQUEST SENSE); There are two tables, one for the - * old Atari disks and one for SCSI on ACSI disks. - */ - -struct acsi_error { - unsigned char code; - const char *text; -} atari_acsi_errors[] = { - { 0x00, "No error (??)" }, - { 0x01, "No index pulses" }, - { 0x02, "Seek not complete" }, - { 0x03, "Write fault" }, - { 0x04, "Drive not ready" }, - { 0x06, "No Track 00 signal" }, - { 0x10, "ECC error in ID field" }, - { 0x11, "Uncorrectable data error" }, - { 0x12, "ID field address mark not found" }, - { 0x13, "Data field address mark not found" }, - { 0x14, "Record not found" }, - { 0x15, "Seek error" }, - { 0x18, "Data check in no retry mode" }, - { 0x19, "ECC error during verify" }, - { 0x1a, "Access to bad block" }, - { 0x1c, "Unformatted or bad format" }, - { 0x20, "Invalid command" }, - { 0x21, "Invalid block address" }, - { 0x23, "Volume overflow" }, - { 0x24, "Invalid argument" }, - { 0x25, "Invalid drive number" }, - { 0x26, "Byte zero parity check" }, - { 0x28, "Cartride changed" }, - { 0x2c, "Error count overflow" }, - { 0x30, "Controller selftest failed" } -}, - - scsi_acsi_errors[] = { - { 0x00, "No error (??)" }, - { 0x01, "Recovered error" }, - { 0x02, "Drive not ready" }, - { 0x03, "Uncorrectable medium error" }, - { 0x04, "Hardware error" }, - { 0x05, "Illegal request" }, - { 0x06, "Unit attention (Reset or cartridge changed)" }, - { 0x07, "Data protection" }, - { 0x08, "Blank check" }, - { 0x0b, "Aborted Command" }, - { 0x0d, "Volume overflow" } -}; - - - -/***************************** Prototypes *****************************/ - -static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int - rwflag, int enable); -static int acsi_reqsense( char *buffer, int targ, int lun); -static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip); -static irqreturn_t acsi_interrupt (int irq, void *data); -static void unexpected_acsi_interrupt( void ); -static void bad_rw_intr( void ); -static void read_intr( void ); -static void write_intr( void); -static void acsi_times_out( unsigned long dummy ); -static void copy_to_acsibuffer( void ); -static void copy_from_acsibuffer( void ); -static void do_end_requests( void ); -static void do_acsi_request( request_queue_t * ); -static void redo_acsi_request( void ); -static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int - cmd, unsigned long arg ); -static int acsi_open( struct inode * inode, struct file * filp ); -static int acsi_release( struct inode * inode, struct file * file ); -static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag ); -static int acsi_change_blk_size( int target, int lun); -static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd ); -static int acsi_revalidate (struct gendisk *disk); - -/************************* End of Prototypes **************************/ - - -DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0); - - -#ifdef CONFIG_ATARI_SLM - -extern int attach_slm( int target, int lun ); -extern int slm_init( void ); - -#endif - - - -/*********************************************************************** - * - * ACSI primitives - * - **********************************************************************/ - - -/* - * The following two functions wait for _IRQ to become Low or High, - * resp., with a timeout. The 'timeout' parameter is in jiffies - * (10ms). - * If the functions are called with timer interrupts on (int level < - * 6), the timeout is based on the 'jiffies' variable to provide exact - * timeouts for device probing etc. - * If interrupts are disabled, the number of tries is based on the - * 'loops_per_jiffy' variable. A rough estimation is sufficient here... - */ - -#define INT_LEVEL \ - ({ unsigned __sr; \ - __asm__ __volatile__ ( "movew %/sr,%0" : "=dm" (__sr) ); \ - (__sr >> 8) & 7; \ - }) - -int acsi_wait_for_IRQ( unsigned timeout ) - -{ - if (INT_LEVEL < 6) { - unsigned long maxjif = jiffies + timeout; - while (time_before(jiffies, maxjif)) - if (!(mfp.par_dt_reg & 0x20)) return( 1 ); - } - else { - long tries = loops_per_jiffy / 8 * timeout; - while( --tries >= 0 ) - if (!(mfp.par_dt_reg & 0x20)) return( 1 ); - } - return( 0 ); /* timeout! */ -} - - -int acsi_wait_for_noIRQ( unsigned timeout ) - -{ - if (INT_LEVEL < 6) { - unsigned long maxjif = jiffies + timeout; - while (time_before(jiffies, maxjif)) - if (mfp.par_dt_reg & 0x20) return( 1 ); - } - else { - long tries = loops_per_jiffy * timeout / 8; - while( tries-- >= 0 ) - if (mfp.par_dt_reg & 0x20) return( 1 ); - } - return( 0 ); /* timeout! */ -} - -static struct timeval start_time; - -void -acsi_delay_start(void) -{ - do_gettimeofday(&start_time); -} - -/* wait from acsi_delay_start to now usec (<1E6) usec */ - -void -acsi_delay_end(long usec) -{ - struct timeval end_time; - long deltau,deltas; - do_gettimeofday(&end_time); - deltau=end_time.tv_usec - start_time.tv_usec; - deltas=end_time.tv_sec - start_time.tv_sec; - if (deltas > 1 || deltas < 0) - return; - if (deltas > 0) - deltau += 1000*1000; - if (deltau >= usec) - return; - udelay(usec-deltau); -} - -/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer - * 'blocks' blocks of 512 bytes from/to 'buffer'. - * Because the _IRQ signal is used for handshaking the command bytes, - * the ACSI interrupt has to be disabled in this function. If the end - * of the operation should be signalled by a real interrupt, it has to be - * reenabled afterwards. - */ - -static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable) - -{ unsigned long flags, paddr; - int i; - -#ifdef NO_WRITE - if (rwflag || *cmd == 0x0a) { - printk( "ACSI: Write commands disabled!\n" ); - return( 0 ); - } -#endif - - rwflag = rwflag ? 0x100 : 0; - paddr = virt_to_phys( buffer ); - - acsi_delay_end(COMMAND_DELAY); - DISABLE_IRQ(); - - local_irq_save(flags); - /* Low on A1 */ - dma_wd.dma_mode_status = 0x88 | rwflag; - MFPDELAY(); - - /* set DMA address */ - dma_wd.dma_lo = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - dma_wd.dma_md = (unsigned char)paddr; - paddr >>= 8; - MFPDELAY(); - if (ATARIHW_PRESENT(EXTD_DMA)) - st_dma_ext_dmahi = (unsigned short)paddr; - else - dma_wd.dma_hi = (unsigned char)paddr; - MFPDELAY(); - local_irq_restore(flags); - - /* send the command bytes except the last */ - for( i = 0; i < 5; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a | rwflag ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - - /* Clear FIFO and switch DMA to correct direction */ - dma_wd.dma_mode_status = 0x92 | (rwflag ^ 0x100); - MFPDELAY(); - dma_wd.dma_mode_status = 0x92 | rwflag; - MFPDELAY(); - - /* How many sectors for DMA */ - dma_wd.fdc_acces_seccount = blocks; - MFPDELAY(); - - /* send last command byte */ - dma_wd.dma_mode_status = 0x8a | rwflag; - MFPDELAY(); - DMA_LONG_WRITE( *cmd++, 0x0a | rwflag ); - if (enable) - ENABLE_IRQ(); - udelay(80); - - return( 1 ); -} - - -/* - * acsicmd_nodma() sends an ACSI command that requires no DMA. - */ - -int acsicmd_nodma( const char *cmd, int enable) - -{ int i; - - acsi_delay_end(COMMAND_DELAY); - DISABLE_IRQ(); - - /* send first command byte */ - dma_wd.dma_mode_status = 0x88; - MFPDELAY(); - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - - /* send the intermediate command bytes */ - for( i = 0; i < 4; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - - /* send last command byte */ - DMA_LONG_WRITE( *cmd++, 0x0a ); - if (enable) - ENABLE_IRQ(); - udelay(80); - - return( 1 ); - /* Note that the ACSI interrupt is still disabled after this - * function. If you want to get the IRQ delivered, enable it manually! - */ -} - - -static int acsi_reqsense( char *buffer, int targ, int lun) - -{ - CMDSET_TARG_LUN( reqsense_cmd, targ, lun); - if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 ); - if (!acsi_wait_for_IRQ( 10 )) return( 0 ); - acsi_getstatus(); - dma_cache_maintenance( virt_to_phys(buffer), 16, 0 ); - - return( 1 ); -} - - -/* - * ACSI status phase: get the status byte from the bus - * - * I've seen several times that a 0xff status is read, propably due to - * a timing error. In this case, the procedure is repeated after the - * next _IRQ edge. - */ - -int acsi_getstatus( void ) - -{ int status; - - DISABLE_IRQ(); - for(;;) { - if (!acsi_wait_for_IRQ( 100 )) { - acsi_delay_start(); - return( -1 ); - } - dma_wd.dma_mode_status = 0x8a; - MFPDELAY(); - status = dma_wd.fdc_acces_seccount; - if (status != 0xff) break; -#ifdef DEBUG - printk("ACSI: skipping 0xff status byte\n" ); -#endif - udelay(40); - acsi_wait_for_noIRQ( 20 ); - } - dma_wd.dma_mode_status = 0x80; - udelay(40); - acsi_wait_for_noIRQ( 20 ); - - acsi_delay_start(); - return( status & 0x1f ); /* mask of the device# */ -} - - -#if (defined(CONFIG_ATARI_SLM) || defined(CONFIG_ATARI_SLM_MODULE)) - -/* Receive data in an extended status phase. Needed by SLM printer. */ - -int acsi_extstatus( char *buffer, int cnt ) - -{ int status; - - DISABLE_IRQ(); - udelay(80); - while( cnt-- > 0 ) { - if (!acsi_wait_for_IRQ( 40 )) return( 0 ); - dma_wd.dma_mode_status = 0x8a; - MFPDELAY(); - status = dma_wd.fdc_acces_seccount; - MFPDELAY(); - *buffer++ = status & 0xff; - udelay(40); - } - return( 1 ); -} - - -/* Finish an extended status phase */ - -void acsi_end_extstatus( void ) - -{ - dma_wd.dma_mode_status = 0x80; - udelay(40); - acsi_wait_for_noIRQ( 20 ); - acsi_delay_start(); -} - - -/* Send data in an extended command phase */ - -int acsi_extcmd( unsigned char *buffer, int cnt ) - -{ - while( cnt-- > 0 ) { - DMA_LONG_WRITE( *buffer++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */ - } - return( 1 ); -} - -#endif - - -static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip) - -{ int atari_err, i, errcode; - struct acsi_error *arr; - - atari_err = aip->old_atari_disk; - if (atari_err) - errcode = errblk[0] & 0x7f; - else - if ((errblk[0] & 0x70) == 0x70) - errcode = errblk[2] & 0x0f; - else - errcode = errblk[0] & 0x0f; - - printk( KERN_ERR "ACSI error 0x%02x", errcode ); - - if (errblk[0] & 0x80) - printk( " for sector %d", - ((errblk[1] & 0x1f) << 16) | - (errblk[2] << 8) | errblk[0] ); - - arr = atari_err ? atari_acsi_errors : scsi_acsi_errors; - i = atari_err ? sizeof(atari_acsi_errors)/sizeof(*atari_acsi_errors) : - sizeof(scsi_acsi_errors)/sizeof(*scsi_acsi_errors); - - for( --i; i >= 0; --i ) - if (arr[i].code == errcode) break; - if (i >= 0) - printk( ": %s\n", arr[i].text ); -} - -/******************************************************************* - * - * ACSI interrupt routine - * Test, if this is a ACSI interrupt and call the irq handler - * Otherwise ignore this interrupt. - * - *******************************************************************/ - -static irqreturn_t acsi_interrupt(int irq, void *data ) - -{ void (*acsi_irq_handler)(void) = do_acsi; - - do_acsi = NULL; - CLEAR_TIMER(); - - if (!acsi_irq_handler) - acsi_irq_handler = unexpected_acsi_interrupt; - acsi_irq_handler(); - return IRQ_HANDLED; -} - - -/****************************************************************** - * - * The Interrupt handlers - * - *******************************************************************/ - - -static void unexpected_acsi_interrupt( void ) - -{ - printk( KERN_WARNING "Unexpected ACSI interrupt\n" ); -} - - -/* This function is called in case of errors. Because we cannot reset - * the ACSI bus or a single device, there is no other choice than - * retrying several times :-( - */ - -static void bad_rw_intr( void ) - -{ - if (!CURRENT) - return; - - if (++CURRENT->errors >= MAX_ERRORS) - end_request(CURRENT, 0); - /* Otherwise just retry */ -} - - -static void read_intr( void ) - -{ int status; - - status = acsi_getstatus(); - if (status != 0) { - struct gendisk *disk = CURRENT->rq_disk; - struct acsi_info_struct *aip = disk->private_data; - printk(KERN_ERR "%s: ", disk->disk_name); - if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) - printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status ); - else { - acsi_print_error(acsi_buffer, aip); - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - ENABLE_IRQ(); - bad_rw_intr(); - redo_acsi_request(); - return; - } - - dma_cache_maintenance( virt_to_phys(CurrentBuffer), CurrentNSect*512, 0 ); - if (CurrentBuffer == acsi_buffer) - copy_from_acsibuffer(); - - do_end_requests(); - redo_acsi_request(); -} - - -static void write_intr(void) - -{ int status; - - status = acsi_getstatus(); - if (status != 0) { - struct gendisk *disk = CURRENT->rq_disk; - struct acsi_info_struct *aip = disk->private_data; - printk( KERN_ERR "%s: ", disk->disk_name); - if (!acsi_reqsense( acsi_buffer, aip->target, aip->lun)) - printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status ); - else { - acsi_print_error(acsi_buffer, aip); - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - bad_rw_intr(); - redo_acsi_request(); - return; - } - - do_end_requests(); - redo_acsi_request(); -} - - -static void acsi_times_out( unsigned long dummy ) - -{ - DISABLE_IRQ(); - if (!do_acsi) return; - - do_acsi = NULL; - printk( KERN_ERR "ACSI timeout\n" ); - if (!CURRENT) - return; - if (++CURRENT->errors >= MAX_ERRORS) { -#ifdef DEBUG - printk( KERN_ERR "ACSI: too many errors.\n" ); -#endif - end_request(CURRENT, 0); - } - - redo_acsi_request(); -} - - - -/*********************************************************************** - * - * Scatter-gather utility functions - * - ***********************************************************************/ - - -static void copy_to_acsibuffer( void ) - -{ int i; - char *src, *dst; - struct buffer_head *bh; - - src = CURRENT->buffer; - dst = acsi_buffer; - bh = CURRENT->bh; - - if (!bh) - memcpy( dst, src, CurrentNSect*512 ); - else - for( i = 0; i < CurrentNReq; ++i ) { - memcpy( dst, src, bh->b_size ); - dst += bh->b_size; - if ((bh = bh->b_reqnext)) - src = bh->b_data; - } -} - - -static void copy_from_acsibuffer( void ) - -{ int i; - char *src, *dst; - struct buffer_head *bh; - - dst = CURRENT->buffer; - src = acsi_buffer; - bh = CURRENT->bh; - - if (!bh) - memcpy( dst, src, CurrentNSect*512 ); - else - for( i = 0; i < CurrentNReq; ++i ) { - memcpy( dst, src, bh->b_size ); - src += bh->b_size; - if ((bh = bh->b_reqnext)) - dst = bh->b_data; - } -} - - -static void do_end_requests( void ) - -{ int i, n; - - if (!CURRENT->bh) { - CURRENT->nr_sectors -= CurrentNSect; - CURRENT->current_nr_sectors -= CurrentNSect; - CURRENT->sector += CurrentNSect; - if (CURRENT->nr_sectors == 0) - end_request(CURRENT, 1); - } - else { - for( i = 0; i < CurrentNReq; ++i ) { - n = CURRENT->bh->b_size >> 9; - CURRENT->nr_sectors -= n; - CURRENT->current_nr_sectors -= n; - CURRENT->sector += n; - end_request(CURRENT, 1); - } - } -} - - - - -/*********************************************************************** - * - * do_acsi_request and friends - * - ***********************************************************************/ - -static void do_acsi_request( request_queue_t * q ) - -{ - stdma_lock( acsi_interrupt, NULL ); - redo_acsi_request(); -} - - -static void redo_acsi_request( void ) -{ - unsigned block, target, lun, nsect; - char *buffer; - unsigned long pbuffer; - struct buffer_head *bh; - struct gendisk *disk; - struct acsi_info_struct *aip; - - repeat: - CLEAR_TIMER(); - - if (do_acsi) - return; - - if (!CURRENT) { - do_acsi = NULL; - ENABLE_IRQ(); - stdma_release(); - return; - } - - disk = CURRENT->rq_disk; - aip = disk->private_data; - if (CURRENT->bh) { - if (!CURRENT->bh && !buffer_locked(CURRENT->bh)) - panic("ACSI: block not locked"); - } - - block = CURRENT->sector; - if (block+CURRENT->nr_sectors >= get_capacity(disk)) { -#ifdef DEBUG - printk( "%s: attempted access for blocks %d...%ld past end of device at block %ld.\n", - disk->disk_name, - block, block + CURRENT->nr_sectors - 1, - get_capacity(disk)); -#endif - end_request(CURRENT, 0); - goto repeat; - } - if (aip->changed) { - printk( KERN_NOTICE "%s: request denied because cartridge has " - "been changed.\n", disk->disk_name); - end_request(CURRENT, 0); - goto repeat; - } - - target = aip->target; - lun = aip->lun; - - /* Find out how many sectors should be transferred from/to - * consecutive buffers and thus can be done with a single command. - */ - buffer = CURRENT->buffer; - pbuffer = virt_to_phys(buffer); - nsect = CURRENT->current_nr_sectors; - CurrentNReq = 1; - - if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) { - if (!STRAM_ADDR(pbuffer)) { - /* If transfer is done via the ACSI buffer anyway, we can - * assemble as much bh's as fit in the buffer. - */ - while( (bh = bh->b_reqnext) ) { - if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break; - nsect += bh->b_size >> 9; - ++CurrentNReq; - if (bh == CURRENT->bhtail) break; - } - buffer = acsi_buffer; - pbuffer = phys_acsi_buffer; - } - else { - unsigned long pendadr, pnewadr; - pendadr = pbuffer + nsect*512; - while( (bh = bh->b_reqnext) ) { - pnewadr = virt_to_phys(bh->b_data); - if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break; - nsect += bh->b_size >> 9; - pendadr = pnewadr + bh->b_size; - ++CurrentNReq; - if (bh == CURRENT->bhtail) break; - } - } - } - else { - if (!STRAM_ADDR(pbuffer)) { - buffer = acsi_buffer; - pbuffer = phys_acsi_buffer; - if (nsect > ACSI_BUFFER_SECTORS) - nsect = ACSI_BUFFER_SECTORS; - } - } - CurrentBuffer = buffer; - CurrentNSect = nsect; - - if (rq_data_dir(CURRENT) == WRITE) { - CMDSET_TARG_LUN( write_cmd, target, lun ); - CMDSET_BLOCK( write_cmd, block ); - CMDSET_LEN( write_cmd, nsect ); - if (buffer == acsi_buffer) - copy_to_acsibuffer(); - dma_cache_maintenance( pbuffer, nsect*512, 1 ); - do_acsi = write_intr; - if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) { - do_acsi = NULL; - printk( KERN_ERR "ACSI (write): Timeout in command block\n" ); - bad_rw_intr(); - goto repeat; - } - SET_TIMER(); - return; - } - if (rq_data_dir(CURRENT) == READ) { - CMDSET_TARG_LUN( read_cmd, target, lun ); - CMDSET_BLOCK( read_cmd, block ); - CMDSET_LEN( read_cmd, nsect ); - do_acsi = read_intr; - if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) { - do_acsi = NULL; - printk( KERN_ERR "ACSI (read): Timeout in command block\n" ); - bad_rw_intr(); - goto repeat; - } - SET_TIMER(); - return; - } - panic("unknown ACSI command"); -} - - - -/*********************************************************************** - * - * Misc functions: ioctl, open, release, check_change, ... - * - ***********************************************************************/ - -static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct acsi_info_struct *aip = bdev->bd_disk->private_data; - - /* - * Just fake some geometry here, it's nonsense anyway - * To make it easy, use Adaptec's usual 64/32 mapping - */ - geo->heads = 64; - geo->sectors = 32; - geo->cylinders = aip->size >> 11; - return 0; -} - -static int acsi_ioctl( struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ - put_user( aip->target | (aip->lun << 8), - &((Scsi_Idlun *) arg)->dev_id ); - put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id ); - return 0; - default: - return -EINVAL; - } -} - - -/* - * Open a device, check for read-only and lock the medium if it is - * removable. - * - * Changes by Martin Rogge, 9th Aug 1995: - * Check whether check_disk_change (and therefore revalidate_acsidisk) - * was successful. They fail when there is no medium in the drive. - * - * The problem of media being changed during an operation can be - * ignored because of the prevent_removal code. - * - * Added check for the validity of the device number. - * - */ - -static int acsi_open( struct inode * inode, struct file * filp ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - - if (aip->access_count == 0 && aip->removable) { -#if 0 - aip->changed = 1; /* safety first */ -#endif - check_disk_change( inode->i_bdev ); - if (aip->changed) /* revalidate was not successful (no medium) */ - return -ENXIO; - acsi_prevent_removal(aip, 1); - } - aip->access_count++; - - if (filp && filp->f_mode) { - check_disk_change( inode->i_bdev ); - if (filp->f_mode & 2) { - if (aip->read_only) { - acsi_release( inode, filp ); - return -EROFS; - } - } - } - - return 0; -} - -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ - -static int acsi_release( struct inode * inode, struct file * file ) -{ - struct gendisk *disk = inode->i_bdev->bd_disk; - struct acsi_info_struct *aip = disk->private_data; - if (--aip->access_count == 0 && aip->removable) - acsi_prevent_removal(aip, 0); - return( 0 ); -} - -/* - * Prevent or allow a media change for removable devices. - */ - -static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag) -{ - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN(pa_med_rem_cmd, aip->target, aip->lun); - CMDSET_LEN( pa_med_rem_cmd, flag ); - - if (acsicmd_nodma(pa_med_rem_cmd, 0) && acsi_wait_for_IRQ(3*HZ)) - acsi_getstatus(); - /* Do not report errors -- some devices may not know this command. */ - - ENABLE_IRQ(); - stdma_release(); -} - -static int acsi_media_change(struct gendisk *disk) -{ - struct acsi_info_struct *aip = disk->private_data; - - if (!aip->removable) - return 0; - - if (aip->changed) - /* We can be sure that the medium has been changed -- REQUEST - * SENSE has reported this earlier. - */ - return 1; - - /* If the flag isn't set, make a test by reading block 0. - * If errors happen, it seems to be better to say "changed"... - */ - stdma_lock( NULL, NULL ); - CMDSET_TARG_LUN(read_cmd, aip->target, aip->lun); - CMDSET_BLOCK( read_cmd, 0 ); - CMDSET_LEN( read_cmd, 1 ); - if (acsicmd_dma(read_cmd, acsi_buffer, 1, 0, 0) && - acsi_wait_for_IRQ(3*HZ)) { - if (acsi_getstatus()) { - if (acsi_reqsense(acsi_buffer, aip->target, aip->lun)) { - if (CARTRCH_STAT(aip, acsi_buffer)) - aip->changed = 1; - } - else { - printk( KERN_ERR "%s: REQUEST SENSE failed in test for " - "medium change; assuming a change\n", disk->disk_name ); - aip->changed = 1; - } - } - } - else { - printk( KERN_ERR "%s: Test for medium changed timed out; " - "assuming a change\n", disk->disk_name); - aip->changed = 1; - } - ENABLE_IRQ(); - stdma_release(); - - /* Now, after reading a block, the changed status is surely valid. */ - return aip->changed; -} - - -static int acsi_change_blk_size( int target, int lun) - -{ int i; - - for (i=0; i<12; i++) - acsi_buffer[i] = 0; - - acsi_buffer[3] = 8; - acsi_buffer[10] = 2; - CMDSET_TARG_LUN( modeselect_cmd, target, lun); - - if (!acsicmd_dma( modeselect_cmd, acsi_buffer, 1,1,0) || - !acsi_wait_for_IRQ( 3*HZ ) || - acsi_getstatus() != 0 ) { - return(0); - } - return(1); -} - - -static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd ) - -{ - int page; - - CMDSET_TARG_LUN( modesense_cmd, target, lun ); - for (page=0; page<4; page++) { - modesense_cmd[2] = page; - if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0, 0 ) || - !acsi_wait_for_IRQ( 3*HZ ) || - acsi_getstatus()) - continue; - - /* read twice to jump over the second 16-byte border! */ - udelay(300); - if (acsi_wait_for_noIRQ( 20 ) && - acsicmd_nodma( modesense_cmd, 0 ) && - acsi_wait_for_IRQ( 3*HZ ) && - acsi_getstatus() == 0) - break; - } - if (page == 4) { - return(0); - } - - dma_cache_maintenance( phys_acsi_buffer, sizeof(SENSE_DATA), 0 ); - *sd = *(SENSE_DATA *)acsi_buffer; - - /* Validity check, depending on type of data */ - - switch( SENSE_TYPE(*sd) ) { - - case SENSE_TYPE_ATARI: - if (CAPACITY(*sd) == 0) - goto invalid_sense; - break; - - case SENSE_TYPE_SCSI: - if (sd->scsi.descriptor_size != 8) - goto invalid_sense; - break; - - case SENSE_TYPE_UNKNOWN: - - printk( KERN_ERR "ACSI target %d, lun %d: Cannot interpret " - "sense data\n", target, lun ); - - invalid_sense: - -#ifdef DEBUG - { int i; - printk( "Mode sense data for ACSI target %d, lun %d seem not valid:", - target, lun ); - for( i = 0; i < sizeof(SENSE_DATA); ++i ) - printk( "%02x ", (unsigned char)acsi_buffer[i] ); - printk( "\n" ); - } -#endif - return( 0 ); - } - - return( 1 ); -} - - - -/******************************************************************* - * - * Initialization - * - ********************************************************************/ - - -extern struct block_device_operations acsi_fops; - -static struct gendisk *acsi_gendisk[MAX_DEV]; - -#define MAX_SCSI_DEVICE_CODE 10 - -static const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = -{ - "Direct-Access ", - "Sequential-Access", - "Printer ", - "Processor ", - "WORM ", - "CD-ROM ", - "Scanner ", - "Optical Device ", - "Medium Changer ", - "Communications " -}; - -static void print_inquiry(unsigned char *data) -{ - int i; - - printk(KERN_INFO " Vendor: "); - for (i = 8; i < 16; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Model: "); - for (i = 16; i < 32; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk(" Rev: "); - for (i = 32; i < 36; i++) - { - if (data[i] >= 0x20 && i < data[4] + 5) - printk("%c", data[i]); - else - printk(" "); - } - - printk("\n"); - - i = data[0] & 0x1f; - - printk(KERN_INFO " Type: %s ", (i < MAX_SCSI_DEVICE_CODE - ? scsi_device_types[i] - : "Unknown ")); - printk(" ANSI SCSI revision: %02x", data[2] & 0x07); - if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1) - printk(" CCS\n"); - else - printk("\n"); -} - - -/* - * Changes by Martin Rogge, 9th Aug 1995: - * acsi_devinit has been taken out of acsi_geninit, because it needs - * to be called from revalidate_acsidisk. The result of request sense - * is now checked for DRIVE NOT READY. - * - * The structure *aip is only valid when acsi_devinit returns - * DEV_SUPPORTED. - * - */ - -#define DEV_NONE 0 -#define DEV_UNKNOWN 1 -#define DEV_SUPPORTED 2 -#define DEV_SLM 3 - -static int acsi_devinit(struct acsi_info_struct *aip) -{ - int status, got_inquiry; - SENSE_DATA sense; - unsigned char reqsense, extsense; - - /*****************************************************************/ - /* Do a TEST UNIT READY command to test the presence of a device */ - /*****************************************************************/ - - CMDSET_TARG_LUN(tur_cmd, aip->target, aip->lun); - if (!acsicmd_nodma(tur_cmd, 0)) { - /* timed out -> no device here */ -#ifdef DEBUG_DETECT - printk("target %d lun %d: timeout\n", aip->target, aip->lun); -#endif - return DEV_NONE; - } - - /*************************/ - /* Read the ACSI status. */ - /*************************/ - - status = acsi_getstatus(); - if (status) { - if (status == 0x12) { - /* The SLM printer should be the only device that - * responds with the error code in the status byte. In - * correct status bytes, bit 4 is never set. - */ - printk( KERN_INFO "Detected SLM printer at id %d lun %d\n", - aip->target, aip->lun); - return DEV_SLM; - } - /* ignore CHECK CONDITION, since some devices send a - UNIT ATTENTION */ - if ((status & 0x1e) != 0x2) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: status %d\n", - aip->target, aip->lun, status); -#endif - return DEV_UNKNOWN; - } - } - - /*******************************/ - /* Do a REQUEST SENSE command. */ - /*******************************/ - - if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) { - printk( KERN_WARNING "acsi_reqsense failed\n"); - acsi_buffer[0] = 0; - acsi_buffer[2] = UNIT_ATTENTION; - } - reqsense = acsi_buffer[0]; - extsense = acsi_buffer[2] & 0xf; - if (status) { - if ((reqsense & 0x70) == 0x70) { /* extended sense */ - if (extsense != UNIT_ATTENTION && - extsense != NOT_READY) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: extended sense %d\n", - aip->target, aip->lun, extsense); -#endif - return DEV_UNKNOWN; - } - } - else { - if (reqsense & 0x7f) { -#ifdef DEBUG_DETECT - printk("target %d lun %d: sense %d\n", - aip->target, aip->lun, reqsense); -#endif - return DEV_UNKNOWN; - } - } - } - else - if (reqsense == 0x4) { /* SH204 Bug workaround */ -#ifdef DEBUG_DETECT - printk("target %d lun %d status=0 sense=4\n", - aip->target, aip->lun); -#endif - return DEV_UNKNOWN; - } - - /***********************************************************/ - /* Do an INQUIRY command to get more infos on this device. */ - /***********************************************************/ - - /* Assume default values */ - aip->removable = 1; - aip->read_only = 0; - aip->old_atari_disk = 0; - aip->changed = (extsense == NOT_READY); /* medium inserted? */ - aip->size = DEFAULT_SIZE; - got_inquiry = 0; - /* Fake inquiry result for old atari disks */ - memcpy(acsi_buffer, "\000\000\001\000 Adaptec 40xx" - " ", 40); - CMDSET_TARG_LUN(inquiry_cmd, aip->target, aip->lun); - if (acsicmd_dma(inquiry_cmd, acsi_buffer, 1, 0, 0) && - acsi_getstatus() == 0) { - acsicmd_nodma(inquiry_cmd, 0); - acsi_getstatus(); - dma_cache_maintenance( phys_acsi_buffer, 256, 0 ); - got_inquiry = 1; - aip->removable = !!(acsi_buffer[1] & 0x80); - } - if (aip->type == NONE) /* only at boot time */ - print_inquiry(acsi_buffer); - switch(acsi_buffer[0]) { - case TYPE_DISK: - aip->type = HARDDISK; - break; - case TYPE_ROM: - aip->type = CDROM; - aip->read_only = 1; - break; - default: - return DEV_UNKNOWN; - } - /****************************/ - /* Do a MODE SENSE command. */ - /****************************/ - - if (!acsi_mode_sense(aip->target, aip->lun, &sense)) { - printk( KERN_WARNING "No mode sense data.\n" ); - return DEV_UNKNOWN; - } - if ((SECTOR_SIZE(sense) != 512) && - ((aip->type != CDROM) || - !acsi_change_blk_size(aip->target, aip->lun) || - !acsi_mode_sense(aip->target, aip->lun, &sense) || - (SECTOR_SIZE(sense) != 512))) { - printk( KERN_WARNING "Sector size != 512 not supported.\n" ); - return DEV_UNKNOWN; - } - /* There are disks out there that claim to have 0 sectors... */ - if (CAPACITY(sense)) - aip->size = CAPACITY(sense); /* else keep DEFAULT_SIZE */ - if (!got_inquiry && SENSE_TYPE(sense) == SENSE_TYPE_ATARI) { - /* If INQUIRY failed and the sense data suggest an old - * Atari disk (SH20x, Megafile), the disk is not removable - */ - aip->removable = 0; - aip->old_atari_disk = 1; - } - - /******************/ - /* We've done it. */ - /******************/ - - return DEV_SUPPORTED; -} - -EXPORT_SYMBOL(acsi_delay_start); -EXPORT_SYMBOL(acsi_delay_end); -EXPORT_SYMBOL(acsi_wait_for_IRQ); -EXPORT_SYMBOL(acsi_wait_for_noIRQ); -EXPORT_SYMBOL(acsicmd_nodma); -EXPORT_SYMBOL(acsi_getstatus); -EXPORT_SYMBOL(acsi_buffer); -EXPORT_SYMBOL(phys_acsi_buffer); - -#ifdef CONFIG_ATARI_SLM_MODULE -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); - -EXPORT_SYMBOL(acsi_extstatus); -EXPORT_SYMBOL(acsi_end_extstatus); -EXPORT_SYMBOL(acsi_extcmd); -EXPORT_SYMBOL(acsi_attach_SLMs); - -/* to remember IDs of SLM devices, SLM module is loaded later - * (index is target#, contents is lun#, -1 means "no SLM") */ -int SLM_devices[8]; -#endif - -static struct block_device_operations acsi_fops = { - .owner = THIS_MODULE, - .open = acsi_open, - .release = acsi_release, - .ioctl = acsi_ioctl, - .getgeo = acsi_getgeo, - .media_changed = acsi_media_change, - .revalidate_disk= acsi_revalidate, -}; - -#ifdef CONFIG_ATARI_SLM_MODULE -/* call attach_slm() for each device that is a printer; needed for init of SLM - * driver as a module, since it's not yet present if acsi.c is inited and thus - * the bus gets scanned. */ -void acsi_attach_SLMs( int (*attach_func)( int, int ) ) -{ - int i, n = 0; - - for( i = 0; i < 8; ++i ) - if (SLM_devices[i] >= 0) - n += (*attach_func)( i, SLM_devices[i] ); - printk( KERN_INFO "Found %d SLM printer(s) total.\n", n ); -} -#endif /* CONFIG_ATARI_SLM_MODULE */ - - -int acsi_init( void ) -{ - int err = 0; - int i, target, lun; - struct acsi_info_struct *aip; -#ifdef CONFIG_ATARI_SLM - int n_slm = 0; -#endif - if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI)) - return 0; - if (register_blkdev(ACSI_MAJOR, "ad")) { - err = -EBUSY; - goto out1; - } - if (!(acsi_buffer = - (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) { - err = -ENOMEM; - printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" ); - goto out2; - } - phys_acsi_buffer = virt_to_phys( acsi_buffer ); - STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000; - - acsi_queue = blk_init_queue(do_acsi_request, &acsi_lock); - if (!acsi_queue) { - err = -ENOMEM; - goto out2a; - } -#ifdef CONFIG_ATARI_SLM - err = slm_init(); -#endif - if (err) - goto out3; - - printk( KERN_INFO "Probing ACSI devices:\n" ); - NDevices = 0; -#ifdef CONFIG_ATARI_SLM_MODULE - for( i = 0; i < 8; ++i ) - SLM_devices[i] = -1; -#endif - stdma_lock(NULL, NULL); - - for (target = 0; target < 8 && NDevices < MAX_DEV; ++target) { - lun = 0; - do { - aip = &acsi_info[NDevices]; - aip->type = NONE; - aip->target = target; - aip->lun = lun; - i = acsi_devinit(aip); - switch (i) { - case DEV_SUPPORTED: - printk( KERN_INFO "Detected "); - switch (aip->type) { - case HARDDISK: - printk("disk"); - break; - case CDROM: - printk("cdrom"); - break; - default: - } - printk(" ad%c at id %d lun %d ", - 'a' + NDevices, target, lun); - if (aip->removable) - printk("(removable) "); - if (aip->read_only) - printk("(read-only) "); - if (aip->size == DEFAULT_SIZE) - printk(" unkown size, using default "); - printk("%ld MByte\n", - (aip->size*512+1024*1024/2)/(1024*1024)); - NDevices++; - break; - case DEV_SLM: -#ifdef CONFIG_ATARI_SLM - n_slm += attach_slm( target, lun ); - break; -#endif -#ifdef CONFIG_ATARI_SLM_MODULE - SLM_devices[target] = lun; - break; -#endif - /* neither of the above: fall through to unknown device */ - case DEV_UNKNOWN: - printk( KERN_INFO "Detected unsupported device at " - "id %d lun %d\n", target, lun); - break; - } - } -#ifdef CONFIG_ACSI_MULTI_LUN - while (i != DEV_NONE && ++lun < MAX_LUN); -#else - while (0); -#endif - } - - /* reenable interrupt */ - ENABLE_IRQ(); - stdma_release(); - -#ifndef CONFIG_ATARI_SLM - printk( KERN_INFO "Found %d ACSI device(s) total.\n", NDevices ); -#else - printk( KERN_INFO "Found %d ACSI device(s) and %d SLM printer(s) total.\n", - NDevices, n_slm ); -#endif - err = -ENOMEM; - for( i = 0; i < NDevices; ++i ) { - acsi_gendisk[i] = alloc_disk(16); - if (!acsi_gendisk[i]) - goto out4; - } - - for( i = 0; i < NDevices; ++i ) { - struct gendisk *disk = acsi_gendisk[i]; - sprintf(disk->disk_name, "ad%c", 'a'+i); - aip = &acsi_info[NDevices]; - disk->major = ACSI_MAJOR; - disk->first_minor = i << 4; - if (acsi_info[i].type != HARDDISK) - disk->minors = 1; - disk->fops = &acsi_fops; - disk->private_data = &acsi_info[i]; - set_capacity(disk, acsi_info[i].size); - disk->queue = acsi_queue; - add_disk(disk); - } - return 0; -out4: - while (i--) - put_disk(acsi_gendisk[i]); -out3: - blk_cleanup_queue(acsi_queue); -out2a: - atari_stram_free( acsi_buffer ); -out2: - unregister_blkdev( ACSI_MAJOR, "ad" ); -out1: - return err; -} - - -#ifdef MODULE - -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - int err; - - if ((err = acsi_init())) - return( err ); - printk( KERN_INFO "ACSI driver loaded as module.\n"); - return( 0 ); -} - -void cleanup_module(void) -{ - int i; - del_timer( &acsi_timer ); - blk_cleanup_queue(acsi_queue); - atari_stram_free( acsi_buffer ); - - if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0) - printk( KERN_ERR "acsi: cleanup_module failed\n"); - - for (i = 0; i < NDevices; i++) { - del_gendisk(acsi_gendisk[i]); - put_disk(acsi_gendisk[i]); - } -} -#endif - -/* - * This routine is called to flush all partitions and partition tables - * for a changed scsi disk, and then re-read the new partition table. - * If we are revalidating a disk because of a media change, then we - * enter with usage == 0. If we are using an ioctl, we automatically have - * usage == 1 (we need an open channel to use an ioctl :-), so this - * is our limit. - * - * Changes by Martin Rogge, 9th Aug 1995: - * got cd-roms to work by calling acsi_devinit. There are only two problems: - * First, if there is no medium inserted, the status will remain "changed". - * That is no problem at all, but our design of three-valued logic (medium - * changed, medium not changed, no medium inserted). - * Secondly the check could fail completely and the drive could deliver - * nonsensical data, which could mess up the acsi_info[] structure. In - * that case we try to make the entry safe. - * - */ - -static int acsi_revalidate(struct gendisk *disk) -{ - struct acsi_info_struct *aip = disk->private_data; - stdma_lock( NULL, NULL ); - if (acsi_devinit(aip) != DEV_SUPPORTED) { - printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n", - aip->target, aip->lun); - aip->size = 0; - aip->read_only = 1; - aip->removable = 1; - aip->changed = 1; /* next acsi_open will try again... */ - } - - ENABLE_IRQ(); - stdma_release(); - set_capacity(disk, aip->size); - return 0; -} From 9cff3b383dad193b0762c27278a16237e10b53dc Mon Sep 17 00:00:00 2001 From: "Mike Miller (OS Dev" Date: Tue, 19 Jun 2007 20:52:18 +0200 Subject: [PATCH 392/551] cciss: add new controller support for P700m This patch adds support for the Smart Array P700m SAS controller. This new controller will ship Fall 2007. Signed-off-by: Mike Miller Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 5acc6c44aead..0fcad430474e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -87,6 +87,7 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, {0,} @@ -119,6 +120,7 @@ static struct board_type products[] = { {0x3214103C, "Smart Array E200i", &SA5_access, 120}, {0x3215103C, "Smart Array E200i", &SA5_access, 120}, {0x3237103C, "Smart Array E500", &SA5_access, 512}, + {0x323D103C, "Smart Array P700m", &SA5_access, 512}, {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, }; From e654bc4393e85e326993256d80b9710a4d6411ff Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Wed, 20 Jun 2007 13:53:23 +0200 Subject: [PATCH 393/551] [PATCH] fix request->cmd == INT cases - I have unearthed very old bugs in stale drivers that still used request->cmd as a READ|WRITE int - This patch is maybe a proof that these drivers have not been used for a long time. Should they be removed completely? Drivers that currently do not work for sure: drivers/acorn/block/fd1772.c | 2 +- drivers/acorn/block/mfmhd.c | 8 ++++---- drivers/cdrom/aztcd.c | 2 +- drivers/cdrom/cm206.c | 2 +- drivers/cdrom/gscd.c | 2 +- drivers/cdrom/mcdx.c | 2 +- drivers/cdrom/optcd.c | 2 +- drivers/cdrom/sjcd.c | 2 +- Drivers with cosmetic fixes only: b/drivers/block/amiflop.c b/drivers/block/nbd.c b/drivers/ide/legacy/hd.c Signed-off-by: Boaz Harrosh Signed-off-by: Jens Axboe --- drivers/acorn/block/fd1772.c | 2 +- drivers/acorn/block/mfmhd.c | 13 +++---------- drivers/block/amiflop.c | 2 +- drivers/block/nbd.c | 2 +- drivers/cdrom/aztcd.c | 2 +- drivers/cdrom/cm206.c | 2 +- drivers/cdrom/gscd.c | 2 +- drivers/cdrom/mcdx.c | 2 +- drivers/cdrom/optcd.c | 2 +- drivers/cdrom/sjcd.c | 2 +- drivers/ide/legacy/hd.c | 3 ++- 11 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c index 674bf81c6e66..423ed08fb6f7 100644 --- a/drivers/acorn/block/fd1772.c +++ b/drivers/acorn/block/fd1772.c @@ -1246,7 +1246,7 @@ repeat: del_timer(&motor_off_timer); ReqCnt = 0; - ReqCmd = CURRENT->cmd; + ReqCmd = rq_data_dir(CURRENT); ReqBlock = CURRENT->sector; ReqBuffer = CURRENT->buffer; setup_req_params(drive); diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c index 689a4c3542ba..d85520f78e68 100644 --- a/drivers/acorn/block/mfmhd.c +++ b/drivers/acorn/block/mfmhd.c @@ -439,7 +439,7 @@ static void mfm_rw_intr(void) a choice of command end or some data which is ready to be collected */ /* I think we have to transfer data while the interrupt line is on and its not any other type of interrupt */ - if (CURRENT->cmd == WRITE) { + if (rq_data_dir(CURRENT) == WRITE) { extern void hdc63463_writedma(void); if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) { printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n"); @@ -799,7 +799,7 @@ static void issue_request(unsigned int block, unsigned int nsect, raw_cmd.head = start_head; raw_cmd.cylinder = track / p->heads; raw_cmd.cmdtype = CURRENT->cmd; - raw_cmd.cmdcode = CURRENT->cmd == WRITE ? CMD_WD : CMD_RD; + raw_cmd.cmdcode = rq_data_dir(CURRENT) == WRITE ? CMD_WD : CMD_RD; raw_cmd.cmddata[0] = dev + 1; /* DAG: +1 to get US */ raw_cmd.cmddata[1] = raw_cmd.head; raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8; @@ -830,7 +830,7 @@ static void issue_request(unsigned int block, unsigned int nsect, hdc63463_dataleft = nsect * 256; /* Better way? */ DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n", - raw_cmd.dev + 'a', (CURRENT->cmd == READ) ? "read" : "writ", + raw_cmd.dev + 'a', rq_data_dir(CURRENT) == READ ? "read" : "writ", raw_cmd.cylinder, raw_cmd.head, raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT); @@ -917,13 +917,6 @@ static void mfm_request(void) DBG("mfm_request: block after offset=%d\n", block); - if (CURRENT->cmd != READ && CURRENT->cmd != WRITE) { - printk("unknown mfm-command %d\n", CURRENT->cmd); - end_request(CURRENT, 0); - Busy = 0; - printk("mfm: continue 4\n"); - continue; - } issue_request(block, nsect, CURRENT); break; diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 27a139025ced..6ce8b897e262 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1363,7 +1363,7 @@ static void redo_fd_request(void) #ifdef DEBUG printk("fd: sector %ld + %d requested for %s\n", CURRENT->sector,cnt, - (CURRENT->cmd==READ)?"read":"write"); + (rq_data_dir(CURRENT) == READ) ? "read" : "write"); #endif block = CURRENT->sector + cnt; if ((int)block > floppy->blocks) { diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 069ae39a9cd9..c575fb1d585f 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -416,7 +416,7 @@ static void nbd_clear_que(struct nbd_device *lo) /* * We always wait for result of write, for now. It would be nice to make it optional * in future - * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) + * if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) * { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); } */ diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index 1f9fb7a96703..d7fbfaae2449 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c @@ -229,7 +229,7 @@ static struct request_queue *azt_queue; static int current_valid(void) { return CURRENT && - CURRENT->cmd == READ && + rq_data_dir(CURRENT) == READ && CURRENT->sector != -1; } diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index 230131163240..2f8fe3b6bbd0 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c @@ -851,7 +851,7 @@ static void do_cm206_request(request_queue_t * q) if (!req) return; - if (req->cmd != READ) { + if (rq_data_dir(req) != READ) { debug(("Non-read command %d on cdrom\n", req->cmd)); end_request(req, 0); continue; diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c index b3ab6e9b8df1..176742ed007b 100644 --- a/drivers/cdrom/gscd.c +++ b/drivers/cdrom/gscd.c @@ -264,7 +264,7 @@ repeat: if (req->sector == -1) goto out; - if (req->cmd != READ) { + if (rq_data_dir(req) != READ) { printk("GSCD: bad cmd %u\n", rq_data_dir(req)); end_request(req, 0); goto repeat; diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 4310cc84dfed..972ee9c8247c 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c @@ -596,7 +596,7 @@ static void do_mcdx_request(request_queue_t * q) xtrace(REQUEST, "do_request() (%lu + %lu)\n", req->sector, req->nr_sectors); - if (req->cmd != READ) { + if (rq_data_dir(req) != READ) { xwarn("do_request(): non-read command to cd!!\n"); xtrace(REQUEST, "end_request(0): write\n"); end_request(req, 0); diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c index 3541690a77d4..efd619c0fe10 100644 --- a/drivers/cdrom/optcd.c +++ b/drivers/cdrom/optcd.c @@ -977,7 +977,7 @@ static int update_toc(void) static int current_valid(void) { return CURRENT && - CURRENT->cmd == READ && + rq_data_dir(CURRENT) == READ && CURRENT->sector != -1; } diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c index 5409fca5bbfc..76c24e679e68 100644 --- a/drivers/cdrom/sjcd.c +++ b/drivers/cdrom/sjcd.c @@ -1064,7 +1064,7 @@ static void sjcd_invalidate_buffers(void) static int current_valid(void) { return CURRENT && - CURRENT->cmd == READ && + rq_data_dir(CURRENT) == READ && CURRENT->sector != -1; } diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 661c12f6dda6..7f4c0a5050a1 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -623,7 +623,8 @@ repeat: cyl = track / disk->head; #ifdef DEBUG printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", - req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ", + req->rq_disk->disk_name, + req_data_dir(req) == READ ? "read" : "writ", cyl, head, sec, nsect, req->buffer); #endif if (blk_fs_request(req)) { From f3f541f9ded9dd37edca103dd3be49bfbd9e730d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 21 Jun 2007 08:29:34 +0200 Subject: [PATCH 394/551] Remove legacy CDROM drivers They are all broken beyond repair. Given that nobody has complained about them (most haven't worked in 2.6 AT ALL), remove them from the tree. A new mitsumi driver that actually works is in progress, it'll get added when completed. Signed-off-by: Jens Axboe --- drivers/Kconfig | 2 - drivers/cdrom/Kconfig | 213 -- drivers/cdrom/Makefile | 10 - drivers/cdrom/aztcd.c | 2492 ---------------- drivers/cdrom/aztcd.h | 162 - drivers/cdrom/cdu31a.c | 3251 -------------------- drivers/cdrom/cdu31a.h | 411 --- drivers/cdrom/cm206.c | 1594 ---------- drivers/cdrom/cm206.h | 171 -- drivers/cdrom/gscd.c | 1029 ------- drivers/cdrom/gscd.h | 108 - drivers/cdrom/isp16.c | 374 --- drivers/cdrom/isp16.h | 72 - drivers/cdrom/mcdx.c | 1943 ------------ drivers/cdrom/mcdx.h | 185 -- drivers/cdrom/optcd.c | 2105 ------------- drivers/cdrom/optcd.h | 52 - drivers/cdrom/sbpcd.c | 5966 ------------------------------------- drivers/cdrom/sbpcd.h | 839 ------ drivers/cdrom/sjcd.c | 1815 ----------- drivers/cdrom/sjcd.h | 181 -- drivers/cdrom/sonycd535.c | 1689 ----------- drivers/cdrom/sonycd535.h | 183 -- 23 files changed, 24847 deletions(-) delete mode 100644 drivers/cdrom/Kconfig delete mode 100644 drivers/cdrom/aztcd.c delete mode 100644 drivers/cdrom/aztcd.h delete mode 100644 drivers/cdrom/cdu31a.c delete mode 100644 drivers/cdrom/cdu31a.h delete mode 100644 drivers/cdrom/cm206.c delete mode 100644 drivers/cdrom/cm206.h delete mode 100644 drivers/cdrom/gscd.c delete mode 100644 drivers/cdrom/gscd.h delete mode 100644 drivers/cdrom/isp16.c delete mode 100644 drivers/cdrom/isp16.h delete mode 100644 drivers/cdrom/mcdx.c delete mode 100644 drivers/cdrom/mcdx.h delete mode 100644 drivers/cdrom/optcd.c delete mode 100644 drivers/cdrom/optcd.h delete mode 100644 drivers/cdrom/sbpcd.c delete mode 100644 drivers/cdrom/sbpcd.h delete mode 100644 drivers/cdrom/sjcd.c delete mode 100644 drivers/cdrom/sjcd.h delete mode 100644 drivers/cdrom/sonycd535.c delete mode 100644 drivers/cdrom/sonycd535.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 050323fd79e9..4e6487d461f3 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -24,8 +24,6 @@ source "drivers/scsi/Kconfig" source "drivers/ata/Kconfig" -source "drivers/cdrom/Kconfig" - source "drivers/md/Kconfig" source "drivers/message/fusion/Kconfig" diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig deleted file mode 100644 index 4b12e9031fb3..000000000000 --- a/drivers/cdrom/Kconfig +++ /dev/null @@ -1,213 +0,0 @@ -# -# CDROM driver configuration -# - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - depends on ISA && BLOCK - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - . - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - To compile these CD-ROM drivers as a module, choose M instead of Y. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - -config AZTCD - tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM CDROM support" - depends on CD_NO_IDESCSI - ---help--- - This is your driver if you have an Aztech CDA268-01A, Orchid - CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or - CR540 CD-ROM drive. This driver -- just like all these CD-ROM - drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such - as Aztech CDA269-031SE. Please read the file - . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called aztcd. - -config GSCD - tristate "Goldstar R420 CDROM support" - depends on CD_NO_IDESCSI - ---help--- - If this is your CD-ROM drive, say Y here. As described in the file - , you might have to change a setting - in the file before compiling the - kernel. Please read the file . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called gscd. - -config SBPCD - tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support" - depends on CD_NO_IDESCSI && BROKEN_ON_SMP - ---help--- - This driver supports most of the drives which use the Panasonic or - Sound Blaster interface. Please read the file - . - - The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives - (sometimes labeled "Creative"), the Creative Labs CD200, the - Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x - model), the TEAC CD-55A fall under this category. Some other - "electrically compatible" drives (Vertos, Genoa, some Funai models) - are currently not supported; for the Sanyo H94A drive currently a - separate driver (asked later) is responsible. Most drives have a - uniquely shaped faceplate, with a caddyless motorized drawer, but - without external brand markings. The older CR-52x drives have a - caddy and manual loading/eject, but still no external markings. The - driver is able to do an extended auto-probing for interface - addresses and drive types; this can help to find facts in cases you - are not sure, but can consume some time during the boot process if - none of the supported drives gets found. Once your drive got found, - you should enter the reported parameters into - and set "DISTRIBUTION 0" there. - - This driver can support up to four CD-ROM controller cards, and each - card can support up to four CD-ROM drives; if you say Y here, you - will be asked how many controller cards you have. If compiled as a - module, only one controller card (but with up to four drives) is - usable. - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called sbpcd. - -config MCDX - tristate "Mitsumi CDROM support" - depends on CD_NO_IDESCSI - ---help--- - Use this driver if you want to be able to use your Mitsumi LU-005, - FX-001 or FX-001D CD-ROM drive. - - Please read the file . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called mcdx. - -config OPTCD - tristate "Optics Storage DOLPHIN 8000AT CDROM support" - depends on CD_NO_IDESCSI - ---help--- - This is the driver for the 'DOLPHIN' drive with a 34-pin Sony - compatible interface. It also works with the Lasermate CR328A. If - you have one of those, say Y. This driver does not work for the - Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that - one. Please read the file . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called optcd. - -config CM206 - tristate "Philips/LMS CM206 CDROM support" - depends on CD_NO_IDESCSI && BROKEN_ON_SMP - ---help--- - If you have a Philips/LMS CD-ROM drive cm206 in combination with a - cm260 host adapter card, say Y here. Please also read the file - . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called cm206. - -config SJCD - tristate "Sanyo CDR-H94A CDROM support" - depends on CD_NO_IDESCSI - help - If this is your CD-ROM drive, say Y here and read the file - . You should then also say Y or M to - "ISO 9660 CD-ROM file system support" below, because that's the - file system used on CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called sjcd. - -config ISP16_CDI - tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support" - depends on CD_NO_IDESCSI - ---help--- - These are sound cards with built-in cdrom interfaces using the OPTi - 82C928 or 82C929 chips. Say Y here to have them detected and - possibly configured at boot time. In addition, You'll have to say Y - to a driver for the particular cdrom drive you have attached to the - card. Read for details. - - To compile this driver as a module, choose M here: the - module will be called isp16. - -config CDU31A - tristate "Sony CDU31A/CDU33A CDROM support" - depends on CD_NO_IDESCSI && BROKEN_ON_SMP - ---help--- - These CD-ROM drives have a spring-pop-out caddyless drawer, and a - rectangular green LED centered beneath it. NOTE: these CD-ROM - drives will not be auto detected by the kernel at boot time; you - have to provide the interface address as an option to the kernel at - boot time as described in or fill - in your parameters into . Try "man - bootparam" or see the documentation of your boot loader (lilo or - loadlin) about how to pass options to the kernel. - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called cdu31a. - -config CDU535 - tristate "Sony CDU535 CDROM support" - depends on CD_NO_IDESCSI - ---help--- - This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM - drives. Please read the file . - - If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM - file system support" below, because that's the file system used on - CD-ROMs. - - To compile this driver as a module, choose M here: the - module will be called sonycd535. - -endmenu diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile index d1d1e5a4be73..774c180a4e11 100644 --- a/drivers/cdrom/Makefile +++ b/drivers/cdrom/Makefile @@ -10,14 +10,4 @@ obj-$(CONFIG_BLK_DEV_SR) += cdrom.o obj-$(CONFIG_PARIDE_PCD) += cdrom.o obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o -obj-$(CONFIG_AZTCD) += aztcd.o -obj-$(CONFIG_CDU31A) += cdu31a.o cdrom.o -obj-$(CONFIG_CM206) += cm206.o cdrom.o -obj-$(CONFIG_GSCD) += gscd.o -obj-$(CONFIG_ISP16_CDI) += isp16.o -obj-$(CONFIG_MCDX) += mcdx.o cdrom.o -obj-$(CONFIG_OPTCD) += optcd.o -obj-$(CONFIG_SBPCD) += sbpcd.o cdrom.o -obj-$(CONFIG_SJCD) += sjcd.o -obj-$(CONFIG_CDU535) += sonycd535.o obj-$(CONFIG_VIOCD) += viocd.o cdrom.o diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c deleted file mode 100644 index d7fbfaae2449..000000000000 --- a/drivers/cdrom/aztcd.c +++ /dev/null @@ -1,2492 +0,0 @@ -#define AZT_VERSION "2.60" - -/* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $ - linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver - - Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de) - - based on Mitsumi CDROM driver by Martin Hariss and preworks by - Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby - Schirmer. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - HISTORY - V0.0 Adaption to Aztech CD268-01A Version 1.3 - Version is PRE_ALPHA, unresolved points: - 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW - thus driver causes CPU overhead and is very slow - 2. could not find a way to stop the drive, when it is - in data read mode, therefore I had to set - msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one - frame can be read in sequence, this is also the reason for - 3. getting 'timeout in state 4' messages, but nevertheless - it works - W.Zimmermann, Oct. 31, 1994 - V0.1 Version is ALPHA, problems #2 and #3 resolved. - W.Zimmermann, Nov. 3, 1994 - V0.2 Modification to some comments, debugging aids for partial test - with Borland C under DOS eliminated. Timer interrupt wait - STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented; - use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_ - SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy - waiting seems better to me than interrupt rescheduling. - Besides that, when used in the wrong place, STEN_LOW_WAIT causes - kernel panic. - In function aztPlay command ACMD_PLAY_AUDIO added, should make - audio functions work. The Aztech drive needs different commands - to read data tracks and play audio tracks. - W.Zimmermann, Nov. 8, 1994 - V0.3 Recognition of missing drive during boot up improved (speeded up). - W.Zimmermann, Nov. 13, 1994 - V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll) - including removal of all 'goto' commands. :-); - J. Nardone, Nov. 14, 1994 - V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had - to make some "compatibility" defines in azt.h; please note, - that the source file was renamed to azt.c, the include file to - azt.h - Speeded up drive recognition during init (will be a little bit - slower than before if no drive is installed!); suggested by - Robby Schirmer. - read_count declared volatile and set to AZT_BUF_SIZ to make - drive faster (now 300kB/sec, was 60kB/sec before, measured - by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096'; - different AZT_BUF_SIZes were test, above 16 no further im- - provement seems to be possible; suggested by E.Moenkeberg. - W.Zimmermann, Nov. 18, 1994 - V0.42 Included getAztStatus command in GetQChannelInfo() to allow - reading Q-channel info on audio disks, if drive is stopped, - and some other bug fixes in the audio stuff, suggested by - Robby Schirmer. - Added more ioctls (reading data in mode 1 and mode 2). - Completely removed the old azt_poll() routine. - Detection of ORCHID CDS-3110 in aztcd_init implemented. - Additional debugging aids (see the readme file). - W.Zimmermann, Dec. 9, 1994 - V0.50 Autodetection of drives implemented. - W.Zimmermann, Dec. 12, 1994 - V0.52 Prepared for including in the standard kernel, renamed most - variables to contain 'azt', included autoconf.h - W.Zimmermann, Dec. 16, 1994 - V0.6 Version for being included in the standard Linux kernel. - Renamed source and header file to aztcd.c and aztcd.h - W.Zimmermann, Dec. 24, 1994 - V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case - CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl, - which causes kernel crashes when playing audio, changed - include-files (config.h instead of autoconf.h, removed - delay.h) - W.Zimmermann, Jan. 8, 1995 - V0.72 Some more modifications for adaption to the standard kernel. - W.Zimmermann, Jan. 16, 1995 - V0.80 aztcd is now part of the standard kernel since version 1.1.83. - Modified the SET_TIMER and CLEAR_TIMER macros to comply with - the new timer scheme. - W.Zimmermann, Jan. 21, 1995 - V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn - the channels on and off. If it works better with your drive, - please mail me. Also implemented ACMD_CLOSE for CDROMSTART. - W.Zimmermann, Jan. 24, 1995 - V1.00 Implemented close and lock tray commands. Patches supplied by - Frank Racis - Added support for loadable MODULEs, so aztcd can now also be - loaded by insmod and removed by rmmod during run time - Werner Zimmermann, Mar. 24, 95 - V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives - connected to Soundwave32 cards. Release for LST 2.1. - (still experimental) - Werner Zimmermann, May 8, 95 - V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but - sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver- - sion needs an update of Dosemu0.60's cdrom.c, which will come with the - next revision of Dosemu. - Also Soundwave32 support now works. - Werner Zimmermann, May 22, 95 - V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu) - Werner Zimmermann, July 4, 95 - V1.40 Started multisession support. Implementation copied from mcdx.c - by Heiko Schlittermann. Not tested yet. - Werner Zimmermann, July 15, 95 - V1.50 Implementation of ioctl CDROMRESET, continued multisession, began - XA, but still untested. Heavy modifications to drive status de- - tection. - Werner Zimmermann, July 25, 95 - V1.60 XA support now should work. Speeded up drive recognition in cases, - where no drive is installed. - Werner Zimmermann, August 8, 1995 - V1.70 Multisession support now is completed, but there is still not - enough testing done. If you can test it, please contact me. For - details please read Documentation/cdrom/aztcd - Werner Zimmermann, August 19, 1995 - V1.80 Modification to suit the new kernel boot procedure introduced - with kernel 1.3.33. Will definitely not work with older kernels. - Programming done by Linus himself. - Werner Zimmermann, October 11, 1995 - V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza. - Werner Zimmermann, October 21, 1995 - V2.00 Changed #include "blk.h" to as the directory - structure was changed. README.aztcd is now /usr/src/docu- - mentation/cdrom/aztcd - Werner Zimmermann, November 10, 95 - V2.10 Started to modify azt_poll to prevent reading beyond end of - tracks. - Werner Zimmermann, December 3, 95 - V2.20 Changed some comments - Werner Zimmermann, April 1, 96 - V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520 - delivered by H.Berger with preworks by E.Moenkeberg. - Werner Zimmermann, April 29, 96 - V2.40 Reorganized the placement of functions in the source code file - to reflect the layered approach; did not actually change code - Werner Zimmermann, May 1, 96 - V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in - aztcd_ioctl; check_aztcd_media_change modified - Werner Zimmermann, May 16, 96 - V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize - Adaption to linux kernel > 2.1.0 - Werner Zimmermann, Nov 29, 97 - - November 1999 -- Make kernel-parameter implementation work with 2.3.x - Removed init_module & cleanup_module in favor of - module_init & module_exit. - Torben Mathiasen -*/ - -#include -#include "aztcd.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -/*########################################################################### - Defines - ########################################################################### -*/ - -#define MAJOR_NR AZTECH_CDROM_MAJOR -#define QUEUE (azt_queue) -#define CURRENT elv_next_request(azt_queue) -#define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \ - delay_timer.function = (void *) (func); \ - add_timer(&delay_timer); - -#define CLEAR_TIMER del_timer(&delay_timer); - -#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\ - return value;} -#define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\ - return;} - -/* Macros to switch the IDE-interface to the slave device and back to the master*/ -#define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \ - outb_p(0x10,azt_port+6); \ - outb_p(0x00,azt_port+7); \ - outb_p(0x10,azt_port+6); -#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6); - - -#if 0 -#define AZT_TEST -#define AZT_TEST1 /* */ -#define AZT_TEST2 /* do_aztcd_request */ -#define AZT_TEST3 /* AZT_S_state */ -#define AZT_TEST4 /* QUICK_LOOP-counter */ -#define AZT_TEST5 /* port(1) state */ -#define AZT_DEBUG -#define AZT_DEBUG_MULTISESSION -#endif - -static struct request_queue *azt_queue; - -static int current_valid(void) -{ - return CURRENT && - rq_data_dir(CURRENT) == READ && - CURRENT->sector != -1; -} - -#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA) -#define AZT_BUF_SIZ 16 - -#define READ_TIMEOUT 3000 - -#define azt_port aztcd /*needed for the modutils */ - -/*########################################################################## - Type Definitions - ########################################################################## -*/ -enum azt_state_e { AZT_S_IDLE, /* 0 */ - AZT_S_START, /* 1 */ - AZT_S_MODE, /* 2 */ - AZT_S_READ, /* 3 */ - AZT_S_DATA, /* 4 */ - AZT_S_STOP, /* 5 */ - AZT_S_STOPPING /* 6 */ -}; -enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */ - AZT_MODE_1, /*read mode for normal CD-ROMs */ - AZT_MODE_2 /*read mode for XA CD-ROMs */ -}; - -/*########################################################################## - Global Variables - ########################################################################## -*/ -static int aztPresent = 0; - -static volatile int azt_transfer_is_active = 0; - -static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */ -#if AZT_PRIVATE_IOCTLS -static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */ -#endif - -static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn; -static volatile int azt_buf_in, azt_buf_out = -1; -static volatile int azt_error = 0; -static int azt_open_count = 0; -static volatile enum azt_state_e azt_state = AZT_S_IDLE; -#ifdef AZT_TEST3 -static volatile enum azt_state_e azt_state_old = AZT_S_STOP; -static volatile int azt_st_old = 0; -#endif -static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1; - -static int azt_mode = -1; -static volatile int azt_read_count = 1; - -static int azt_port = AZT_BASE_ADDR; - -module_param(azt_port, int, 0); - -static int azt_port_auto[16] = AZT_BASE_AUTO; - -static char azt_cont = 0; -static char azt_init_end = 0; -static char azt_auto_eject = AZT_AUTO_EJECT; - -static int AztTimeout, AztTries; -static DECLARE_WAIT_QUEUE_HEAD(azt_waitq); -static DEFINE_TIMER(delay_timer, NULL, 0, 0); - -static struct azt_DiskInfo DiskInfo; -static struct azt_Toc Toc[MAX_TRACKS]; -static struct azt_Play_msf azt_Play; - -static int aztAudioStatus = CDROM_AUDIO_NO_STATUS; -static char aztDiskChanged = 1; -static char aztTocUpToDate = 0; - -static unsigned char aztIndatum; -static unsigned long aztTimeOutCount; -static int aztCmd = 0; - -static DEFINE_SPINLOCK(aztSpin); - -/*########################################################################### - Function Prototypes - ########################################################################### -*/ -/* CDROM Drive Low Level I/O Functions */ -static void aztStatTimer(void); - -/* CDROM Drive Command Functions */ -static int aztGetDiskInfo(void); -#if AZT_MULTISESSION -static int aztGetMultiDiskInfo(void); -#endif -static int aztGetToc(int multi); - -/* Kernel Interface Functions */ -static int check_aztcd_media_change(struct gendisk *disk); -static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg); -static int aztcd_open(struct inode *ip, struct file *fp); -static int aztcd_release(struct inode *inode, struct file *file); - -static struct block_device_operations azt_fops = { - .owner = THIS_MODULE, - .open = aztcd_open, - .release = aztcd_release, - .ioctl = aztcd_ioctl, - .media_changed = check_aztcd_media_change, -}; - -/* Aztcd State Machine: Controls Drive Operating State */ -static void azt_poll(void); - -/* Miscellaneous support functions */ -static void azt_hsg2msf(long hsg, struct msf *msf); -static long azt_msf2hsg(struct msf *mp); -static void azt_bin2bcd(unsigned char *p); -static int azt_bcd2bin(unsigned char bcd); - -/*########################################################################## - CDROM Drive Low Level I/O Functions - ########################################################################## -*/ -/* Macros for the drive hardware interface handshake, these macros use - busy waiting */ -/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/ -# define OP_OK op_ok() -static void op_ok(void) -{ - aztTimeOutCount = 0; - do { - aztIndatum = inb(DATA_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_TIMEOUT) { - printk("aztcd: Error Wait OP_OK\n"); - break; - } - } while (aztIndatum != AFL_OP_OK); -} - -/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/ -#if 0 -# define PA_OK pa_ok() -static void pa_ok(void) -{ - aztTimeOutCount = 0; - do { - aztIndatum = inb(DATA_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_TIMEOUT) { - printk("aztcd: Error Wait PA_OK\n"); - break; - } - } while (aztIndatum != AFL_PA_OK); -} -#endif - -/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/ -# define STEN_LOW sten_low() -static void sten_low(void) -{ - aztTimeOutCount = 0; - do { - aztIndatum = inb(STATUS_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_TIMEOUT) { - if (azt_init_end) - printk - ("aztcd: Error Wait STEN_LOW commands:%x\n", - aztCmd); - break; - } - } while (aztIndatum & AFL_STATUS); -} - -/* Wait for DTEN=Low = handshake signal 'Data available'*/ -# define DTEN_LOW dten_low() -static void dten_low(void) -{ - aztTimeOutCount = 0; - do { - aztIndatum = inb(STATUS_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_TIMEOUT) { - printk("aztcd: Error Wait DTEN_OK\n"); - break; - } - } while (aztIndatum & AFL_DATA); -} - -/* - * Macro for timer wait on STEN=Low, should only be used for 'slow' commands; - * may cause kernel panic when used in the wrong place -*/ -#define STEN_LOW_WAIT statusAzt() -static void statusAzt(void) -{ - AztTimeout = AZT_STATUS_DELAY; - SET_TIMER(aztStatTimer, HZ / 100); - sleep_on(&azt_waitq); - if (AztTimeout <= 0) - printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n", - aztCmd); - return; -} - -static void aztStatTimer(void) -{ - if (!(inb(STATUS_PORT) & AFL_STATUS)) { - wake_up(&azt_waitq); - return; - } - AztTimeout--; - if (AztTimeout <= 0) { - wake_up(&azt_waitq); - printk("aztcd: Error aztStatTimer: Timeout\n"); - return; - } - SET_TIMER(aztStatTimer, HZ / 100); -} - -/*########################################################################## - CDROM Drive Command Functions - ########################################################################## -*/ -/* - * Send a single command, return -1 on error, else 0 -*/ -static int aztSendCmd(int cmd) -{ - unsigned char data; - int retry; - -#ifdef AZT_DEBUG - printk("aztcd: Executing command %x\n", cmd); -#endif - - if ((azt_port == 0x1f0) || (azt_port == 0x170)) - SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */ - - aztCmd = cmd; - outb(POLLED, MODE_PORT); - do { - if (inb(STATUS_PORT) & AFL_STATUS) - break; - inb(DATA_PORT); /* if status left from last command, read and */ - } while (1); /* discard it */ - do { - if (inb(STATUS_PORT) & AFL_DATA) - break; - inb(DATA_PORT); /* if data left from last command, read and */ - } while (1); /* discard it */ - for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) { - outb((unsigned char) cmd, CMD_PORT); - STEN_LOW; - data = inb(DATA_PORT); - if (data == AFL_OP_OK) { - return 0; - } /*OP_OK? */ - if (data == AFL_OP_ERR) { - STEN_LOW; - data = inb(DATA_PORT); - printk - ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n", - cmd, data); - } - } - if (retry >= AZT_RETRY_ATTEMPTS) { - printk("### Error 2 aztcd: aztSendCmd %x \n", cmd); - azt_error = 0xA5; - } - RETURNM("aztSendCmd", -1); -} - -/* - * Send a play or read command to the drive, return -1 on error, else 0 -*/ -static int sendAztCmd(int cmd, struct azt_Play_msf *params) -{ - unsigned char data; - int retry; - -#ifdef AZT_DEBUG - printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n", - params->start.min, params->start.sec, params->start.frame, - params->end.min, params->end.sec, params->end.frame); -#endif - for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) { - aztSendCmd(cmd); - outb(params->start.min, CMD_PORT); - outb(params->start.sec, CMD_PORT); - outb(params->start.frame, CMD_PORT); - outb(params->end.min, CMD_PORT); - outb(params->end.sec, CMD_PORT); - outb(params->end.frame, CMD_PORT); - STEN_LOW; - data = inb(DATA_PORT); - if (data == AFL_PA_OK) { - return 0; - } /*PA_OK ? */ - if (data == AFL_PA_ERR) { - STEN_LOW; - data = inb(DATA_PORT); - printk - ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n", - cmd, data); - } - } - if (retry >= AZT_RETRY_ATTEMPTS) { - printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd); - azt_error = 0xA5; - } - RETURNM("sendAztCmd", -1); -} - -/* - * Send a seek command to the drive, return -1 on error, else 0 -*/ -static int aztSeek(struct azt_Play_msf *params) -{ - unsigned char data; - int retry; - -#ifdef AZT_DEBUG - printk("aztcd: aztSeek %02x:%02x:%02x\n", - params->start.min, params->start.sec, params->start.frame); -#endif - for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) { - aztSendCmd(ACMD_SEEK); - outb(params->start.min, CMD_PORT); - outb(params->start.sec, CMD_PORT); - outb(params->start.frame, CMD_PORT); - STEN_LOW; - data = inb(DATA_PORT); - if (data == AFL_PA_OK) { - return 0; - } /*PA_OK ? */ - if (data == AFL_PA_ERR) { - STEN_LOW; - data = inb(DATA_PORT); - printk("### Error 1 aztcd: aztSeek\n"); - } - } - if (retry >= AZT_RETRY_ATTEMPTS) { - printk("### Error 2 aztcd: aztSeek\n "); - azt_error = 0xA5; - } - RETURNM("aztSeek", -1); -} - -/* Send a Set Disk Type command - does not seem to work with Aztech drives, behavior is completely indepen- - dent on which mode is set ??? -*/ -static int aztSetDiskType(int type) -{ - unsigned char data; - int retry; - -#ifdef AZT_DEBUG - printk("aztcd: set disk type command: type= %i\n", type); -#endif - for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) { - aztSendCmd(ACMD_SET_DISK_TYPE); - outb(type, CMD_PORT); - STEN_LOW; - data = inb(DATA_PORT); - if (data == AFL_PA_OK) { /*PA_OK ? */ - azt_read_mode = type; - return 0; - } - if (data == AFL_PA_ERR) { - STEN_LOW; - data = inb(DATA_PORT); - printk - ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n", - type, data); - } - } - if (retry >= AZT_RETRY_ATTEMPTS) { - printk("### Error 2 aztcd: aztSetDiskType %x\n ", type); - azt_error = 0xA5; - } - RETURNM("aztSetDiskType", -1); -} - - -/* used in azt_poll to poll the status, expects another program to issue a - * ACMD_GET_STATUS directly before - */ -static int aztStatus(void) -{ - int st; -/* int i; - - i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ??? - if (!i) -*/ STEN_LOW; - if (aztTimeOutCount < AZT_TIMEOUT) { - st = inb(DATA_PORT) & 0xFF; - return st; - } else - RETURNM("aztStatus", -1); -} - -/* - * Get the drive status - */ -static int getAztStatus(void) -{ - int st; - - if (aztSendCmd(ACMD_GET_STATUS)) - RETURNM("getAztStatus 1", -1); - STEN_LOW; - st = inb(DATA_PORT) & 0xFF; -#ifdef AZT_DEBUG - printk("aztcd: Status = %x\n", st); -#endif - if ((st == 0xFF) || (st & AST_CMD_CHECK)) { - printk - ("aztcd: AST_CMD_CHECK error or no status available\n"); - return -1; - } - - if (((st & AST_MODE_BITS) != AST_BUSY) - && (aztAudioStatus == CDROM_AUDIO_PLAY)) - /* XXX might be an error? look at q-channel? */ - aztAudioStatus = CDROM_AUDIO_COMPLETED; - - if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - aztAudioStatus = CDROM_AUDIO_NO_STATUS; - } - return st; -} - - -/* - * Send a 'Play' command and get the status. Use only from the top half. - */ -static int aztPlay(struct azt_Play_msf *arg) -{ - if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) - RETURNM("aztPlay", -1); - return 0; -} - -/* - * Subroutines to automatically close the door (tray) and - * lock it closed when the cd is mounted. Leave the tray - * locking as an option - */ -static void aztCloseDoor(void) -{ - aztSendCmd(ACMD_CLOSE); - STEN_LOW; - return; -} - -static void aztLockDoor(void) -{ -#if AZT_ALLOW_TRAY_LOCK - aztSendCmd(ACMD_LOCK); - STEN_LOW; -#endif - return; -} - -static void aztUnlockDoor(void) -{ -#if AZT_ALLOW_TRAY_LOCK - aztSendCmd(ACMD_UNLOCK); - STEN_LOW; -#endif - return; -} - -/* - * Read a value from the drive. Should return quickly, so a busy wait - * is used to avoid excessive rescheduling. The read command itself must - * be issued with aztSendCmd() directly before - */ -static int aztGetValue(unsigned char *result) -{ - int s; - - STEN_LOW; - if (aztTimeOutCount >= AZT_TIMEOUT) { - printk("aztcd: aztGetValue timeout\n"); - return -1; - } - s = inb(DATA_PORT) & 0xFF; - *result = (unsigned char) s; - return 0; -} - -/* - * Read the current Q-channel info. Also used for reading the - * table of contents. - */ -static int aztGetQChannelInfo(struct azt_Toc *qp) -{ - unsigned char notUsed; - int st; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies); -#endif - if ((st = getAztStatus()) == -1) - RETURNM("aztGetQChannelInfo 1", -1); - if (aztSendCmd(ACMD_GET_Q_CHANNEL)) - RETURNM("aztGetQChannelInfo 2", -1); - /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */ - if (aztGetValue(¬Used)) - RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */ - if ((st & AST_MODE_BITS) == AST_INITIAL) { - qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */ - qp->track = 0; /* only one byte with Aztech drives */ - qp->pointIndex = 0; - qp->trackTime.min = 0; - qp->trackTime.sec = 0; - qp->trackTime.frame = 0; - qp->diskTime.min = 0; - qp->diskTime.sec = 0; - qp->diskTime.frame = 0; - return 0; - } else { - if (aztGetValue(&qp->ctrl_addr) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->track) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->pointIndex) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->trackTime.min) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->trackTime.sec) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->trackTime.frame) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(¬Used) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->diskTime.min) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->diskTime.sec) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - if (aztGetValue(&qp->diskTime.frame) < 0) - RETURNM("aztGetQChannelInfo 4", -1); - } -#ifdef AZT_DEBUG - printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies); -#endif - return 0; -} - -/* - * Read the table of contents (TOC) and TOC header if necessary - */ -static int aztUpdateToc(void) -{ - int st; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies); -#endif - if (aztTocUpToDate) - return 0; - - if (aztGetDiskInfo() < 0) - return -EIO; - - if (aztGetToc(0) < 0) - return -EIO; - - /*audio disk detection - with my Aztech drive there is no audio status bit, so I use the copy - protection bit of the first track. If this track is copy protected - (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */ - if (!(Toc[DiskInfo.first].ctrl_addr & 0x40)) - DiskInfo.audio = 1; - else - DiskInfo.audio = 0; - - /* XA detection */ - if (!DiskInfo.audio) { - azt_Play.start.min = 0; /*XA detection only seems to work */ - azt_Play.start.sec = 2; /*when we play a track */ - azt_Play.start.frame = 0; - azt_Play.end.min = 0; - azt_Play.end.sec = 0; - azt_Play.end.frame = 1; - if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) - return -1; - DTEN_LOW; - for (st = 0; st < CD_FRAMESIZE; st++) - inb(DATA_PORT); - } - DiskInfo.xa = getAztStatus() & AST_MODE; - if (DiskInfo.xa) { - printk - ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n"); - } - - /*multisession detection - support for multisession CDs is done automatically with Aztech drives, - we don't have to take care about TOC redirection; if we want the isofs - to take care about redirection, we have to set AZT_MULTISESSION to 1 */ - DiskInfo.multi = 0; -#if AZT_MULTISESSION - if (DiskInfo.xa) { - aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */ - } -#endif - if (DiskInfo.multi) { - DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min; - DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec; - DiskInfo.lastSession.frame = - Toc[DiskInfo.next].diskTime.frame; - printk("aztcd: Multisession support experimental\n"); - } else { - DiskInfo.lastSession.min = - Toc[DiskInfo.first].diskTime.min; - DiskInfo.lastSession.sec = - Toc[DiskInfo.first].diskTime.sec; - DiskInfo.lastSession.frame = - Toc[DiskInfo.first].diskTime.frame; - } - - aztTocUpToDate = 1; -#ifdef AZT_DEBUG - printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies); -#endif - return 0; -} - - -/* Read the table of contents header, i.e. no. of tracks and start of first - * track - */ -static int aztGetDiskInfo(void) -{ - int limit; - unsigned char test; - struct azt_Toc qInfo; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies); -#endif - if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) - RETURNM("aztGetDiskInfo 1", -1); - STEN_LOW_WAIT; - test = 0; - for (limit = 300; limit > 0; limit--) { - if (aztGetQChannelInfo(&qInfo) < 0) - RETURNM("aztGetDiskInfo 2", -1); - if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */ - DiskInfo.first = qInfo.diskTime.min; - DiskInfo.first = azt_bcd2bin(DiskInfo.first); - test = test | 0x01; - } - if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */ - DiskInfo.last = qInfo.diskTime.min; - DiskInfo.last = azt_bcd2bin(DiskInfo.last); - test = test | 0x02; - } - if (qInfo.pointIndex == 0xA2) { /*DiskLength */ - DiskInfo.diskLength.min = qInfo.diskTime.min; - DiskInfo.diskLength.sec = qInfo.diskTime.sec; - DiskInfo.diskLength.frame = qInfo.diskTime.frame; - test = test | 0x04; - } - if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */ - DiskInfo.firstTrack.min = qInfo.diskTime.min; - DiskInfo.firstTrack.sec = qInfo.diskTime.sec; - DiskInfo.firstTrack.frame = qInfo.diskTime.frame; - test = test | 0x08; - } - if (test == 0x0F) - break; - } -#ifdef AZT_DEBUG - printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies); - printk - ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n", - DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min, - DiskInfo.diskLength.sec, DiskInfo.diskLength.frame, - DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec, - DiskInfo.firstTrack.frame); -#endif - if (test != 0x0F) - return -1; - return 0; -} - -#if AZT_MULTISESSION -/* - * Get Multisession Disk Info - */ -static int aztGetMultiDiskInfo(void) -{ - int limit, k = 5; - unsigned char test; - struct azt_Toc qInfo; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztGetMultiDiskInfo\n"); -#endif - - do { - azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min; - azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec; - azt_Play.start.frame = - Toc[DiskInfo.last + 1].diskTime.frame; - test = 0; - - for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */ - if (aztSeek(&azt_Play)) - RETURNM("aztGetMultiDiskInfo 1", -1); - if (aztGetQChannelInfo(&qInfo) < 0) - RETURNM("aztGetMultiDiskInfo 2", -1); - if ((qInfo.track == 0) && (qInfo.pointIndex)) - break; /*LeadIn found */ - if ((azt_Play.start.sec += 10) > 59) { - azt_Play.start.sec = 0; - azt_Play.start.min++; - } - } - if (!limit) - break; /*Check, if a leadin track was found, if not we're - at the end of the disk */ -#ifdef AZT_DEBUG_MULTISESSION - printk("leadin found track %d pointIndex %x limit %d\n", - qInfo.track, qInfo.pointIndex, limit); -#endif - for (limit = 300; limit > 0; limit--) { - if (++azt_Play.start.frame > 74) { - azt_Play.start.frame = 0; - if (azt_Play.start.sec > 59) { - azt_Play.start.sec = 0; - azt_Play.start.min++; - } - } - if (aztSeek(&azt_Play)) - RETURNM("aztGetMultiDiskInfo 3", -1); - if (aztGetQChannelInfo(&qInfo) < 0) - RETURNM("aztGetMultiDiskInfo 4", -1); - if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */ - DiskInfo.next = qInfo.diskTime.min; - DiskInfo.next = azt_bcd2bin(DiskInfo.next); - test = test | 0x01; - } - if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */ - DiskInfo.last = qInfo.diskTime.min; - DiskInfo.last = azt_bcd2bin(DiskInfo.last); - test = test | 0x02; - } - if (qInfo.pointIndex == 0xA2) { /*DiskLength */ - DiskInfo.diskLength.min = - qInfo.diskTime.min; - DiskInfo.diskLength.sec = - qInfo.diskTime.sec; - DiskInfo.diskLength.frame = - qInfo.diskTime.frame; - test = test | 0x04; - } - if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */ - DiskInfo.nextSession.min = - qInfo.diskTime.min; - DiskInfo.nextSession.sec = - qInfo.diskTime.sec; - DiskInfo.nextSession.frame = - qInfo.diskTime.frame; - test = test | 0x08; - } - if (test == 0x0F) - break; - } -#ifdef AZT_DEBUG_MULTISESSION - printk - ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n", - DiskInfo.first, DiskInfo.next, DiskInfo.last, - DiskInfo.diskLength.min, DiskInfo.diskLength.sec, - DiskInfo.diskLength.frame, DiskInfo.firstTrack.min, - DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame, - DiskInfo.nextSession.min, DiskInfo.nextSession.sec, - DiskInfo.nextSession.frame); -#endif - if (test != 0x0F) - break; - else - DiskInfo.multi = 1; /*found TOC of more than one session */ - aztGetToc(1); - } while (--k); - -#ifdef AZT_DEBUG - printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies); -#endif - return 0; -} -#endif - -/* - * Read the table of contents (TOC) - */ -static int aztGetToc(int multi) -{ - int i, px; - int limit; - struct azt_Toc qInfo; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztGetToc Time:%li\n", jiffies); -#endif - if (!multi) { - for (i = 0; i < MAX_TRACKS; i++) - Toc[i].pointIndex = 0; - i = DiskInfo.last + 3; - } else { - for (i = DiskInfo.next; i < MAX_TRACKS; i++) - Toc[i].pointIndex = 0; - i = DiskInfo.last + 4 - DiskInfo.next; - } - -/*Is there a good reason to stop motor before TOC read? - if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1); - STEN_LOW_WAIT; -*/ - - if (!multi) { - azt_mode = 0x05; - if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) - RETURNM("aztGetToc 2", -1); - STEN_LOW_WAIT; - } - for (limit = 300; limit > 0; limit--) { - if (multi) { - if (++azt_Play.start.sec > 59) { - azt_Play.start.sec = 0; - azt_Play.start.min++; - } - if (aztSeek(&azt_Play)) - RETURNM("aztGetToc 3", -1); - } - if (aztGetQChannelInfo(&qInfo) < 0) - break; - - px = azt_bcd2bin(qInfo.pointIndex); - - if (px > 0 && px < MAX_TRACKS && qInfo.track == 0) - if (Toc[px].pointIndex == 0) { - Toc[px] = qInfo; - i--; - } - - if (i <= 0) - break; - } - - Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength; - Toc[DiskInfo.last].trackTime = DiskInfo.diskLength; - -#ifdef AZT_DEBUG_MULTISESSION - printk("aztcd: exiting aztGetToc\n"); - for (i = 1; i <= DiskInfo.last + 1; i++) - printk - ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n", - i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex, - Toc[i].trackTime.min, Toc[i].trackTime.sec, - Toc[i].trackTime.frame, Toc[i].diskTime.min, - Toc[i].diskTime.sec, Toc[i].diskTime.frame); - for (i = 100; i < 103; i++) - printk - ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n", - i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex, - Toc[i].trackTime.min, Toc[i].trackTime.sec, - Toc[i].trackTime.frame, Toc[i].diskTime.min, - Toc[i].diskTime.sec, Toc[i].diskTime.frame); -#endif - - return limit > 0 ? 0 : -1; -} - - -/*########################################################################## - Kernel Interface Functions - ########################################################################## -*/ - -#ifndef MODULE -static int __init aztcd_setup(char *str) -{ - int ints[4]; - - (void) get_options(str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) - azt_port = ints[1]; - if (ints[1] > 1) - azt_cont = ints[2]; - return 1; -} - -__setup("aztcd=", aztcd_setup); - -#endif /* !MODULE */ - -/* - * Checking if the media has been changed -*/ -static int check_aztcd_media_change(struct gendisk *disk) -{ - if (aztDiskChanged) { /* disk changed */ - aztDiskChanged = 0; - return 1; - } else - return 0; /* no change */ -} - -/* - * Kernel IO-controls -*/ -static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg) -{ - int i; - struct azt_Toc qInfo; - struct cdrom_ti ti; - struct cdrom_tochdr tocHdr; - struct cdrom_msf msf; - struct cdrom_tocentry entry; - struct azt_Toc *tocPtr; - struct cdrom_subchnl subchnl; - struct cdrom_volctrl volctrl; - void __user *argp = (void __user *)arg; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n", - cmd, jiffies); - printk("aztcd Status %x\n", getAztStatus()); -#endif - if (!ip) - RETURNM("aztcd_ioctl 1", -EINVAL); - if (getAztStatus() < 0) - RETURNM("aztcd_ioctl 2", -EIO); - if ((!aztTocUpToDate) || (aztDiskChanged)) { - if ((i = aztUpdateToc()) < 0) - RETURNM("aztcd_ioctl 3", i); /* error reading TOC */ - } - - switch (cmd) { - case CDROMSTART: /* Spin up the drive. Don't know, what to do, - at least close the tray */ -#if AZT_PRIVATE_IOCTLS - if (aztSendCmd(ACMD_CLOSE)) - RETURNM("aztcd_ioctl 4", -1); - STEN_LOW_WAIT; -#endif - break; - case CDROMSTOP: /* Spin down the drive */ - if (aztSendCmd(ACMD_STOP)) - RETURNM("aztcd_ioctl 5", -1); - STEN_LOW_WAIT; - /* should we do anything if it fails? */ - aztAudioStatus = CDROM_AUDIO_NO_STATUS; - break; - case CDROMPAUSE: /* Pause the drive */ - if (aztAudioStatus != CDROM_AUDIO_PLAY) - return -EINVAL; - - if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */ - aztAudioStatus = CDROM_AUDIO_NO_STATUS; - RETURNM("aztcd_ioctl 7", 0); - } - azt_Play.start = qInfo.diskTime; /* remember restart point */ - - if (aztSendCmd(ACMD_PAUSE)) - RETURNM("aztcd_ioctl 8", -1); - STEN_LOW_WAIT; - aztAudioStatus = CDROM_AUDIO_PAUSED; - break; - case CDROMRESUME: /* Play it again, Sam */ - if (aztAudioStatus != CDROM_AUDIO_PAUSED) - return -EINVAL; - /* restart the drive at the saved position. */ - i = aztPlay(&azt_Play); - if (i < 0) { - aztAudioStatus = CDROM_AUDIO_ERROR; - return -EIO; - } - aztAudioStatus = CDROM_AUDIO_PLAY; - break; - case CDROMMULTISESSION: /*multisession support -- experimental */ - { - struct cdrom_multisession ms; -#ifdef AZT_DEBUG - printk("aztcd ioctl MULTISESSION\n"); -#endif - if (copy_from_user(&ms, argp, - sizeof(struct cdrom_multisession))) - return -EFAULT; - if (ms.addr_format == CDROM_MSF) { - ms.addr.msf.minute = - azt_bcd2bin(DiskInfo.lastSession.min); - ms.addr.msf.second = - azt_bcd2bin(DiskInfo.lastSession.sec); - ms.addr.msf.frame = - azt_bcd2bin(DiskInfo.lastSession. - frame); - } else if (ms.addr_format == CDROM_LBA) - ms.addr.lba = - azt_msf2hsg(&DiskInfo.lastSession); - else - return -EINVAL; - ms.xa_flag = DiskInfo.xa; - if (copy_to_user(argp, &ms, - sizeof(struct cdrom_multisession))) - return -EFAULT; -#ifdef AZT_DEBUG - if (ms.addr_format == CDROM_MSF) - printk - ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n", - ms.xa_flag, ms.addr.msf.minute, - ms.addr.msf.second, ms.addr.msf.frame, - DiskInfo.lastSession.min, - DiskInfo.lastSession.sec, - DiskInfo.lastSession.frame); - else - printk - ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n", - ms.xa_flag, ms.addr.lba, - DiskInfo.lastSession.min, - DiskInfo.lastSession.sec, - DiskInfo.lastSession.frame); -#endif - return 0; - } - case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ - if (copy_from_user(&ti, argp, sizeof ti)) - return -EFAULT; - if (ti.cdti_trk0 < DiskInfo.first - || ti.cdti_trk0 > DiskInfo.last - || ti.cdti_trk1 < ti.cdti_trk0) { - return -EINVAL; - } - if (ti.cdti_trk1 > DiskInfo.last) - ti.cdti_trk1 = DiskInfo.last; - azt_Play.start = Toc[ti.cdti_trk0].diskTime; - azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime; -#ifdef AZT_DEBUG - printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n", - azt_Play.start.min, azt_Play.start.sec, - azt_Play.start.frame, azt_Play.end.min, - azt_Play.end.sec, azt_Play.end.frame); -#endif - i = aztPlay(&azt_Play); - if (i < 0) { - aztAudioStatus = CDROM_AUDIO_ERROR; - return -EIO; - } - aztAudioStatus = CDROM_AUDIO_PLAY; - break; - case CDROMPLAYMSF: /* Play starting at the given MSF address. */ -/* if (aztAudioStatus == CDROM_AUDIO_PLAY) - { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1); - STEN_LOW; - aztAudioStatus = CDROM_AUDIO_NO_STATUS; - } -*/ - if (copy_from_user(&msf, argp, sizeof msf)) - return -EFAULT; - /* convert to bcd */ - azt_bin2bcd(&msf.cdmsf_min0); - azt_bin2bcd(&msf.cdmsf_sec0); - azt_bin2bcd(&msf.cdmsf_frame0); - azt_bin2bcd(&msf.cdmsf_min1); - azt_bin2bcd(&msf.cdmsf_sec1); - azt_bin2bcd(&msf.cdmsf_frame1); - azt_Play.start.min = msf.cdmsf_min0; - azt_Play.start.sec = msf.cdmsf_sec0; - azt_Play.start.frame = msf.cdmsf_frame0; - azt_Play.end.min = msf.cdmsf_min1; - azt_Play.end.sec = msf.cdmsf_sec1; - azt_Play.end.frame = msf.cdmsf_frame1; -#ifdef AZT_DEBUG - printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n", - azt_Play.start.min, azt_Play.start.sec, - azt_Play.start.frame, azt_Play.end.min, - azt_Play.end.sec, azt_Play.end.frame); -#endif - i = aztPlay(&azt_Play); - if (i < 0) { - aztAudioStatus = CDROM_AUDIO_ERROR; - return -EIO; - } - aztAudioStatus = CDROM_AUDIO_PLAY; - break; - - case CDROMREADTOCHDR: /* Read the table of contents header */ - tocHdr.cdth_trk0 = DiskInfo.first; - tocHdr.cdth_trk1 = DiskInfo.last; - if (copy_to_user(argp, &tocHdr, sizeof tocHdr)) - return -EFAULT; - break; - case CDROMREADTOCENTRY: /* Read an entry in the table of contents */ - if (copy_from_user(&entry, argp, sizeof entry)) - return -EFAULT; - if ((!aztTocUpToDate) || aztDiskChanged) - aztUpdateToc(); - if (entry.cdte_track == CDROM_LEADOUT) - tocPtr = &Toc[DiskInfo.last + 1]; - else if (entry.cdte_track > DiskInfo.last - || entry.cdte_track < DiskInfo.first) { - return -EINVAL; - } else - tocPtr = &Toc[entry.cdte_track]; - entry.cdte_adr = tocPtr->ctrl_addr; - entry.cdte_ctrl = tocPtr->ctrl_addr >> 4; - if (entry.cdte_format == CDROM_LBA) - entry.cdte_addr.lba = - azt_msf2hsg(&tocPtr->diskTime); - else if (entry.cdte_format == CDROM_MSF) { - entry.cdte_addr.msf.minute = - azt_bcd2bin(tocPtr->diskTime.min); - entry.cdte_addr.msf.second = - azt_bcd2bin(tocPtr->diskTime.sec); - entry.cdte_addr.msf.frame = - azt_bcd2bin(tocPtr->diskTime.frame); - } else { - return -EINVAL; - } - if (copy_to_user(argp, &entry, sizeof entry)) - return -EFAULT; - break; - case CDROMSUBCHNL: /* Get subchannel info */ - if (copy_from_user - (&subchnl, argp, sizeof(struct cdrom_subchnl))) - return -EFAULT; - if (aztGetQChannelInfo(&qInfo) < 0) { -#ifdef AZT_DEBUG - printk - ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n", - cmd); -#endif - return -EIO; - } - subchnl.cdsc_audiostatus = aztAudioStatus; - subchnl.cdsc_adr = qInfo.ctrl_addr; - subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4; - subchnl.cdsc_trk = azt_bcd2bin(qInfo.track); - subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex); - if (subchnl.cdsc_format == CDROM_LBA) { - subchnl.cdsc_absaddr.lba = - azt_msf2hsg(&qInfo.diskTime); - subchnl.cdsc_reladdr.lba = - azt_msf2hsg(&qInfo.trackTime); - } else { /*default */ - subchnl.cdsc_format = CDROM_MSF; - subchnl.cdsc_absaddr.msf.minute = - azt_bcd2bin(qInfo.diskTime.min); - subchnl.cdsc_absaddr.msf.second = - azt_bcd2bin(qInfo.diskTime.sec); - subchnl.cdsc_absaddr.msf.frame = - azt_bcd2bin(qInfo.diskTime.frame); - subchnl.cdsc_reladdr.msf.minute = - azt_bcd2bin(qInfo.trackTime.min); - subchnl.cdsc_reladdr.msf.second = - azt_bcd2bin(qInfo.trackTime.sec); - subchnl.cdsc_reladdr.msf.frame = - azt_bcd2bin(qInfo.trackTime.frame); - } - if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl))) - return -EFAULT; - break; - case CDROMVOLCTRL: /* Volume control - * With my Aztech CD268-01A volume control does not work, I can only - turn the channels on (any value !=0) or off (value==0). Maybe it - works better with your drive */ - if (copy_from_user(&volctrl, argp, sizeof(volctrl))) - return -EFAULT; - azt_Play.start.min = 0x21; - azt_Play.start.sec = 0x84; - azt_Play.start.frame = volctrl.channel0; - azt_Play.end.min = volctrl.channel1; - azt_Play.end.sec = volctrl.channel2; - azt_Play.end.frame = volctrl.channel3; - sendAztCmd(ACMD_SET_VOLUME, &azt_Play); - STEN_LOW_WAIT; - break; - case CDROMEJECT: - aztUnlockDoor(); /* Assume user knows what they're doing */ - /* all drives can at least stop! */ - if (aztAudioStatus == CDROM_AUDIO_PLAY) { - if (aztSendCmd(ACMD_STOP)) - RETURNM("azt_ioctl 10", -1); - STEN_LOW_WAIT; - } - if (aztSendCmd(ACMD_EJECT)) - RETURNM("azt_ioctl 11", -1); - STEN_LOW_WAIT; - aztAudioStatus = CDROM_AUDIO_NO_STATUS; - break; - case CDROMEJECT_SW: - azt_auto_eject = (char) arg; - break; - case CDROMRESET: - outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */ - STEN_LOW; - if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */ - printk - ("aztcd: AZTECH CD-ROM drive does not respond\n"); - } - break; -/*Take care, the following code is not compatible with other CD-ROM drivers, - use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h, - if you do not want to use it! -*/ -#if AZT_PRIVATE_IOCTLS - case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */ - case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */ - { - if (copy_from_user(&msf, argp, sizeof msf)) - return -EFAULT; - /* convert to bcd */ - azt_bin2bcd(&msf.cdmsf_min0); - azt_bin2bcd(&msf.cdmsf_sec0); - azt_bin2bcd(&msf.cdmsf_frame0); - msf.cdmsf_min1 = 0; - msf.cdmsf_sec1 = 0; - msf.cdmsf_frame1 = 1; /*read only one frame */ - azt_Play.start.min = msf.cdmsf_min0; - azt_Play.start.sec = msf.cdmsf_sec0; - azt_Play.start.frame = msf.cdmsf_frame0; - azt_Play.end.min = msf.cdmsf_min1; - azt_Play.end.sec = msf.cdmsf_sec1; - azt_Play.end.frame = msf.cdmsf_frame1; - if (cmd == CDROMREADRAW) { - if (DiskInfo.xa) { - return -1; /*XA Disks can't be read raw */ - } else { - if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) - return -1; - DTEN_LOW; - insb(DATA_PORT, buf, CD_FRAMESIZE_RAW); - if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW)) - return -EFAULT; - } - } else - /*CDROMREADCOOKED*/ { - if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) - return -1; - DTEN_LOW; - insb(DATA_PORT, buf, CD_FRAMESIZE); - if (copy_to_user(argp, &buf, CD_FRAMESIZE)) - return -EFAULT; - } - } - break; - case CDROMSEEK: /*seek msf address */ - if (copy_from_user(&msf, argp, sizeof msf)) - return -EFAULT; - /* convert to bcd */ - azt_bin2bcd(&msf.cdmsf_min0); - azt_bin2bcd(&msf.cdmsf_sec0); - azt_bin2bcd(&msf.cdmsf_frame0); - azt_Play.start.min = msf.cdmsf_min0; - azt_Play.start.sec = msf.cdmsf_sec0; - azt_Play.start.frame = msf.cdmsf_frame0; - if (aztSeek(&azt_Play)) - return -1; - break; -#endif /*end of incompatible code */ - case CDROMREADMODE1: /*set read data in mode 1 */ - return aztSetDiskType(AZT_MODE_1); - case CDROMREADMODE2: /*set read data in mode 2 */ - return aztSetDiskType(AZT_MODE_2); - default: - return -EINVAL; - } -#ifdef AZT_DEBUG - printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd, - jiffies); -#endif - return 0; -} - -/* - * Take care of the different block sizes between cdrom and Linux. - * When Linux gets variable block sizes this will probably go away. - */ -static void azt_transfer(void) -{ -#ifdef AZT_TEST - printk("aztcd: executing azt_transfer Time:%li\n", jiffies); -#endif - if (!current_valid()) - return; - - while (CURRENT->nr_sectors) { - int bn = CURRENT->sector / 4; - int i; - for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i); - if (i < AZT_BUF_SIZ) { - int offs = (i * 4 + (CURRENT->sector & 3)) * 512; - int nr_sectors = 4 - (CURRENT->sector & 3); - if (azt_buf_out != i) { - azt_buf_out = i; - if (azt_buf_bn[i] != bn) { - azt_buf_out = -1; - continue; - } - } - if (nr_sectors > CURRENT->nr_sectors) - nr_sectors = CURRENT->nr_sectors; - memcpy(CURRENT->buffer, azt_buf + offs, - nr_sectors * 512); - CURRENT->nr_sectors -= nr_sectors; - CURRENT->sector += nr_sectors; - CURRENT->buffer += nr_sectors * 512; - } else { - azt_buf_out = -1; - break; - } - } -} - -static void do_aztcd_request(request_queue_t * q) -{ -#ifdef AZT_TEST - printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector, - CURRENT->nr_sectors, jiffies); -#endif - if (DiskInfo.audio) { - printk("aztcd: Error, tried to mount an Audio CD\n"); - end_request(CURRENT, 0); - return; - } - azt_transfer_is_active = 1; - while (current_valid()) { - azt_transfer(); - if (CURRENT->nr_sectors == 0) { - end_request(CURRENT, 1); - } else { - azt_buf_out = -1; /* Want to read a block not in buffer */ - if (azt_state == AZT_S_IDLE) { - if ((!aztTocUpToDate) || aztDiskChanged) { - if (aztUpdateToc() < 0) { - while (current_valid()) - end_request(CURRENT, 0); - break; - } - } - azt_state = AZT_S_START; - AztTries = 5; - SET_TIMER(azt_poll, HZ / 100); - } - break; - } - } - azt_transfer_is_active = 0; -#ifdef AZT_TEST2 - printk - ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", - azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]); - printk(" do_aztcd_request ends Time:%li\n", jiffies); -#endif -} - - -static void azt_invalidate_buffers(void) -{ - int i; - -#ifdef AZT_DEBUG - printk("aztcd: executing azt_invalidate_buffers\n"); -#endif - for (i = 0; i < AZT_BUF_SIZ; ++i) - azt_buf_bn[i] = -1; - azt_buf_out = -1; -} - -/* - * Open the device special file. Check that a disk is in. - */ -static int aztcd_open(struct inode *ip, struct file *fp) -{ - int st; - -#ifdef AZT_DEBUG - printk("aztcd: starting aztcd_open\n"); -#endif - - if (aztPresent == 0) - return -ENXIO; /* no hardware */ - - if (!azt_open_count && azt_state == AZT_S_IDLE) { - azt_invalidate_buffers(); - - st = getAztStatus(); /* check drive status */ - if (st == -1) - goto err_out; /* drive doesn't respond */ - - if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */ - printk("aztcd: Door Open?\n"); - aztCloseDoor(); - st = getAztStatus(); - } - - if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */ - printk - ("aztcd: Disk Changed or No Disk in Drive?\n"); - aztTocUpToDate = 0; - } - if (aztUpdateToc()) - goto err_out; - - } - ++azt_open_count; - aztLockDoor(); - -#ifdef AZT_DEBUG - printk("aztcd: exiting aztcd_open\n"); -#endif - return 0; - - err_out: - return -EIO; -} - - -/* - * On close, we flush all azt blocks from the buffer cache. - */ -static int aztcd_release(struct inode *inode, struct file *file) -{ -#ifdef AZT_DEBUG - printk("aztcd: executing aztcd_release\n"); - printk("inode: %p, device: %s file: %p\n", inode, - inode->i_bdev->bd_disk->disk_name, file); -#endif - if (!--azt_open_count) { - azt_invalidate_buffers(); - aztUnlockDoor(); - if (azt_auto_eject) - aztSendCmd(ACMD_EJECT); - CLEAR_TIMER; - } - return 0; -} - -static struct gendisk *azt_disk; - -/* - * Test for presence of drive and initialize it. Called at boot time. - */ - -static int __init aztcd_init(void) -{ - long int count, max_count; - unsigned char result[50]; - int st; - void* status = NULL; - int i = 0; - int ret = 0; - - if (azt_port == 0) { - printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization"); - return -EIO; - } - - printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM " - "CD-ROM Driver\n"); - printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n"); - if (azt_port == -1) { - printk - ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n", - AZT_VERSION); - } else - printk - ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n", - AZT_VERSION, azt_port); - printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/" - "Documentation/cdrom/aztcd\n"); - - -#ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */ - if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) { - printk - ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n", - AZT_SW32_BASE_ADDR, AZT_SW32_INIT, - AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG); - return -EIO; - } else { - printk(KERN_INFO - "aztcd: Soundwave32 card detected at %x Version %x\n", - AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG)); - outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG); - for (count = 0; count < 10000; count++); /*delay a bit */ - } -#endif - - /* check for presence of drive */ - - if (azt_port == -1) { /* autoprobing for proprietary interface */ - for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) { - azt_port = azt_port_auto[i]; - printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x" - "\n", azt_port); - /*proprietary interfaces need 4 bytes */ - if (!request_region(azt_port, 4, "aztcd")) { - continue; - } - outb(POLLED, MODE_PORT); - inb(CMD_PORT); - inb(CMD_PORT); - outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */ - - aztTimeOutCount = 0; - do { - aztIndatum = inb(STATUS_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_FAST_TIMEOUT) - break; - } while (aztIndatum & AFL_STATUS); - if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */ - break; - } - else { /* Drive not found on this port - try next one */ - release_region(azt_port, 4); - } - } - if ((i == 16) || (azt_port_auto[i] == 0)) { - printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n"); - return -EIO; - } - } else { /* no autoprobing */ - if ((azt_port == 0x1f0) || (azt_port == 0x170)) - status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */ - else - status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */ - if (!status) { - printk(KERN_WARNING "aztcd: conflict, I/O port (%X) " - "already used\n", azt_port); - return -EIO; - } - - if ((azt_port == 0x1f0) || (azt_port == 0x170)) - SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */ - - outb(POLLED, MODE_PORT); - inb(CMD_PORT); - inb(CMD_PORT); - outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */ - - aztTimeOutCount = 0; - do { - aztIndatum = inb(STATUS_PORT); - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_FAST_TIMEOUT) - break; - } while (aztIndatum & AFL_STATUS); - - if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */ -#ifndef MODULE - if (azt_cont != 0x79) { - printk(KERN_WARNING "aztcd: no AZTECH CD-ROM " - "drive found-Try boot parameter aztcd=" - ",0x79\n"); - ret = -EIO; - goto err_out; - } -#else - if (0) { - } -#endif - else { - printk(KERN_INFO "aztcd: drive reset - " - "please wait\n"); - for (count = 0; count < 50; count++) { - inb(STATUS_PORT); /*removing all data from earlier tries */ - inb(DATA_PORT); - } - outb(POLLED, MODE_PORT); - inb(CMD_PORT); - inb(CMD_PORT); - getAztStatus(); /*trap errors */ - outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */ - STEN_LOW; - if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */ - printk(KERN_WARNING "aztcd: no AZTECH " - "CD-ROM drive found\n"); - ret = -EIO; - goto err_out; - } - - for (count = 0; count < AZT_TIMEOUT; - count++) - barrier(); /* Stop gcc 2.96 being smart */ - /* use udelay(), damnit -- AV */ - - if ((st = getAztStatus()) == -1) { - printk(KERN_WARNING "aztcd: Drive Status" - " Error Status=%x\n", st); - ret = -EIO; - goto err_out; - } -#ifdef AZT_DEBUG - printk(KERN_DEBUG "aztcd: Status = %x\n", st); -#endif - outb(POLLED, MODE_PORT); - inb(CMD_PORT); - inb(CMD_PORT); - outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */ - STEN_LOW; - OP_OK; - } - } - } - - azt_init_end = 1; - STEN_LOW; - result[0] = inb(DATA_PORT); /*reading in a null byte??? */ - for (count = 1; count < 50; count++) { /*Reading version string */ - aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */ - do { - aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */ - aztTimeOutCount++; - if (aztTimeOutCount >= AZT_FAST_TIMEOUT) - break; - } while (aztIndatum & AFL_STATUS); - if (aztTimeOutCount >= AZT_FAST_TIMEOUT) - break; /*all chars read? */ - result[count] = inb(DATA_PORT); - } - if (count > 30) - max_count = 30; /*print max.30 chars of the version string */ - else - max_count = count; - printk(KERN_INFO "aztcd: FirmwareVersion="); - for (count = 1; count < max_count; count++) - printk("%c", result[count]); - printk("<<>> "); - - if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) { - printk("AZTECH drive detected\n"); - /*AZTECH*/} - else if ((result[2] == 'C') && (result[3] == 'D') - && (result[4] == 'D')) { - printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */ - } else if ((result[1] == 0x03) && (result[2] == '5')) { - printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */ - } else { /*OTHERS or none */ - printk("\nunknown drive or firmware version detected\n"); - printk - ("aztcd may not run stable, if you want to try anyhow,\n"); - printk("boot with: aztcd=,0x79\n"); - if ((azt_cont != 0x79)) { - printk("aztcd: FirmwareVersion="); - for (count = 1; count < 5; count++) - printk("%c", result[count]); - printk("<<>> "); - printk("Aborted\n"); - ret = -EIO; - goto err_out; - } - } - azt_disk = alloc_disk(1); - if (!azt_disk) - goto err_out; - - if (register_blkdev(MAJOR_NR, "aztcd")) { - ret = -EIO; - goto err_out2; - } - - azt_queue = blk_init_queue(do_aztcd_request, &aztSpin); - if (!azt_queue) { - ret = -ENOMEM; - goto err_out3; - } - - blk_queue_hardsect_size(azt_queue, 2048); - azt_disk->major = MAJOR_NR; - azt_disk->first_minor = 0; - azt_disk->fops = &azt_fops; - sprintf(azt_disk->disk_name, "aztcd"); - azt_disk->queue = azt_queue; - add_disk(azt_disk); - azt_invalidate_buffers(); - aztPresent = 1; - aztCloseDoor(); - return 0; -err_out3: - unregister_blkdev(MAJOR_NR, "aztcd"); -err_out2: - put_disk(azt_disk); -err_out: - if ((azt_port == 0x1f0) || (azt_port == 0x170)) { - SWITCH_IDE_MASTER; - release_region(azt_port, 8); /*IDE-interface */ - } else - release_region(azt_port, 4); /*proprietary interface */ - return ret; - -} - -static void __exit aztcd_exit(void) -{ - del_gendisk(azt_disk); - put_disk(azt_disk); - if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) { - printk("What's that: can't unregister aztcd\n"); - return; - } - blk_cleanup_queue(azt_queue); - if ((azt_port == 0x1f0) || (azt_port == 0x170)) { - SWITCH_IDE_MASTER; - release_region(azt_port, 8); /*IDE-interface */ - } else - release_region(azt_port, 4); /*proprietary interface */ - printk(KERN_INFO "aztcd module released.\n"); -} - -module_init(aztcd_init); -module_exit(aztcd_exit); - -/*########################################################################## - Aztcd State Machine: Controls Drive Operating State - ########################################################################## -*/ -static void azt_poll(void) -{ - int st = 0; - int loop_ctl = 1; - int skip = 0; - - if (azt_error) { - if (aztSendCmd(ACMD_GET_ERROR)) - RETURN("azt_poll 1"); - STEN_LOW; - azt_error = inb(DATA_PORT) & 0xFF; - printk("aztcd: I/O error 0x%02x\n", azt_error); - azt_invalidate_buffers(); -#ifdef WARN_IF_READ_FAILURE - if (AztTries == 5) - printk - ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", - azt_next_bn); -#endif - if (!AztTries--) { - printk - ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", - azt_next_bn); - if (azt_transfer_is_active) { - AztTries = 0; - loop_ctl = 0; - } - if (current_valid()) - end_request(CURRENT, 0); - AztTries = 5; - } - azt_error = 0; - azt_state = AZT_S_STOP; - } - - while (loop_ctl) { - loop_ctl = 0; /* each case must flip this back to 1 if we want - to come back up here */ - switch (azt_state) { - - case AZT_S_IDLE: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_IDLE\n"); - } -#endif - return; - - case AZT_S_START: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_START\n"); - } -#endif - if (aztSendCmd(ACMD_GET_STATUS)) - RETURN("azt_poll 2"); /*result will be checked by aztStatus() */ - azt_state = - azt_mode == 1 ? AZT_S_READ : AZT_S_MODE; - AztTimeout = 3000; - break; - - case AZT_S_MODE: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_MODE\n"); - } -#endif - if (!skip) { - if ((st = aztStatus()) != -1) { - if ((st & AST_DSK_CHG) - || (st & AST_NOT_READY)) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - azt_invalidate_buffers(); - end_request(CURRENT, 0); - printk - ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n"); - } - } else - break; - } - skip = 0; - - if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - printk - ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n"); - end_request(CURRENT, 0); - printk((st & AST_DOOR_OPEN) ? - "aztcd: door open\n" : - "aztcd: disk removed\n"); - if (azt_transfer_is_active) { - azt_state = AZT_S_START; - loop_ctl = 1; /* goto immediately */ - break; - } - azt_state = AZT_S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - -/* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3"); - outb(0x01, DATA_PORT); - PA_OK; - STEN_LOW; -*/ - if (aztSendCmd(ACMD_GET_STATUS)) - RETURN("azt_poll 4"); - STEN_LOW; - azt_mode = 1; - azt_state = AZT_S_READ; - AztTimeout = 3000; - - break; - - - case AZT_S_READ: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_READ\n"); - } -#endif - if (!skip) { - if ((st = aztStatus()) != -1) { - if ((st & AST_DSK_CHG) - || (st & AST_NOT_READY)) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - azt_invalidate_buffers(); - printk - ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n"); - end_request(CURRENT, 0); - } - } else - break; - } - - skip = 0; - if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - printk((st & AST_DOOR_OPEN) ? - "aztcd: door open\n" : - "aztcd: disk removed\n"); - if (azt_transfer_is_active) { - azt_state = AZT_S_START; - loop_ctl = 1; - break; - } - azt_state = AZT_S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - - if (current_valid()) { - struct azt_Play_msf msf; - int i; - azt_next_bn = CURRENT->sector / 4; - azt_hsg2msf(azt_next_bn, &msf.start); - i = 0; - /* find out in which track we are */ - while (azt_msf2hsg(&msf.start) > - azt_msf2hsg(&Toc[++i].trackTime)) { - }; - if (azt_msf2hsg(&msf.start) < - azt_msf2hsg(&Toc[i].trackTime) - - AZT_BUF_SIZ) { - azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */ - /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */ - } else /* don't read beyond end of track */ -#if AZT_MULTISESSION - { - azt_read_count = - (azt_msf2hsg(&Toc[i].trackTime) - / 4) * 4 - - azt_msf2hsg(&msf.start); - if (azt_read_count < 0) - azt_read_count = 0; - if (azt_read_count > AZT_BUF_SIZ) - azt_read_count = - AZT_BUF_SIZ; - printk - ("aztcd: warning - trying to read beyond end of track\n"); -/* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime)); -*/ } -#else - { - azt_read_count = AZT_BUF_SIZ; - } -#endif - msf.end.min = 0; - msf.end.sec = 0; - msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */ -#ifdef AZT_TEST3 - printk - ("---reading msf-address %x:%x:%x %x:%x:%x\n", - msf.start.min, msf.start.sec, - msf.start.frame, msf.end.min, - msf.end.sec, msf.end.frame); - printk - ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", - azt_next_bn, azt_buf_in, azt_buf_out, - azt_buf_bn[azt_buf_in]); -#endif - if (azt_read_mode == AZT_MODE_2) { - sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */ - } else { - sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */ - } - azt_state = AZT_S_DATA; - AztTimeout = READ_TIMEOUT; - } else { - azt_state = AZT_S_STOP; - loop_ctl = 1; - break; - } - - break; - - - case AZT_S_DATA: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_DATA\n"); - } -#endif - - st = inb(STATUS_PORT) & AFL_STATUSorDATA; - - switch (st) { - - case AFL_DATA: -#ifdef AZT_TEST3 - if (st != azt_st_old) { - azt_st_old = st; - printk("---AFL_DATA st:%x\n", st); - } -#endif - if (!AztTries--) { - printk - ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", - azt_next_bn); - if (azt_transfer_is_active) { - AztTries = 0; - break; - } - if (current_valid()) - end_request(CURRENT, 0); - AztTries = 5; - } - azt_state = AZT_S_START; - AztTimeout = READ_TIMEOUT; - loop_ctl = 1; - break; - - case AFL_STATUSorDATA: -#ifdef AZT_TEST3 - if (st != azt_st_old) { - azt_st_old = st; - printk - ("---AFL_STATUSorDATA st:%x\n", - st); - } -#endif - break; - - default: -#ifdef AZT_TEST3 - if (st != azt_st_old) { - azt_st_old = st; - printk("---default: st:%x\n", st); - } -#endif - AztTries = 5; - if (!current_valid() && azt_buf_in == azt_buf_out) { - azt_state = AZT_S_STOP; - loop_ctl = 1; - break; - } - if (azt_read_count <= 0) - printk - ("aztcd: warning - try to read 0 frames\n"); - while (azt_read_count) { /*??? fast read ahead loop */ - azt_buf_bn[azt_buf_in] = -1; - DTEN_LOW; /*??? unsolved problem, very - seldom we get timeouts - here, don't now the real - reason. With my drive this - sometimes also happens with - Aztech's original driver under - DOS. Is it a hardware bug? - I tried to recover from such - situations here. Zimmermann */ - if (aztTimeOutCount >= AZT_TIMEOUT) { - printk - ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", - azt_read_count, - CURRENT->nr_sectors, - azt_buf_in); - printk - ("azt_transfer_is_active:%x\n", - azt_transfer_is_active); - azt_read_count = 0; - azt_state = AZT_S_STOP; - loop_ctl = 1; - end_request(CURRENT, 1); /*should we have here (1) or (0)? */ - } else { - if (azt_read_mode == - AZT_MODE_2) { - insb(DATA_PORT, - azt_buf + - CD_FRAMESIZE_RAW - * azt_buf_in, - CD_FRAMESIZE_RAW); - } else { - insb(DATA_PORT, - azt_buf + - CD_FRAMESIZE * - azt_buf_in, - CD_FRAMESIZE); - } - azt_read_count--; -#ifdef AZT_TEST3 - printk - ("AZT_S_DATA; ---I've read data- read_count: %d\n", - azt_read_count); - printk - ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n", - azt_next_bn, - azt_buf_in, - azt_buf_out, - azt_buf_bn - [azt_buf_in]); -#endif - azt_buf_bn[azt_buf_in] = - azt_next_bn++; - if (azt_buf_out == -1) - azt_buf_out = - azt_buf_in; - azt_buf_in = - azt_buf_in + 1 == - AZT_BUF_SIZ ? 0 : - azt_buf_in + 1; - } - } - if (!azt_transfer_is_active) { - while (current_valid()) { - azt_transfer(); - if (CURRENT->nr_sectors == - 0) - end_request(CURRENT, 1); - else - break; - } - } - - if (current_valid() - && (CURRENT->sector / 4 < azt_next_bn - || CURRENT->sector / 4 > - azt_next_bn + AZT_BUF_SIZ)) { - azt_state = AZT_S_STOP; - loop_ctl = 1; - break; - } - AztTimeout = READ_TIMEOUT; - if (azt_read_count == 0) { - azt_state = AZT_S_STOP; - loop_ctl = 1; - break; - } - break; - } - break; - - - case AZT_S_STOP: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_STOP\n"); - } -#endif - if (azt_read_count != 0) - printk("aztcd: discard data=%x frames\n", - azt_read_count); - while (azt_read_count != 0) { - int i; - if (!(inb(STATUS_PORT) & AFL_DATA)) { - if (azt_read_mode == AZT_MODE_2) - for (i = 0; - i < CD_FRAMESIZE_RAW; - i++) - inb(DATA_PORT); - else - for (i = 0; - i < CD_FRAMESIZE; i++) - inb(DATA_PORT); - } - azt_read_count--; - } - if (aztSendCmd(ACMD_GET_STATUS)) - RETURN("azt_poll 5"); - azt_state = AZT_S_STOPPING; - AztTimeout = 1000; - break; - - case AZT_S_STOPPING: -#ifdef AZT_TEST3 - if (azt_state != azt_state_old) { - azt_state_old = azt_state; - printk("AZT_S_STOPPING\n"); - } -#endif - - if ((st = aztStatus()) == -1 && AztTimeout) - break; - - if ((st != -1) - && ((st & AST_DSK_CHG) - || (st & AST_NOT_READY))) { - aztDiskChanged = 1; - aztTocUpToDate = 0; - azt_invalidate_buffers(); - printk - ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n"); - end_request(CURRENT, 0); - } - -#ifdef AZT_TEST3 - printk("CURRENT_VALID %d azt_mode %d\n", - current_valid(), azt_mode); -#endif - - if (current_valid()) { - if (st != -1) { - if (azt_mode == 1) { - azt_state = AZT_S_READ; - loop_ctl = 1; - skip = 1; - break; - } else { - azt_state = AZT_S_MODE; - loop_ctl = 1; - skip = 1; - break; - } - } else { - azt_state = AZT_S_START; - AztTimeout = 1; - } - } else { - azt_state = AZT_S_IDLE; - return; - } - break; - - default: - printk("aztcd: invalid state %d\n", azt_state); - return; - } /* case */ - } /* while */ - - - if (!AztTimeout--) { - printk("aztcd: timeout in state %d\n", azt_state); - azt_state = AZT_S_STOP; - if (aztSendCmd(ACMD_STOP)) - RETURN("azt_poll 6"); - STEN_LOW_WAIT; - }; - - SET_TIMER(azt_poll, HZ / 100); -} - - -/*########################################################################### - * Miscellaneous support functions - ########################################################################### -*/ -static void azt_hsg2msf(long hsg, struct msf *msf) -{ - hsg += 150; - msf->min = hsg / 4500; - hsg %= 4500; - msf->sec = hsg / 75; - msf->frame = hsg % 75; -#ifdef AZT_DEBUG - if (msf->min >= 70) - printk("aztcd: Error hsg2msf address Minutes\n"); - if (msf->sec >= 60) - printk("aztcd: Error hsg2msf address Seconds\n"); - if (msf->frame >= 75) - printk("aztcd: Error hsg2msf address Frames\n"); -#endif - azt_bin2bcd(&msf->min); /* convert to BCD */ - azt_bin2bcd(&msf->sec); - azt_bin2bcd(&msf->frame); -} - -static long azt_msf2hsg(struct msf *mp) -{ - return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75 - + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET; -} - -static void azt_bin2bcd(unsigned char *p) -{ - int u, t; - - u = *p % 10; - t = *p / 10; - *p = u | (t << 4); -} - -static int azt_bcd2bin(unsigned char bcd) -{ - return (bcd >> 4) * 10 + (bcd & 0xF); -} - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR); diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h deleted file mode 100644 index 057501e31628..000000000000 --- a/drivers/cdrom/aztcd.h +++ /dev/null @@ -1,162 +0,0 @@ -/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $ - * - * Definitions for a AztechCD268 CD-ROM interface - * Copyright (C) 1994-98 Werner Zimmermann - * - * based on Mitsumi CDROM driver by Martin Harriss - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * History: W.Zimmermann adaption to Aztech CD268-01A Version 1.3 - * October 1994 Email: Werner.Zimmermann@fht-esslingen.de - */ - -/* *** change this to set the I/O port address of your CD-ROM drive, - set to '-1', if you want autoprobing */ -#define AZT_BASE_ADDR -1 - -/* list of autoprobing addresses (not more than 15), last value must be 0x000 - Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */ -#define AZT_BASE_AUTO { 0x320, 0x300, 0x310, 0x330, 0x000 } - -/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard - and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */ -/*#define AZT_SW32 1 -*/ - -#ifdef AZT_SW32 -#define AZT_SW32_BASE_ADDR 0x220 /*I/O port base address of your soundcard*/ -#endif - -/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray - from locking */ -#define AZT_ALLOW_TRAY_LOCK 1 - -/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you - don't want the auto-eject feature*/ -#define AZT_AUTO_EJECT 0 - -/*Set this to 1, if you want to use incompatible ioctls for reading in raw and - cooked mode */ -#define AZT_PRIVATE_IOCTLS 1 - -/*Set this to 1, if you want multisession support by the ISO fs. Even if you set - this value to '0' you can use multisession CDs. In that case the drive's firm- - ware will do the appropriate redirection automatically. The CD will then look - like a single session CD (but nevertheless all data may be read). Please read - chapter '5.1 Multisession support' in README.aztcd for details. Normally it's - uncritical to leave this setting untouched */ -#define AZT_MULTISESSION 1 - -/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */ -/*#define AZT_KERNEL_PRIOR_2_1 */ - -/*---------------------------------------------------------------------------*/ -/*-----nothing to be configured for normal applications below this line------*/ - - -/* Increase this if you get lots of timeouts; if you get kernel panic, replace - STEN_LOW_WAIT by STEN_LOW in the source code */ -#define AZT_STATUS_DELAY 400 /*for timer wait, STEN_LOW_WAIT*/ -#define AZT_TIMEOUT 8000000 /*for busy wait STEN_LOW, DTEN_LOW*/ -#define AZT_FAST_TIMEOUT 10000 /*for reading the version string*/ - -/* number of times to retry a command before giving up */ -#define AZT_RETRY_ATTEMPTS 3 - -/* port access macros */ -#define CMD_PORT azt_port -#define DATA_PORT azt_port -#define STATUS_PORT azt_port+1 -#define MODE_PORT azt_port+2 -#ifdef AZT_SW32 - #define AZT_SW32_INIT (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16)) - #define AZT_SW32_CONFIG_REG AZT_SW32_BASE_ADDR+0x16 /*Soundwave32 Config. Register*/ - #define AZT_SW32_ID_REG AZT_SW32_BASE_ADDR+0x04 /*Soundwave32 ID Version Register*/ -#endif - -/* status bits */ -#define AST_CMD_CHECK 0x80 /* 1 = command error */ -#define AST_DOOR_OPEN 0x40 /* 1 = door is open */ -#define AST_NOT_READY 0x20 /* 1 = no disk in the drive */ -#define AST_DSK_CHG 0x02 /* 1 = disk removed or changed */ -#define AST_MODE 0x01 /* 0=MODE1, 1=MODE2 */ -#define AST_MODE_BITS 0x1C /* Mode Bits */ -#define AST_INITIAL 0x0C /* initial, only valid ... */ -#define AST_BUSY 0x04 /* now playing, only valid - in combination with mode - bits */ -/* flag bits */ -#define AFL_DATA 0x02 /* data available if low */ -#define AFL_STATUS 0x04 /* status available if low */ -#define AFL_OP_OK 0x01 /* OP_OK command correct*/ -#define AFL_PA_OK 0x02 /* PA_OK parameter correct*/ -#define AFL_OP_ERR 0x05 /* error in command*/ -#define AFL_PA_ERR 0x06 /* error in parameters*/ -#define POLLED 0x04 /* polled mode */ - -/* commands */ -#define ACMD_SOFT_RESET 0x10 /* reset drive */ -#define ACMD_PLAY_READ 0x20 /* read data track in cooked mode */ -#define ACMD_PLAY_READ_RAW 0x21 /* reading in raw mode*/ -#define ACMD_SEEK 0x30 /* seek msf address*/ -#define ACMD_SEEK_TO_LEADIN 0x31 /* seek to leadin track*/ -#define ACMD_GET_ERROR 0x40 /* get error code */ -#define ACMD_GET_STATUS 0x41 /* get status */ -#define ACMD_GET_Q_CHANNEL 0x50 /* read info from q channel */ -#define ACMD_EJECT 0x60 /* eject/open tray */ -#define ACMD_CLOSE 0x61 /* close tray */ -#define ACMD_LOCK 0x71 /* lock tray closed */ -#define ACMD_UNLOCK 0x72 /* unlock tray */ -#define ACMD_PAUSE 0x80 /* pause */ -#define ACMD_STOP 0x81 /* stop play */ -#define ACMD_PLAY_AUDIO 0x90 /* play audio track */ -#define ACMD_SET_VOLUME 0x93 /* set audio level */ -#define ACMD_GET_VERSION 0xA0 /* get firmware version */ -#define ACMD_SET_DISK_TYPE 0xA1 /* set disk data mode */ - -#define MAX_TRACKS 104 - -struct msf { - unsigned char min; - unsigned char sec; - unsigned char frame; -}; - -struct azt_Play_msf { - struct msf start; - struct msf end; -}; - -struct azt_DiskInfo { - unsigned char first; - unsigned char next; - unsigned char last; - struct msf diskLength; - struct msf firstTrack; - unsigned char multi; - struct msf nextSession; - struct msf lastSession; - unsigned char xa; - unsigned char audio; -}; - -struct azt_Toc { - unsigned char ctrl_addr; - unsigned char track; - unsigned char pointIndex; - struct msf trackTime; - struct msf diskTime; -}; diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c deleted file mode 100644 index 2157c58755e0..000000000000 --- a/drivers/cdrom/cdu31a.c +++ /dev/null @@ -1,3251 +0,0 @@ -/* -* Sony CDU-31A CDROM interface device driver. -* -* Corey Minyard (minyard@wf-rch.cirr.com) -* -* Colossians 3:17 -* -* See Documentation/cdrom/cdu31a for additional details about this driver. -* -* The Sony interface device driver handles Sony interface CDROM -* drives and provides a complete block-level interface as well as an -* ioctl() interface compatible with the Sun (as specified in -* include/linux/cdrom.h). With this interface, CDROMs can be -* accessed and standard audio CDs can be played back normally. -* -* WARNING - All autoprobes have been removed from the driver. -* You MUST configure the CDU31A via a LILO config -* at boot time or in lilo.conf. I have the -* following in my lilo.conf: -* -* append="cdu31a=0x1f88,0,PAS" -* -* The first number is the I/O base address of the -* card. The second is the interrupt (0 means none). - * The third should be "PAS" if on a Pro-Audio - * spectrum, or nothing if on something else. - * - * This interface is (unfortunately) a polled interface. This is - * because most Sony interfaces are set up with DMA and interrupts - * disables. Some (like mine) do not even have the capability to - * handle interrupts or DMA. For this reason you will see a lot of - * the following: - * - * retry_count = jiffies+ SONY_JIFFIES_TIMEOUT; - * while (time_before(jiffies, retry_count) && (! - * For finding abug in the return of the track numbers. - * TOC processing redone for proper multisession support. - * - * - * It probably a little late to be adding a history, but I guess I - * will start. - * - * 10/24/95 - Added support for disabling the eject button when the - * drive is open. Note that there is a small problem - * still here, if the eject button is pushed while the - * drive light is flashing, the drive will return a bad - * status and be reset. It recovers, though. - * - * 03/07/97 - Fixed a problem with timers. - * - * - * 18 Spetember 1997 -- Ported to Uniform CD-ROM driver by - * Heiko Eissfeldt with additional - * changes by Erik Andersen - * - * 24 January 1998 -- Removed the scd_disc_status() function, which was now - * just dead code left over from the port. - * Erik Andersen - * - * 16 July 1998 -- Drive donated to Erik Andersen by John Kodis - * . Work begun on fixing driver to - * work under 2.1.X. Added temporary extra printks - * which seem to slow it down enough to work. - * - * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - * - * 22 October 2004 -- Make the driver work in 2.6.X - * Added workaround to fix hard lockups on eject - * Fixed door locking problem after mounting empty drive - * Set double-speed drives to double speed by default - * Removed all readahead things - not needed anymore - * Ondrej Zary -*/ - -#define DEBUG 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "cdu31a.h" - -#define MAJOR_NR CDU31A_CDROM_MAJOR -#include - -#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10 - -#define PFX "CDU31A: " - -/* -** Edit the following data to change interrupts, DMA channels, etc. -** Default is polled and no DMA. DMA is not recommended for double-speed -** drives. -*/ -static struct { - unsigned short base; /* I/O Base Address */ - short int_num; /* Interrupt Number (-1 means scan for it, - 0 means don't use) */ -} cdu31a_addresses[] __initdata = { - {0} -}; - -static int handle_sony_cd_attention(void); -static int read_subcode(void); -static void sony_get_toc(void); -static int scd_spinup(void); -/*static int scd_open(struct inode *inode, struct file *filp);*/ -static int scd_open(struct cdrom_device_info *, int); -static void do_sony_cd_cmd(unsigned char cmd, - unsigned char *params, - unsigned int num_params, - unsigned char *result_buffer, - unsigned int *result_size); -static void size_to_buf(unsigned int size, unsigned char *buf); - -/* Parameters for the read-ahead. */ -static unsigned int sony_next_block; /* Next 512 byte block offset */ -static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left - in the current read command. */ - - -/* The base I/O address of the Sony Interface. This is a variable (not a - #define) so it can be easily changed via some future ioctl() */ -static unsigned int cdu31a_port = 0; -module_param(cdu31a_port, uint, 0); - -/* - * The following are I/O addresses of the various registers for the drive. The - * comment for the base address also applies here. - */ -static volatile unsigned short sony_cd_cmd_reg; -static volatile unsigned short sony_cd_param_reg; -static volatile unsigned short sony_cd_write_reg; -static volatile unsigned short sony_cd_control_reg; -static volatile unsigned short sony_cd_status_reg; -static volatile unsigned short sony_cd_result_reg; -static volatile unsigned short sony_cd_read_reg; -static volatile unsigned short sony_cd_fifost_reg; - -static struct request_queue *cdu31a_queue; -static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */ - -static int sony_spun_up = 0; /* Has the drive been spun up? */ - -static int sony_speed = 0; /* Last wanted speed */ - -static int sony_xa_mode = 0; /* Is an XA disk in the drive - and the drive a CDU31A? */ - -static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio. - For raw data reads. */ - -static unsigned int sony_usage = 0; /* How many processes have the - drive open. */ - -static int sony_pas_init = 0; /* Initialize the Pro-Audio - Spectrum card? */ - -static struct s_sony_session_toc single_toc; /* Holds the - table of - contents. */ - -static struct s_all_sessions_toc sony_toc; /* entries gathered from all - sessions */ - -static int sony_toc_read = 0; /* Has the TOC been read for - the drive? */ - -static struct s_sony_subcode last_sony_subcode; /* Points to the last - subcode address read */ - -static DECLARE_MUTEX(sony_sem); /* Semaphore for drive hardware access */ - -static int is_double_speed = 0; /* does the drive support double speed ? */ - -static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */ - -/* - * The audio status uses the values from read subchannel data as specified - * in include/linux/cdrom.h. - */ -static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS; - -/* - * The following are a hack for pausing and resuming audio play. The drive - * does not work as I would expect it, if you stop it then start it again, - * the drive seeks back to the beginning and starts over. This holds the - * position during a pause so a resume can restart it. It uses the - * audio status variable above to tell if it is paused. - */ -static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 }; -static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 }; - -/* What IRQ is the drive using? 0 if none. */ -static int cdu31a_irq = 0; -module_param(cdu31a_irq, int, 0); - -/* The interrupt handler will wake this queue up when it gets an - interrupts. */ -static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); -static int irq_flag = 0; - -static int curr_control_reg = 0; /* Current value of the control register */ - -/* A disk changed variable. When a disk change is detected, it will - all be set to TRUE. As the upper layers ask for disk_changed status - it will be cleared. */ -static char disk_changed; - -/* This was readahead_buffer once... Now it's used only for audio reads */ -static char audio_buffer[CD_FRAMESIZE_RAW]; - -/* Used to time a short period to abort an operation after the - drive has been idle for a while. This keeps the light on - the drive from flashing for very long. */ -static struct timer_list cdu31a_abort_timer; - -/* Marks if the timeout has started an abort read. This is used - on entry to the drive to tell the code to read out the status - from the abort read. */ -static int abort_read_started = 0; - -/* - * Uniform cdrom interface function - * report back, if disc has changed from time of last request. - */ -static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr) -{ - int retval; - - retval = disk_changed; - disk_changed = 0; - - return retval; -} - -/* - * Uniform cdrom interface function - * report back, if drive is ready - */ -static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr) -{ - if (CDSL_CURRENT != slot_nr) - /* we have no changer support */ - return -EINVAL; - if (sony_spun_up) - return CDS_DISC_OK; - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - if (scd_spinup() == 0) - sony_spun_up = 1; - up(&sony_sem); - return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY; -} - -static inline void enable_interrupts(void) -{ - curr_control_reg |= (SONY_ATTN_INT_EN_BIT - | SONY_RES_RDY_INT_EN_BIT - | SONY_DATA_RDY_INT_EN_BIT); - outb(curr_control_reg, sony_cd_control_reg); -} - -static inline void disable_interrupts(void) -{ - curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT - | SONY_RES_RDY_INT_EN_BIT - | SONY_DATA_RDY_INT_EN_BIT); - outb(curr_control_reg, sony_cd_control_reg); -} - -/* - * Wait a little while (used for polling the drive). If in initialization, - * setting a timeout doesn't work, so just loop for a while. - */ -static inline void sony_sleep(void) -{ - if (cdu31a_irq <= 0) { - yield(); - } else { /* Interrupt driven */ - DEFINE_WAIT(w); - int first = 1; - - while (1) { - prepare_to_wait(&cdu31a_irq_wait, &w, - TASK_INTERRUPTIBLE); - if (first) { - enable_interrupts(); - first = 0; - } - - if (irq_flag != 0) - break; - if (!signal_pending(current)) { - schedule(); - continue; - } else - disable_interrupts(); - break; - } - finish_wait(&cdu31a_irq_wait, &w); - irq_flag = 0; - } -} - - -/* - * The following are convenience routine to read various status and set - * various conditions in the drive. - */ -static inline int is_attention(void) -{ - return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0; -} - -static inline int is_busy(void) -{ - return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0; -} - -static inline int is_data_ready(void) -{ - return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0; -} - -static inline int is_data_requested(void) -{ - return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0; -} - -static inline int is_result_ready(void) -{ - return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0; -} - -static inline int is_param_write_rdy(void) -{ - return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0; -} - -static inline int is_result_reg_not_empty(void) -{ - return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0; -} - -static inline void reset_drive(void) -{ - curr_control_reg = 0; - sony_toc_read = 0; - outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg); -} - -/* - * Uniform cdrom interface function - * reset drive and return when it is ready - */ -static int scd_reset(struct cdrom_device_info *cdi) -{ - unsigned long retry_count; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - reset_drive(); - - retry_count = jiffies + SONY_RESET_TIMEOUT; - while (time_before(jiffies, retry_count) && (!is_attention())) { - sony_sleep(); - } - - up(&sony_sem); - return 0; -} - -static inline void clear_attention(void) -{ - outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg); -} - -static inline void clear_result_ready(void) -{ - outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg); -} - -static inline void clear_data_ready(void) -{ - outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT, - sony_cd_control_reg); -} - -static inline void clear_param_reg(void) -{ - outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg); -} - -static inline unsigned char read_status_register(void) -{ - return inb(sony_cd_status_reg); -} - -static inline unsigned char read_result_register(void) -{ - return inb(sony_cd_result_reg); -} - -static inline unsigned char read_data_register(void) -{ - return inb(sony_cd_read_reg); -} - -static inline void write_param(unsigned char param) -{ - outb(param, sony_cd_param_reg); -} - -static inline void write_cmd(unsigned char cmd) -{ - outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT, - sony_cd_control_reg); - outb(cmd, sony_cd_cmd_reg); -} - -static irqreturn_t cdu31a_interrupt(int irq, void *dev_id) -{ - unsigned char val; - - if (abort_read_started) { - /* We might be waiting for an abort to finish. Don't - disable interrupts yet, though, because we handle - this one here. */ - /* Clear out the result registers. */ - while (is_result_reg_not_empty()) { - val = read_result_register(); - } - clear_data_ready(); - clear_result_ready(); - - /* Clear out the data */ - while (is_data_requested()) { - val = read_data_register(); - } - abort_read_started = 0; - - /* If something was waiting, wake it up now. */ - if (waitqueue_active(&cdu31a_irq_wait)) { - disable_interrupts(); - irq_flag = 1; - wake_up_interruptible(&cdu31a_irq_wait); - } - } else if (waitqueue_active(&cdu31a_irq_wait)) { - disable_interrupts(); - irq_flag = 1; - wake_up_interruptible(&cdu31a_irq_wait); - } else { - disable_interrupts(); - printk(KERN_NOTICE PFX - "Got an interrupt but nothing was waiting\n"); - } - return IRQ_HANDLED; -} - -/* - * give more verbose error messages - */ -static unsigned char *translate_error(unsigned char err_code) -{ - static unsigned char errbuf[80]; - - switch (err_code) { - case 0x10: return "illegal command "; - case 0x11: return "illegal parameter "; - - case 0x20: return "not loaded "; - case 0x21: return "no disc "; - case 0x22: return "not spinning "; - case 0x23: return "spinning "; - case 0x25: return "spindle servo "; - case 0x26: return "focus servo "; - case 0x29: return "eject mechanism "; - case 0x2a: return "audio playing "; - case 0x2c: return "emergency eject "; - - case 0x30: return "focus "; - case 0x31: return "frame sync "; - case 0x32: return "subcode address "; - case 0x33: return "block sync "; - case 0x34: return "header address "; - - case 0x40: return "illegal track read "; - case 0x41: return "mode 0 read "; - case 0x42: return "illegal mode read "; - case 0x43: return "illegal block size read "; - case 0x44: return "mode read "; - case 0x45: return "form read "; - case 0x46: return "leadout read "; - case 0x47: return "buffer overrun "; - - case 0x53: return "unrecoverable CIRC "; - case 0x57: return "unrecoverable LECC "; - - case 0x60: return "no TOC "; - case 0x61: return "invalid subcode data "; - case 0x63: return "focus on TOC read "; - case 0x64: return "frame sync on TOC read "; - case 0x65: return "TOC data "; - - case 0x70: return "hardware failure "; - case 0x91: return "leadin "; - case 0x92: return "leadout "; - case 0x93: return "data track "; - } - sprintf(errbuf, "unknown 0x%02x ", err_code); - return errbuf; -} - -/* - * Set the drive parameters so the drive will auto-spin-up when a - * disk is inserted. - */ -static void set_drive_params(int want_doublespeed) -{ - unsigned char res_reg[12]; - unsigned int res_size; - unsigned char params[3]; - - - params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME; - params[1] = 0x00; /* Never spin down the drive. */ - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_NOTICE PFX - "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]); - } - - params[0] = SONY_SD_MECH_CONTROL; - params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */ - - if (is_auto_eject) - params[1] |= SONY_AUTO_EJECT_BIT; - - if (is_double_speed && want_doublespeed) { - params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if - possible */ - } - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_NOTICE PFX "Unable to set mechanical " - "parameters: 0x%2.2x\n", res_reg[1]); - } -} - -/* - * Uniform cdrom interface function - * select reading speed for data access - */ -static int scd_select_speed(struct cdrom_device_info *cdi, int speed) -{ - if (speed == 0) - sony_speed = 1; - else - sony_speed = speed - 1; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - set_drive_params(sony_speed); - up(&sony_sem); - return 0; -} - -/* - * Uniform cdrom interface function - * lock or unlock eject button - */ -static int scd_lock_door(struct cdrom_device_info *cdi, int lock) -{ - if (lock == 0) { - is_auto_eject = 1; - } else { - is_auto_eject = 0; - } - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - set_drive_params(sony_speed); - up(&sony_sem); - return 0; -} - -/* - * This code will reset the drive and attempt to restore sane parameters. - */ -static void restart_on_error(void) -{ - unsigned char res_reg[12]; - unsigned int res_size; - unsigned long retry_count; - - - printk(KERN_NOTICE PFX "Resetting drive on error\n"); - reset_drive(); - retry_count = jiffies + SONY_RESET_TIMEOUT; - while (time_before(jiffies, retry_count) && (!is_attention())) { - sony_sleep(); - } - set_drive_params(sony_speed); - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size); - if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n", - res_reg[1]); - } - - msleep(2000); - - sony_get_toc(); -} - -/* - * This routine writes data to the parameter register. Since this should - * happen fairly fast, it is polled with no OS waits between. - */ -static int write_params(unsigned char *params, int num_params) -{ - unsigned int retry_count; - - - retry_count = SONY_READY_RETRIES; - while ((retry_count > 0) && (!is_param_write_rdy())) { - retry_count--; - } - if (!is_param_write_rdy()) { - return -EIO; - } - - while (num_params > 0) { - write_param(*params); - params++; - num_params--; - } - - return 0; -} - - -/* - * The following reads data from the command result register. It is a - * fairly complex routine, all status info flows back through this - * interface. The algorithm is stolen directly from the flowcharts in - * the drive manual. - */ -static void -get_result(unsigned char *result_buffer, unsigned int *result_size) -{ - unsigned char a, b; - int i; - unsigned long retry_count; - - - while (handle_sony_cd_attention()); - /* Wait for the result data to be ready */ - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) - && (is_busy() || (!(is_result_ready())))) { - sony_sleep(); - - while (handle_sony_cd_attention()); - } - if (is_busy() || (!(is_result_ready()))) { - pr_debug(PFX "timeout out %d\n", __LINE__); - result_buffer[0] = 0x20; - result_buffer[1] = SONY_TIMEOUT_OP_ERR; - *result_size = 2; - return; - } - - /* - * Get the first two bytes. This determines what else needs - * to be done. - */ - clear_result_ready(); - a = read_result_register(); - *result_buffer = a; - result_buffer++; - - /* Check for block error status result. */ - if ((a & 0xf0) == 0x50) { - *result_size = 1; - return; - } - - b = read_result_register(); - *result_buffer = b; - result_buffer++; - *result_size = 2; - - /* - * 0x20 means an error occurred. Byte 2 will have the error code. - * Otherwise, the command succeeded, byte 2 will have the count of - * how many more status bytes are coming. - * - * The result register can be read 10 bytes at a time, a wait for - * result ready to be asserted must be done between every 10 bytes. - */ - if ((a & 0xf0) != 0x20) { - if (b > 8) { - for (i = 0; i < 8; i++) { - *result_buffer = read_result_register(); - result_buffer++; - (*result_size)++; - } - b = b - 8; - - while (b > 10) { - retry_count = SONY_READY_RETRIES; - while ((retry_count > 0) - && (!is_result_ready())) { - retry_count--; - } - if (!is_result_ready()) { - pr_debug(PFX "timeout out %d\n", - __LINE__); - result_buffer[0] = 0x20; - result_buffer[1] = - SONY_TIMEOUT_OP_ERR; - *result_size = 2; - return; - } - - clear_result_ready(); - - for (i = 0; i < 10; i++) { - *result_buffer = - read_result_register(); - result_buffer++; - (*result_size)++; - } - b = b - 10; - } - - if (b > 0) { - retry_count = SONY_READY_RETRIES; - while ((retry_count > 0) - && (!is_result_ready())) { - retry_count--; - } - if (!is_result_ready()) { - pr_debug(PFX "timeout out %d\n", - __LINE__); - result_buffer[0] = 0x20; - result_buffer[1] = - SONY_TIMEOUT_OP_ERR; - *result_size = 2; - return; - } - } - } - - while (b > 0) { - *result_buffer = read_result_register(); - result_buffer++; - (*result_size)++; - b--; - } - } -} - -/* - * Do a command that does not involve data transfer. This routine must - * be re-entrant from the same task to support being called from the - * data operation code when an error occurs. - */ -static void -do_sony_cd_cmd(unsigned char cmd, - unsigned char *params, - unsigned int num_params, - unsigned char *result_buffer, unsigned int *result_size) -{ - unsigned long retry_count; - int num_retries = 0; - -retry_cd_operation: - - while (handle_sony_cd_attention()); - - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) && (is_busy())) { - sony_sleep(); - - while (handle_sony_cd_attention()); - } - if (is_busy()) { - pr_debug(PFX "timeout out %d\n", __LINE__); - result_buffer[0] = 0x20; - result_buffer[1] = SONY_TIMEOUT_OP_ERR; - *result_size = 2; - } else { - clear_result_ready(); - clear_param_reg(); - - write_params(params, num_params); - write_cmd(cmd); - - get_result(result_buffer, result_size); - } - - if (((result_buffer[0] & 0xf0) == 0x20) - && (num_retries < MAX_CDU31A_RETRIES)) { - num_retries++; - msleep(100); - goto retry_cd_operation; - } -} - - -/* - * Handle an attention from the drive. This will return 1 if it found one - * or 0 if not (if one is found, the caller might want to call again). - * - * This routine counts the number of consecutive times it is called - * (since this is always called from a while loop until it returns - * a 0), and returns a 0 if it happens too many times. This will help - * prevent a lockup. - */ -static int handle_sony_cd_attention(void) -{ - unsigned char atten_code; - static int num_consecutive_attentions = 0; - volatile int val; - - -#if 0 - pr_debug(PFX "Entering %s\n", __FUNCTION__); -#endif - if (is_attention()) { - if (num_consecutive_attentions > - CDU31A_MAX_CONSECUTIVE_ATTENTIONS) { - printk(KERN_NOTICE PFX "Too many consecutive " - "attentions: %d\n", num_consecutive_attentions); - num_consecutive_attentions = 0; - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, - __LINE__); - return 0; - } - - clear_attention(); - atten_code = read_result_register(); - - switch (atten_code) { - /* Someone changed the CD. Mark it as changed */ - case SONY_MECH_LOADED_ATTN: - disk_changed = 1; - sony_toc_read = 0; - sony_audio_status = CDROM_AUDIO_NO_STATUS; - sony_blocks_left = 0; - break; - - case SONY_SPIN_DOWN_COMPLETE_ATTN: - /* Mark the disk as spun down. */ - sony_spun_up = 0; - break; - - case SONY_AUDIO_PLAY_DONE_ATTN: - sony_audio_status = CDROM_AUDIO_COMPLETED; - read_subcode(); - break; - - case SONY_EJECT_PUSHED_ATTN: - if (is_auto_eject) { - sony_audio_status = CDROM_AUDIO_INVALID; - } - break; - - case SONY_LEAD_IN_ERR_ATTN: - case SONY_LEAD_OUT_ERR_ATTN: - case SONY_DATA_TRACK_ERR_ATTN: - case SONY_AUDIO_PLAYBACK_ERR_ATTN: - sony_audio_status = CDROM_AUDIO_ERROR; - break; - } - - num_consecutive_attentions++; - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); - return 1; - } else if (abort_read_started) { - while (is_result_reg_not_empty()) { - val = read_result_register(); - } - clear_data_ready(); - clear_result_ready(); - /* Clear out the data */ - while (is_data_requested()) { - val = read_data_register(); - } - abort_read_started = 0; - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); - return 1; - } - - num_consecutive_attentions = 0; -#if 0 - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); -#endif - return 0; -} - - -/* Convert from an integer 0-99 to BCD */ -static inline unsigned int int_to_bcd(unsigned int val) -{ - int retval; - - - retval = (val / 10) << 4; - retval = retval | val % 10; - return retval; -} - - -/* Convert from BCD to an integer from 0-99 */ -static unsigned int bcd_to_int(unsigned int bcd) -{ - return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f); -} - - -/* - * Convert a logical sector value (like the OS would want to use for - * a block device) to an MSF format. - */ -static void log_to_msf(unsigned int log, unsigned char *msf) -{ - log = log + LOG_START_OFFSET; - msf[0] = int_to_bcd(log / 4500); - log = log % 4500; - msf[1] = int_to_bcd(log / 75); - msf[2] = int_to_bcd(log % 75); -} - - -/* - * Convert an MSF format to a logical sector. - */ -static unsigned int msf_to_log(unsigned char *msf) -{ - unsigned int log; - - - log = msf[2]; - log += msf[1] * 75; - log += msf[0] * 4500; - log = log - LOG_START_OFFSET; - - return log; -} - - -/* - * Take in integer size value and put it into a buffer like - * the drive would want to see a number-of-sector value. - */ -static void size_to_buf(unsigned int size, unsigned char *buf) -{ - buf[0] = size / 65536; - size = size % 65536; - buf[1] = size / 256; - buf[2] = size % 256; -} - -/* Starts a read operation. Returns 0 on success and 1 on failure. - The read operation used here allows multiple sequential sectors - to be read and status returned for each sector. The driver will - read the output one at a time as the requests come and abort the - operation if the requested sector is not the next one from the - drive. */ -static int -start_request(unsigned int sector, unsigned int nsect) -{ - unsigned char params[6]; - unsigned long retry_count; - - - pr_debug(PFX "Entering %s\n", __FUNCTION__); - log_to_msf(sector, params); - size_to_buf(nsect, ¶ms[3]); - - /* - * Clear any outstanding attentions and wait for the drive to - * complete any pending operations. - */ - while (handle_sony_cd_attention()); - - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) && (is_busy())) { - sony_sleep(); - - while (handle_sony_cd_attention()); - } - - if (is_busy()) { - printk(KERN_NOTICE PFX "Timeout while waiting " - "to issue command\n"); - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); - return 1; - } else { - /* Issue the command */ - clear_result_ready(); - clear_param_reg(); - - write_params(params, 6); - write_cmd(SONY_READ_BLKERR_STAT_CMD); - - sony_blocks_left = nsect * 4; - sony_next_block = sector * 4; - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); - return 0; - } - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); -} - -/* Abort a pending read operation. Clear all the drive status variables. */ -static void abort_read(void) -{ - unsigned char result_reg[2]; - int result_size; - volatile int val; - - - do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size); - if ((result_reg[0] & 0xf0) == 0x20) { - printk(KERN_ERR PFX "Aborting read, %s error\n", - translate_error(result_reg[1])); - } - - while (is_result_reg_not_empty()) { - val = read_result_register(); - } - clear_data_ready(); - clear_result_ready(); - /* Clear out the data */ - while (is_data_requested()) { - val = read_data_register(); - } - - sony_blocks_left = 0; -} - -/* Called when the timer times out. This will abort the - pending read operation. */ -static void handle_abort_timeout(unsigned long data) -{ - pr_debug(PFX "Entering %s\n", __FUNCTION__); - /* If it is in use, ignore it. */ - if (down_trylock(&sony_sem) == 0) { - /* We can't use abort_read(), because it will sleep - or schedule in the timer interrupt. Just start - the operation, finish it on the next access to - the drive. */ - clear_result_ready(); - clear_param_reg(); - write_cmd(SONY_ABORT_CMD); - - sony_blocks_left = 0; - abort_read_started = 1; - up(&sony_sem); - } - pr_debug(PFX "Leaving %s\n", __FUNCTION__); -} - -/* Actually get one sector of data from the drive. */ -static void -input_data_sector(char *buffer) -{ - pr_debug(PFX "Entering %s\n", __FUNCTION__); - - /* If an XA disk on a CDU31A, skip the first 12 bytes of data from - the disk. The real data is after that. We can use audio_buffer. */ - if (sony_xa_mode) - insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD); - - clear_data_ready(); - - insb(sony_cd_read_reg, buffer, 2048); - - /* If an XA disk, we have to clear out the rest of the unused - error correction data. We can use audio_buffer for that. */ - if (sony_xa_mode) - insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL); - - pr_debug(PFX "Leaving %s\n", __FUNCTION__); -} - -/* read data from the drive. Note the nsect must be <= 4. */ -static void -read_data_block(char *buffer, - unsigned int block, - unsigned int nblocks, - unsigned char res_reg[], int *res_size) -{ - unsigned long retry_count; - - pr_debug(PFX "Entering %s\n", __FUNCTION__); - - res_reg[0] = 0; - res_reg[1] = 0; - *res_size = 0; - - /* Wait for the drive to tell us we have something */ - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) && !(is_data_ready())) { - while (handle_sony_cd_attention()); - - sony_sleep(); - } - if (!(is_data_ready())) { - if (is_result_ready()) { - get_result(res_reg, res_size); - if ((res_reg[0] & 0xf0) != 0x20) { - printk(KERN_NOTICE PFX "Got result that should" - " have been error: %d\n", res_reg[0]); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - abort_read(); - } else { - pr_debug(PFX "timeout out %d\n", __LINE__); - res_reg[0] = 0x20; - res_reg[1] = SONY_TIMEOUT_OP_ERR; - *res_size = 2; - abort_read(); - } - } else { - input_data_sector(buffer); - sony_blocks_left -= nblocks; - sony_next_block += nblocks; - - /* Wait for the status from the drive. */ - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) - && !(is_result_ready())) { - while (handle_sony_cd_attention()); - - sony_sleep(); - } - - if (!is_result_ready()) { - pr_debug(PFX "timeout out %d\n", __LINE__); - res_reg[0] = 0x20; - res_reg[1] = SONY_TIMEOUT_OP_ERR; - *res_size = 2; - abort_read(); - } else { - get_result(res_reg, res_size); - - /* If we got a buffer status, handle that. */ - if ((res_reg[0] & 0xf0) == 0x50) { - - if ((res_reg[0] == - SONY_NO_CIRC_ERR_BLK_STAT) - || (res_reg[0] == - SONY_NO_LECC_ERR_BLK_STAT) - || (res_reg[0] == - SONY_RECOV_LECC_ERR_BLK_STAT)) { - /* nothing here */ - } else { - printk(KERN_ERR PFX "Data block " - "error: 0x%x\n", res_reg[0]); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - - /* Final transfer is done for read command, get final result. */ - if (sony_blocks_left == 0) { - get_result(res_reg, res_size); - } - } else if ((res_reg[0] & 0xf0) != 0x20) { - /* The drive gave me bad status, I don't know what to do. - Reset the driver and return an error. */ - printk(KERN_ERR PFX "Invalid block " - "status: 0x%x\n", res_reg[0]); - restart_on_error(); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - } - } - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); -} - - -/* - * The OS calls this to perform a read or write operation to the drive. - * Write obviously fail. Reads to a read ahead of sony_buffer_size - * bytes to help speed operations. This especially helps since the OS - * uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most - * data access on a CD is done sequentially, this saves a lot of operations. - */ -static void do_cdu31a_request(request_queue_t * q) -{ - struct request *req; - int block, nblock, num_retries; - unsigned char res_reg[12]; - unsigned int res_size; - - pr_debug(PFX "Entering %s\n", __FUNCTION__); - - spin_unlock_irq(q->queue_lock); - if (down_interruptible(&sony_sem)) { - spin_lock_irq(q->queue_lock); - return; - } - - /* Get drive status before doing anything. */ - while (handle_sony_cd_attention()); - - /* Make sure we have a valid TOC. */ - sony_get_toc(); - - - /* Make sure the timer is cancelled. */ - del_timer(&cdu31a_abort_timer); - - while (1) { - /* - * The beginning here is stolen from the hard disk driver. I hope - * it's right. - */ - req = elv_next_request(q); - if (!req) - goto end_do_cdu31a_request; - - if (!sony_spun_up) - scd_spinup(); - - block = req->sector; - nblock = req->nr_sectors; - pr_debug(PFX "request at block %d, length %d blocks\n", - block, nblock); - if (!sony_toc_read) { - printk(KERN_NOTICE PFX "TOC not read\n"); - end_request(req, 0); - continue; - } - - /* WTF??? */ - if (!blk_fs_request(req)) { - end_request(req, 0); - continue; - } - if (rq_data_dir(req) == WRITE) { - end_request(req, 0); - continue; - } - - /* - * If the block address is invalid or the request goes beyond the end of - * the media, return an error. - */ - if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) { - printk(KERN_NOTICE PFX "Request past end of media\n"); - end_request(req, 0); - continue; - } - - if (nblock > 4) - nblock = 4; - num_retries = 0; - - try_read_again: - while (handle_sony_cd_attention()); - - if (!sony_toc_read) { - printk(KERN_NOTICE PFX "TOC not read\n"); - end_request(req, 0); - continue; - } - - /* If no data is left to be read from the drive, start the - next request. */ - if (sony_blocks_left == 0) { - if (start_request(block / 4, nblock / 4)) { - end_request(req, 0); - continue; - } - } - /* If the requested block is not the next one waiting in - the driver, abort the current operation and start a - new one. */ - else if (block != sony_next_block) { - pr_debug(PFX "Read for block %d, expected %d\n", - block, sony_next_block); - abort_read(); - if (!sony_toc_read) { - printk(KERN_NOTICE PFX "TOC not read\n"); - end_request(req, 0); - continue; - } - if (start_request(block / 4, nblock / 4)) { - printk(KERN_NOTICE PFX "start request failed\n"); - end_request(req, 0); - continue; - } - } - - read_data_block(req->buffer, block, nblock, res_reg, &res_size); - - if (res_reg[0] != 0x20) { - if (!end_that_request_first(req, 1, nblock)) { - spin_lock_irq(q->queue_lock); - blkdev_dequeue_request(req); - end_that_request_last(req, 1); - spin_unlock_irq(q->queue_lock); - } - continue; - } - - if (num_retries > MAX_CDU31A_RETRIES) { - end_request(req, 0); - continue; - } - - num_retries++; - if (res_reg[1] == SONY_NOT_SPIN_ERR) { - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, - &res_size); - } else { - printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n", - translate_error(res_reg[1]), block, nblock); - } - goto try_read_again; - } - end_do_cdu31a_request: -#if 0 - /* After finished, cancel any pending operations. */ - abort_read(); -#else - /* Start a timer to time out after a while to disable - the read. */ - cdu31a_abort_timer.expires = jiffies + 2 * HZ; /* Wait 2 seconds */ - add_timer(&cdu31a_abort_timer); -#endif - - up(&sony_sem); - spin_lock_irq(q->queue_lock); - pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); -} - - -/* - * Read the table of contents from the drive and set up TOC if - * successful. - */ -static void sony_get_toc(void) -{ - unsigned char res_reg[2]; - unsigned int res_size; - unsigned char parms[1]; - int session; - int num_spin_ups; - int totaltracks = 0; - int mint = 99; - int maxt = 0; - - pr_debug(PFX "Entering %s\n", __FUNCTION__); - - num_spin_ups = 0; - if (!sony_toc_read) { - respinup_on_gettoc: - /* Ignore the result, since it might error if spinning already. */ - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, - &res_size); - - do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, - &res_size); - - /* The drive sometimes returns error 0. I don't know why, but ignore - it. It seems to mean the drive has already done the operation. */ - if ((res_size < 2) - || ((res_reg[0] != 0) && (res_reg[1] != 0))) { - /* If the drive is already playing, it's ok. */ - if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) - || (res_reg[1] == 0)) { - goto gettoc_drive_spinning; - } - - /* If the drive says it is not spun up (even though we just did it!) - then retry the operation at least a few times. */ - if ((res_reg[1] == SONY_NOT_SPIN_ERR) - && (num_spin_ups < MAX_CDU31A_RETRIES)) { - num_spin_ups++; - goto respinup_on_gettoc; - } - - printk("cdu31a: Error reading TOC: %x %s\n", - res_reg[0], translate_error(res_reg[1])); - return; - } - - gettoc_drive_spinning: - - /* The idea here is we keep asking for sessions until the command - fails. Then we know what the last valid session on the disk is. - No need to check session 0, since session 0 is the same as session - 1; the command returns different information if you give it 0. - */ -#if DEBUG - memset(&sony_toc, 0x0e, sizeof(sony_toc)); - memset(&single_toc, 0x0f, sizeof(single_toc)); -#endif - session = 1; - while (1) { -/* This seems to slow things down enough to make it work. This - * appears to be a problem in do_sony_cd_cmd. This printk seems - * to address the symptoms... -Erik */ - pr_debug(PFX "Trying session %d\n", session); - parms[0] = session; - do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD, - parms, 1, res_reg, &res_size); - - pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]); - - if ((res_size < 2) - || ((res_reg[0] & 0xf0) == 0x20)) { - /* An error reading the TOC, this must be past the last session. */ - if (session == 1) - printk - ("Yikes! Couldn't read any sessions!"); - break; - } - pr_debug(PFX "Reading session %d\n", session); - - parms[0] = session; - do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD, - parms, - 1, - (unsigned char *) &single_toc, - &res_size); - if ((res_size < 2) - || ((single_toc.exec_status[0] & 0xf0) == - 0x20)) { - printk(KERN_ERR PFX "Error reading " - "session %d: %x %s\n", - session, single_toc.exec_status[0], - translate_error(single_toc. - exec_status[1])); - /* An error reading the TOC. Return without sony_toc_read - set. */ - return; - } - pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, " - "1st trk %d, dsktyp %x, dum0 %x\n", - single_toc.address0, single_toc.control0, - single_toc.point0, - bcd_to_int(single_toc.first_track_num), - single_toc.disk_type, single_toc.dummy0); - pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, " - "lst trk %d, dummy1 %x, dum2 %x\n", - single_toc.address1, single_toc.control1, - single_toc.point1, - bcd_to_int(single_toc.last_track_num), - single_toc.dummy1, single_toc.dummy2); - pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x " - "leadout start min %d, sec %d, frame %d\n", - single_toc.address2, single_toc.control2, - single_toc.point2, - bcd_to_int(single_toc.lead_out_start_msf[0]), - bcd_to_int(single_toc.lead_out_start_msf[1]), - bcd_to_int(single_toc.lead_out_start_msf[2])); - if (res_size > 18 && single_toc.pointb0 > 0xaf) - pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n" - "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n", - single_toc.addressb0, - single_toc.controlb0, - single_toc.pointb0, - bcd_to_int(single_toc. - next_poss_prog_area_msf - [0]), - bcd_to_int(single_toc. - next_poss_prog_area_msf - [1]), - bcd_to_int(single_toc. - next_poss_prog_area_msf - [2]), - single_toc.num_mode_5_pointers, - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [0]), - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [1]), - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [2])); - if (res_size > 27 && single_toc.pointb1 > 0xaf) - pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n", - single_toc.addressb1, - single_toc.controlb1, - single_toc.pointb1, - single_toc.dummyb0_1[0], - single_toc.dummyb0_1[1], - single_toc.dummyb0_1[2], - single_toc.dummyb0_1[3], - single_toc.num_skip_interval_pointers, - single_toc.num_skip_track_assignments, - single_toc.dummyb0_2); - if (res_size > 36 && single_toc.pointb2 > 0xaf) - pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n", - single_toc.addressb2, - single_toc.controlb2, - single_toc.pointb2, - single_toc.tracksb2[0], - single_toc.tracksb2[1], - single_toc.tracksb2[2], - single_toc.tracksb2[3], - single_toc.tracksb2[4], - single_toc.tracksb2[5], - single_toc.tracksb2[6]); - if (res_size > 45 && single_toc.pointb3 > 0xaf) - pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n", - single_toc.addressb3, - single_toc.controlb3, - single_toc.pointb3, - single_toc.tracksb3[0], - single_toc.tracksb3[1], - single_toc.tracksb3[2], - single_toc.tracksb3[3], - single_toc.tracksb3[4], - single_toc.tracksb3[5], - single_toc.tracksb3[6]); - if (res_size > 54 && single_toc.pointb4 > 0xaf) - pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n", - single_toc.addressb4, - single_toc.controlb4, - single_toc.pointb4, - single_toc.tracksb4[0], - single_toc.tracksb4[1], - single_toc.tracksb4[2], - single_toc.tracksb4[3], - single_toc.tracksb4[4], - single_toc.tracksb4[5], - single_toc.tracksb4[6]); - if (res_size > 63 && single_toc.pointc0 > 0xaf) - pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n", - single_toc.addressc0, - single_toc.controlc0, - single_toc.pointc0, - single_toc.dummyc0[0], - single_toc.dummyc0[1], - single_toc.dummyc0[2], - single_toc.dummyc0[3], - single_toc.dummyc0[4], - single_toc.dummyc0[5], - single_toc.dummyc0[6]); -#undef DEBUG -#define DEBUG 0 - - sony_toc.lead_out_start_msf[0] = - bcd_to_int(single_toc.lead_out_start_msf[0]); - sony_toc.lead_out_start_msf[1] = - bcd_to_int(single_toc.lead_out_start_msf[1]); - sony_toc.lead_out_start_msf[2] = - bcd_to_int(single_toc.lead_out_start_msf[2]); - sony_toc.lead_out_start_lba = - single_toc.lead_out_start_lba = - msf_to_log(sony_toc.lead_out_start_msf); - - /* For points that do not exist, move the data over them - to the right location. */ - if (single_toc.pointb0 != 0xb0) { - memmove(((char *) &single_toc) + 27, - ((char *) &single_toc) + 18, - res_size - 18); - res_size += 9; - } else if (res_size > 18) { - sony_toc.lead_out_start_msf[0] = - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [0]); - sony_toc.lead_out_start_msf[1] = - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [1]); - sony_toc.lead_out_start_msf[2] = - bcd_to_int(single_toc. - max_start_outer_leadout_msf - [2]); - sony_toc.lead_out_start_lba = - msf_to_log(sony_toc. - lead_out_start_msf); - } - if (single_toc.pointb1 != 0xb1) { - memmove(((char *) &single_toc) + 36, - ((char *) &single_toc) + 27, - res_size - 27); - res_size += 9; - } - if (single_toc.pointb2 != 0xb2) { - memmove(((char *) &single_toc) + 45, - ((char *) &single_toc) + 36, - res_size - 36); - res_size += 9; - } - if (single_toc.pointb3 != 0xb3) { - memmove(((char *) &single_toc) + 54, - ((char *) &single_toc) + 45, - res_size - 45); - res_size += 9; - } - if (single_toc.pointb4 != 0xb4) { - memmove(((char *) &single_toc) + 63, - ((char *) &single_toc) + 54, - res_size - 54); - res_size += 9; - } - if (single_toc.pointc0 != 0xc0) { - memmove(((char *) &single_toc) + 72, - ((char *) &single_toc) + 63, - res_size - 63); - res_size += 9; - } -#if DEBUG - printk(PRINT_INFO PFX "start track lba %u, " - "leadout start lba %u\n", - single_toc.start_track_lba, - single_toc.lead_out_start_lba); - { - int i; - for (i = 0; - i < - 1 + - bcd_to_int(single_toc.last_track_num) - - - bcd_to_int(single_toc. - first_track_num); i++) { - printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n", - i, - single_toc.tracks[i].address, - single_toc.tracks[i].control, - bcd_to_int(single_toc. - tracks[i].track), - bcd_to_int(single_toc. - tracks[i]. - track_start_msf - [0]), - bcd_to_int(single_toc. - tracks[i]. - track_start_msf - [1]), - bcd_to_int(single_toc. - tracks[i]. - track_start_msf - [2])); - if (mint > - bcd_to_int(single_toc. - tracks[i].track)) - mint = - bcd_to_int(single_toc. - tracks[i]. - track); - if (maxt < - bcd_to_int(single_toc. - tracks[i].track)) - maxt = - bcd_to_int(single_toc. - tracks[i]. - track); - } - printk(KERN_INFO PFX "min track number %d, " - "max track number %d\n", - mint, maxt); - } -#endif - - /* prepare a special table of contents for a CD-I disc. They don't have one. */ - if (single_toc.disk_type == 0x10 && - single_toc.first_track_num == 2 && - single_toc.last_track_num == 2 /* CD-I */ ) { - sony_toc.tracks[totaltracks].address = 1; - sony_toc.tracks[totaltracks].control = 4; /* force data tracks */ - sony_toc.tracks[totaltracks].track = 1; - sony_toc.tracks[totaltracks]. - track_start_msf[0] = 0; - sony_toc.tracks[totaltracks]. - track_start_msf[1] = 2; - sony_toc.tracks[totaltracks]. - track_start_msf[2] = 0; - mint = maxt = 1; - totaltracks++; - } else - /* gather track entries from this session */ - { - int i; - for (i = 0; - i < - 1 + - bcd_to_int(single_toc.last_track_num) - - - bcd_to_int(single_toc. - first_track_num); - i++, totaltracks++) { - sony_toc.tracks[totaltracks]. - address = - single_toc.tracks[i].address; - sony_toc.tracks[totaltracks]. - control = - single_toc.tracks[i].control; - sony_toc.tracks[totaltracks]. - track = - bcd_to_int(single_toc. - tracks[i].track); - sony_toc.tracks[totaltracks]. - track_start_msf[0] = - bcd_to_int(single_toc. - tracks[i]. - track_start_msf[0]); - sony_toc.tracks[totaltracks]. - track_start_msf[1] = - bcd_to_int(single_toc. - tracks[i]. - track_start_msf[1]); - sony_toc.tracks[totaltracks]. - track_start_msf[2] = - bcd_to_int(single_toc. - tracks[i]. - track_start_msf[2]); - if (i == 0) - single_toc. - start_track_lba = - msf_to_log(sony_toc. - tracks - [totaltracks]. - track_start_msf); - if (mint > - sony_toc.tracks[totaltracks]. - track) - mint = - sony_toc. - tracks[totaltracks]. - track; - if (maxt < - sony_toc.tracks[totaltracks]. - track) - maxt = - sony_toc. - tracks[totaltracks]. - track; - } - } - sony_toc.first_track_num = mint; - sony_toc.last_track_num = maxt; - /* Disk type of last session wins. For example: - CD-Extra has disk type 0 for the first session, so - a dumb HiFi CD player thinks it is a plain audio CD. - We are interested in the disk type of the last session, - which is 0x20 (XA) for CD-Extra, so we can access the - data track ... */ - sony_toc.disk_type = single_toc.disk_type; - sony_toc.sessions = session; - - /* don't believe everything :-) */ - if (session == 1) - single_toc.start_track_lba = 0; - sony_toc.start_track_lba = - single_toc.start_track_lba; - - if (session > 1 && single_toc.pointb0 == 0xb0 && - sony_toc.lead_out_start_lba == - single_toc.lead_out_start_lba) { - break; - } - - /* Let's not get carried away... */ - if (session > 40) { - printk(KERN_NOTICE PFX "too many sessions: " - "%d\n", session); - break; - } - session++; - } - sony_toc.track_entries = totaltracks; - /* add one entry for the LAST track with track number CDROM_LEADOUT */ - sony_toc.tracks[totaltracks].address = single_toc.address2; - sony_toc.tracks[totaltracks].control = single_toc.control2; - sony_toc.tracks[totaltracks].track = CDROM_LEADOUT; - sony_toc.tracks[totaltracks].track_start_msf[0] = - sony_toc.lead_out_start_msf[0]; - sony_toc.tracks[totaltracks].track_start_msf[1] = - sony_toc.lead_out_start_msf[1]; - sony_toc.tracks[totaltracks].track_start_msf[2] = - sony_toc.lead_out_start_msf[2]; - - sony_toc_read = 1; - - pr_debug(PFX "Disk session %d, start track: %d, " - "stop track: %d\n", - session, single_toc.start_track_lba, - single_toc.lead_out_start_lba); - } - pr_debug(PFX "Leaving %s\n", __FUNCTION__); -} - - -/* - * Uniform cdrom interface function - * return multisession offset and sector information - */ -static int scd_get_last_session(struct cdrom_device_info *cdi, - struct cdrom_multisession *ms_info) -{ - if (ms_info == NULL) - return 1; - - if (!sony_toc_read) { - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - sony_get_toc(); - up(&sony_sem); - } - - ms_info->addr_format = CDROM_LBA; - ms_info->addr.lba = sony_toc.start_track_lba; - ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE || - sony_toc.disk_type == 0x10 /* CDI */ ; - - return 0; -} - -/* - * Search for a specific track in the table of contents. - */ -static int find_track(int track) -{ - int i; - - for (i = 0; i <= sony_toc.track_entries; i++) { - if (sony_toc.tracks[i].track == track) { - return i; - } - } - - return -1; -} - - -/* - * Read the subcode and put it in last_sony_subcode for future use. - */ -static int read_subcode(void) -{ - unsigned int res_size; - - - do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD, - NULL, - 0, (unsigned char *) &last_sony_subcode, &res_size); - if ((res_size < 2) - || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n", - translate_error(last_sony_subcode.exec_status[1])); - return -EIO; - } - - last_sony_subcode.track_num = - bcd_to_int(last_sony_subcode.track_num); - last_sony_subcode.index_num = - bcd_to_int(last_sony_subcode.index_num); - last_sony_subcode.abs_msf[0] = - bcd_to_int(last_sony_subcode.abs_msf[0]); - last_sony_subcode.abs_msf[1] = - bcd_to_int(last_sony_subcode.abs_msf[1]); - last_sony_subcode.abs_msf[2] = - bcd_to_int(last_sony_subcode.abs_msf[2]); - - last_sony_subcode.rel_msf[0] = - bcd_to_int(last_sony_subcode.rel_msf[0]); - last_sony_subcode.rel_msf[1] = - bcd_to_int(last_sony_subcode.rel_msf[1]); - last_sony_subcode.rel_msf[2] = - bcd_to_int(last_sony_subcode.rel_msf[2]); - return 0; -} - -/* - * Uniform cdrom interface function - * return the media catalog number found on some older audio cds - */ -static int -scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) -{ - unsigned char resbuffer[2 + 14]; - unsigned char *mcnp = mcn->medium_catalog_number; - unsigned char *resp = resbuffer + 3; - unsigned int res_size; - - memset(mcn->medium_catalog_number, 0, 14); - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD, - NULL, 0, resbuffer, &res_size); - up(&sony_sem); - if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20)); - else { - /* packed bcd to single ASCII digits */ - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - } - *mcnp = '\0'; - return 0; -} - - -/* - * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If - * the drive is playing, the subchannel needs to be read (since it would be - * changing). If the drive is paused or completed, the subcode information has - * already been stored, just use that. The ioctl call wants things in decimal - * (not BCD), so all the conversions are done. - */ -static int sony_get_subchnl_info(struct cdrom_subchnl *schi) -{ - /* Get attention stuff */ - while (handle_sony_cd_attention()); - - sony_get_toc(); - if (!sony_toc_read) { - return -EIO; - } - - switch (sony_audio_status) { - case CDROM_AUDIO_NO_STATUS: - case CDROM_AUDIO_PLAY: - if (read_subcode() < 0) { - return -EIO; - } - break; - - case CDROM_AUDIO_PAUSED: - case CDROM_AUDIO_COMPLETED: - break; - -#if 0 - case CDROM_AUDIO_NO_STATUS: - schi->cdsc_audiostatus = sony_audio_status; - return 0; - break; -#endif - case CDROM_AUDIO_INVALID: - case CDROM_AUDIO_ERROR: - default: - return -EIO; - } - - schi->cdsc_audiostatus = sony_audio_status; - schi->cdsc_adr = last_sony_subcode.address; - schi->cdsc_ctrl = last_sony_subcode.control; - schi->cdsc_trk = last_sony_subcode.track_num; - schi->cdsc_ind = last_sony_subcode.index_num; - if (schi->cdsc_format == CDROM_MSF) { - schi->cdsc_absaddr.msf.minute = - last_sony_subcode.abs_msf[0]; - schi->cdsc_absaddr.msf.second = - last_sony_subcode.abs_msf[1]; - schi->cdsc_absaddr.msf.frame = - last_sony_subcode.abs_msf[2]; - - schi->cdsc_reladdr.msf.minute = - last_sony_subcode.rel_msf[0]; - schi->cdsc_reladdr.msf.second = - last_sony_subcode.rel_msf[1]; - schi->cdsc_reladdr.msf.frame = - last_sony_subcode.rel_msf[2]; - } else if (schi->cdsc_format == CDROM_LBA) { - schi->cdsc_absaddr.lba = - msf_to_log(last_sony_subcode.abs_msf); - schi->cdsc_reladdr.lba = - msf_to_log(last_sony_subcode.rel_msf); - } - - return 0; -} - -/* Get audio data from the drive. This is fairly complex because I - am looking for status and data at the same time, but if I get status - then I just look for data. I need to get the status immediately so - the switch from audio to data tracks will happen quickly. */ -static void -read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) -{ - unsigned long retry_count; - int result_read; - - - res_reg[0] = 0; - res_reg[1] = 0; - *res_size = 0; - result_read = 0; - - /* Wait for the drive to tell us we have something */ - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - continue_read_audio_wait: - while (time_before(jiffies, retry_count) && !(is_data_ready()) - && !(is_result_ready() || result_read)) { - while (handle_sony_cd_attention()); - - sony_sleep(); - } - if (!(is_data_ready())) { - if (is_result_ready() && !result_read) { - get_result(res_reg, res_size); - - /* Read block status and continue waiting for data. */ - if ((res_reg[0] & 0xf0) == 0x50) { - result_read = 1; - goto continue_read_audio_wait; - } - /* Invalid data from the drive. Shut down the operation. */ - else if ((res_reg[0] & 0xf0) != 0x20) { - printk(KERN_WARNING PFX "Got result that " - "should have been error: %d\n", - res_reg[0]); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - abort_read(); - } else { - pr_debug(PFX "timeout out %d\n", __LINE__); - res_reg[0] = 0x20; - res_reg[1] = SONY_TIMEOUT_OP_ERR; - *res_size = 2; - abort_read(); - } - } else { - clear_data_ready(); - - /* If data block, then get 2340 bytes offset by 12. */ - if (sony_raw_data_mode) { - insb(sony_cd_read_reg, buffer + CD_XA_HEAD, - CD_FRAMESIZE_RAW1); - } else { - /* Audio gets the whole 2352 bytes. */ - insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW); - } - - /* If I haven't already gotten the result, get it now. */ - if (!result_read) { - /* Wait for the drive to tell us we have something */ - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; - while (time_before(jiffies, retry_count) - && !(is_result_ready())) { - while (handle_sony_cd_attention()); - - sony_sleep(); - } - - if (!is_result_ready()) { - pr_debug(PFX "timeout out %d\n", __LINE__); - res_reg[0] = 0x20; - res_reg[1] = SONY_TIMEOUT_OP_ERR; - *res_size = 2; - abort_read(); - return; - } else { - get_result(res_reg, res_size); - } - } - - if ((res_reg[0] & 0xf0) == 0x50) { - if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT) - || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT) - || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT) - || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) { - /* Ok, nothing to do. */ - } else { - printk(KERN_ERR PFX "Data block error: 0x%x\n", - res_reg[0]); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - } else if ((res_reg[0] & 0xf0) != 0x20) { - /* The drive gave me bad status, I don't know what to do. - Reset the driver and return an error. */ - printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n", - res_reg[0]); - restart_on_error(); - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - } -} - -/* Perform a raw data read. This will automatically detect the - track type and read the proper data (audio or data). */ -static int read_audio(struct cdrom_read_audio *ra) -{ - int retval; - unsigned char params[2]; - unsigned char res_reg[12]; - unsigned int res_size; - unsigned int cframe; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - if (!sony_spun_up) - scd_spinup(); - - /* Set the drive to do raw operations. */ - params[0] = SONY_SD_DECODE_PARAM; - params[1] = 0x06 | sony_raw_data_mode; - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n", - res_reg[1]); - retval = -EIO; - goto out_up; - } - - /* From here down, we have to goto exit_read_audio instead of returning - because the drive parameters have to be set back to data before - return. */ - - retval = 0; - if (start_request(ra->addr.lba, ra->nframes)) { - retval = -EIO; - goto exit_read_audio; - } - - /* For every requested frame. */ - cframe = 0; - while (cframe < ra->nframes) { - read_audio_data(audio_buffer, res_reg, &res_size); - if ((res_reg[0] & 0xf0) == 0x20) { - if (res_reg[1] == SONY_BAD_DATA_ERR) { - printk(KERN_ERR PFX "Data error on audio " - "sector %d\n", - ra->addr.lba + cframe); - } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) { - /* Illegal track type, change track types and start over. */ - sony_raw_data_mode = - (sony_raw_data_mode) ? 0 : 1; - - /* Set the drive mode. */ - params[0] = SONY_SD_DECODE_PARAM; - params[1] = 0x06 | sony_raw_data_mode; - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, - 2, res_reg, &res_size); - if ((res_size < 2) - || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX "Unable to set " - "decode params: 0x%2.2x\n", - res_reg[1]); - retval = -EIO; - goto exit_read_audio; - } - - /* Restart the request on the current frame. */ - if (start_request - (ra->addr.lba + cframe, - ra->nframes - cframe)) { - retval = -EIO; - goto exit_read_audio; - } - - /* Don't go back to the top because don't want to get into - and infinite loop. A lot of code gets duplicated, but - that's no big deal, I don't guess. */ - read_audio_data(audio_buffer, res_reg, - &res_size); - if ((res_reg[0] & 0xf0) == 0x20) { - if (res_reg[1] == - SONY_BAD_DATA_ERR) { - printk(KERN_ERR PFX "Data error" - " on audio sector %d\n", - ra->addr.lba + - cframe); - } else { - printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n", - ra->addr.lba + cframe, - translate_error - (res_reg[1])); - retval = -EIO; - goto exit_read_audio; - } - } else if (copy_to_user(ra->buf + - (CD_FRAMESIZE_RAW - * cframe), - audio_buffer, - CD_FRAMESIZE_RAW)) { - retval = -EFAULT; - goto exit_read_audio; - } - } else { - printk(KERN_ERR PFX "Error reading audio " - "data on sector %d: %s\n", - ra->addr.lba + cframe, - translate_error(res_reg[1])); - retval = -EIO; - goto exit_read_audio; - } - } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe), - (char *)audio_buffer, - CD_FRAMESIZE_RAW)) { - retval = -EFAULT; - goto exit_read_audio; - } - - cframe++; - } - - get_result(res_reg, &res_size); - if ((res_reg[0] & 0xf0) == 0x20) { - printk(KERN_ERR PFX "Error return from audio read: %s\n", - translate_error(res_reg[1])); - retval = -EIO; - goto exit_read_audio; - } - - exit_read_audio: - - /* Set the drive mode back to the proper one for the disk. */ - params[0] = SONY_SD_DECODE_PARAM; - if (!sony_xa_mode) { - params[1] = 0x0f; - } else { - params[1] = 0x07; - } - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n", - res_reg[1]); - retval = -EIO; - } - - out_up: - up(&sony_sem); - - return retval; -} - -static int -do_sony_cd_cmd_chk(const char *name, - unsigned char cmd, - unsigned char *params, - unsigned int num_params, - unsigned char *result_buffer, unsigned int *result_size) -{ - do_sony_cd_cmd(cmd, params, num_params, result_buffer, - result_size); - if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX "Error %s (CDROM%s)\n", - translate_error(result_buffer[1]), name); - return -EIO; - } - return 0; -} - -/* - * Uniform cdrom interface function - * open the tray - */ -static int scd_tray_move(struct cdrom_device_info *cdi, int position) -{ - int retval; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - if (position == 1 /* open tray */ ) { - unsigned char res_reg[12]; - unsigned int res_size; - - do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, - &res_size); - do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, - &res_size); - - sony_audio_status = CDROM_AUDIO_INVALID; - retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0, - res_reg, &res_size); - } else { - if (0 == scd_spinup()) - sony_spun_up = 1; - retval = 0; - } - up(&sony_sem); - return retval; -} - -/* - * The big ugly ioctl handler. - */ -static int scd_audio_ioctl(struct cdrom_device_info *cdi, - unsigned int cmd, void *arg) -{ - unsigned char res_reg[12]; - unsigned int res_size; - unsigned char params[7]; - int i, retval; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - switch (cmd) { - case CDROMSTART: /* Spin up the drive */ - retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL, - 0, res_reg, &res_size); - break; - - case CDROMSTOP: /* Spin down the drive */ - do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, - &res_size); - - /* - * Spin the drive down, ignoring the error if the disk was - * already not spinning. - */ - sony_audio_status = CDROM_AUDIO_NO_STATUS; - retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL, - 0, res_reg, &res_size); - break; - - case CDROMPAUSE: /* Pause the drive */ - if (do_sony_cd_cmd_chk - ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, - &res_size)) { - retval = -EIO; - break; - } - /* Get the current position and save it for resuming */ - if (read_subcode() < 0) { - retval = -EIO; - break; - } - cur_pos_msf[0] = last_sony_subcode.abs_msf[0]; - cur_pos_msf[1] = last_sony_subcode.abs_msf[1]; - cur_pos_msf[2] = last_sony_subcode.abs_msf[2]; - sony_audio_status = CDROM_AUDIO_PAUSED; - retval = 0; - break; - - case CDROMRESUME: /* Start the drive after being paused */ - if (sony_audio_status != CDROM_AUDIO_PAUSED) { - retval = -EINVAL; - break; - } - - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, - &res_size); - - /* Start the drive at the saved position. */ - params[1] = int_to_bcd(cur_pos_msf[0]); - params[2] = int_to_bcd(cur_pos_msf[1]); - params[3] = int_to_bcd(cur_pos_msf[2]); - params[4] = int_to_bcd(final_pos_msf[0]); - params[5] = int_to_bcd(final_pos_msf[1]); - params[6] = int_to_bcd(final_pos_msf[2]); - params[0] = 0x03; - if (do_sony_cd_cmd_chk - ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, - &res_size) < 0) { - retval = -EIO; - break; - } - sony_audio_status = CDROM_AUDIO_PLAY; - retval = 0; - break; - - case CDROMPLAYMSF: /* Play starting at the given MSF address. */ - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, - &res_size); - - /* The parameters are given in int, must be converted */ - for (i = 1; i < 7; i++) { - params[i] = - int_to_bcd(((unsigned char *) arg)[i - 1]); - } - params[0] = 0x03; - if (do_sony_cd_cmd_chk - ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7, - res_reg, &res_size) < 0) { - retval = -EIO; - break; - } - - /* Save the final position for pauses and resumes */ - final_pos_msf[0] = bcd_to_int(params[4]); - final_pos_msf[1] = bcd_to_int(params[5]); - final_pos_msf[2] = bcd_to_int(params[6]); - sony_audio_status = CDROM_AUDIO_PLAY; - retval = 0; - break; - - case CDROMREADTOCHDR: /* Read the table of contents header */ - { - struct cdrom_tochdr *hdr; - - sony_get_toc(); - if (!sony_toc_read) { - retval = -EIO; - break; - } - - hdr = (struct cdrom_tochdr *) arg; - hdr->cdth_trk0 = sony_toc.first_track_num; - hdr->cdth_trk1 = sony_toc.last_track_num; - } - retval = 0; - break; - - case CDROMREADTOCENTRY: /* Read a given table of contents entry */ - { - struct cdrom_tocentry *entry; - int track_idx; - unsigned char *msf_val = NULL; - - sony_get_toc(); - if (!sony_toc_read) { - retval = -EIO; - break; - } - - entry = (struct cdrom_tocentry *) arg; - - track_idx = find_track(entry->cdte_track); - if (track_idx < 0) { - retval = -EINVAL; - break; - } - - entry->cdte_adr = - sony_toc.tracks[track_idx].address; - entry->cdte_ctrl = - sony_toc.tracks[track_idx].control; - msf_val = - sony_toc.tracks[track_idx].track_start_msf; - - /* Logical buffer address or MSF format requested? */ - if (entry->cdte_format == CDROM_LBA) { - entry->cdte_addr.lba = msf_to_log(msf_val); - } else if (entry->cdte_format == CDROM_MSF) { - entry->cdte_addr.msf.minute = *msf_val; - entry->cdte_addr.msf.second = - *(msf_val + 1); - entry->cdte_addr.msf.frame = - *(msf_val + 2); - } - } - retval = 0; - break; - - case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ - { - struct cdrom_ti *ti = (struct cdrom_ti *) arg; - int track_idx; - - sony_get_toc(); - if (!sony_toc_read) { - retval = -EIO; - break; - } - - if ((ti->cdti_trk0 < sony_toc.first_track_num) - || (ti->cdti_trk0 > sony_toc.last_track_num) - || (ti->cdti_trk1 < ti->cdti_trk0)) { - retval = -EINVAL; - break; - } - - track_idx = find_track(ti->cdti_trk0); - if (track_idx < 0) { - retval = -EINVAL; - break; - } - params[1] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[0]); - params[2] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[1]); - params[3] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[2]); - - /* - * If we want to stop after the last track, use the lead-out - * MSF to do that. - */ - if (ti->cdti_trk1 >= sony_toc.last_track_num) { - track_idx = find_track(CDROM_LEADOUT); - } else { - track_idx = find_track(ti->cdti_trk1 + 1); - } - if (track_idx < 0) { - retval = -EINVAL; - break; - } - params[4] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[0]); - params[5] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[1]); - params[6] = - int_to_bcd(sony_toc.tracks[track_idx]. - track_start_msf[2]); - params[0] = 0x03; - - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, - &res_size); - - do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, - res_reg, &res_size); - - if ((res_size < 2) - || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_ERR PFX - "Params: %x %x %x %x %x %x %x\n", - params[0], params[1], params[2], - params[3], params[4], params[5], - params[6]); - printk(KERN_ERR PFX - "Error %s (CDROMPLAYTRKIND)\n", - translate_error(res_reg[1])); - retval = -EIO; - break; - } - - /* Save the final position for pauses and resumes */ - final_pos_msf[0] = bcd_to_int(params[4]); - final_pos_msf[1] = bcd_to_int(params[5]); - final_pos_msf[2] = bcd_to_int(params[6]); - sony_audio_status = CDROM_AUDIO_PLAY; - retval = 0; - break; - } - - case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */ - { - struct cdrom_volctrl *volctrl = - (struct cdrom_volctrl *) arg; - - params[0] = SONY_SD_AUDIO_VOLUME; - params[1] = volctrl->channel0; - params[2] = volctrl->channel1; - retval = do_sony_cd_cmd_chk("VOLCTRL", - SONY_SET_DRIVE_PARAM_CMD, - params, 3, res_reg, - &res_size); - break; - } - case CDROMSUBCHNL: /* Get subchannel info */ - retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg); - break; - - default: - retval = -EINVAL; - break; - } - up(&sony_sem); - return retval; -} - -static int scd_read_audio(struct cdrom_device_info *cdi, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int retval; - - if (down_interruptible(&sony_sem)) - return -ERESTARTSYS; - switch (cmd) { - case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte - raw data tracks. */ - { - struct cdrom_read_audio ra; - - - sony_get_toc(); - if (!sony_toc_read) { - retval = -EIO; - break; - } - - if (copy_from_user(&ra, argp, sizeof(ra))) { - retval = -EFAULT; - break; - } - - if (ra.nframes == 0) { - retval = 0; - break; - } - - if (!access_ok(VERIFY_WRITE, ra.buf, - CD_FRAMESIZE_RAW * ra.nframes)) - return -EFAULT; - - if (ra.addr_format == CDROM_LBA) { - if ((ra.addr.lba >= - sony_toc.lead_out_start_lba) - || (ra.addr.lba + ra.nframes >= - sony_toc.lead_out_start_lba)) { - retval = -EINVAL; - break; - } - } else if (ra.addr_format == CDROM_MSF) { - if ((ra.addr.msf.minute >= 75) - || (ra.addr.msf.second >= 60) - || (ra.addr.msf.frame >= 75)) { - retval = -EINVAL; - break; - } - - ra.addr.lba = ((ra.addr.msf.minute * 4500) - + (ra.addr.msf.second * 75) - + ra.addr.msf.frame); - if ((ra.addr.lba >= - sony_toc.lead_out_start_lba) - || (ra.addr.lba + ra.nframes >= - sony_toc.lead_out_start_lba)) { - retval = -EINVAL; - break; - } - - /* I know, this can go negative on an unsigned. However, - the first thing done to the data is to add this value, - so this should compensate and allow direct msf access. */ - ra.addr.lba -= LOG_START_OFFSET; - } else { - retval = -EINVAL; - break; - } - - retval = read_audio(&ra); - break; - } - retval = 0; - break; - - default: - retval = -EINVAL; - } - up(&sony_sem); - return retval; -} - -static int scd_spinup(void) -{ - unsigned char res_reg[12]; - unsigned int res_size; - int num_spin_ups; - - num_spin_ups = 0; - - respinup_on_open: - do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size); - - /* The drive sometimes returns error 0. I don't know why, but ignore - it. It seems to mean the drive has already done the operation. */ - if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) { - printk(KERN_ERR PFX "%s error (scd_open, spin up)\n", - translate_error(res_reg[1])); - return 1; - } - - do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size); - - /* The drive sometimes returns error 0. I don't know why, but ignore - it. It seems to mean the drive has already done the operation. */ - if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) { - /* If the drive is already playing, it's ok. */ - if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) - || (res_reg[1] == 0)) { - return 0; - } - - /* If the drive says it is not spun up (even though we just did it!) - then retry the operation at least a few times. */ - if ((res_reg[1] == SONY_NOT_SPIN_ERR) - && (num_spin_ups < MAX_CDU31A_RETRIES)) { - num_spin_ups++; - goto respinup_on_open; - } - - printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n", - translate_error(res_reg[1])); - do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, - &res_size); - return 1; - } - return 0; -} - -/* - * Open the drive for operations. Spin the drive up and read the table of - * contents if these have not already been done. - */ -static int scd_open(struct cdrom_device_info *cdi, int purpose) -{ - unsigned char res_reg[12]; - unsigned int res_size; - unsigned char params[2]; - - if (purpose == 1) { - /* Open for IOCTLs only - no media check */ - sony_usage++; - return 0; - } - - if (sony_usage == 0) { - if (scd_spinup() != 0) - return -EIO; - sony_get_toc(); - if (!sony_toc_read) { - do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, - res_reg, &res_size); - return -EIO; - } - - /* For XA on the CDU31A only, we have to do special reads. - The CDU33A handles XA automagically. */ - /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */ - if ((sony_toc.disk_type != 0x00) - && (!is_double_speed)) { - params[0] = SONY_SD_DECODE_PARAM; - params[1] = 0x07; - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) - || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_WARNING PFX "Unable to set " - "XA params: 0x%2.2x\n", res_reg[1]); - } - sony_xa_mode = 1; - } - /* A non-XA disk. Set the parms back if necessary. */ - else if (sony_xa_mode) { - params[0] = SONY_SD_DECODE_PARAM; - params[1] = 0x0f; - do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, - params, 2, res_reg, &res_size); - if ((res_size < 2) - || ((res_reg[0] & 0xf0) == 0x20)) { - printk(KERN_WARNING PFX "Unable to reset " - "XA params: 0x%2.2x\n", res_reg[1]); - } - sony_xa_mode = 0; - } - - sony_spun_up = 1; - } - - sony_usage++; - - return 0; -} - - -/* - * Close the drive. Spin it down if no task is using it. The spin - * down will fail if playing audio, so audio play is OK. - */ -static void scd_release(struct cdrom_device_info *cdi) -{ - if (sony_usage == 1) { - unsigned char res_reg[12]; - unsigned int res_size; - - do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, - &res_size); - - sony_spun_up = 0; - } - sony_usage--; -} - -static struct cdrom_device_ops scd_dops = { - .open = scd_open, - .release = scd_release, - .drive_status = scd_drive_status, - .media_changed = scd_media_changed, - .tray_move = scd_tray_move, - .lock_door = scd_lock_door, - .select_speed = scd_select_speed, - .get_last_session = scd_get_last_session, - .get_mcn = scd_get_mcn, - .reset = scd_reset, - .audio_ioctl = scd_audio_ioctl, - .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK | - CDC_SELECT_SPEED | CDC_MULTI_SESSION | - CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | - CDC_RESET | CDC_DRIVE_STATUS, - .n_minors = 1, -}; - -static struct cdrom_device_info scd_info = { - .ops = &scd_dops, - .speed = 2, - .capacity = 1, - .name = "cdu31a" -}; - -static int scd_block_open(struct inode *inode, struct file *file) -{ - return cdrom_open(&scd_info, inode, file); -} - -static int scd_block_release(struct inode *inode, struct file *file) -{ - return cdrom_release(&scd_info, file); -} - -static int scd_block_ioctl(struct inode *inode, struct file *file, - unsigned cmd, unsigned long arg) -{ - int retval; - - /* The eject and close commands should be handled by Uniform CD-ROM - * driver - but I always got hard lockup instead of eject - * until I put this here. - */ - switch (cmd) { - case CDROMEJECT: - scd_lock_door(&scd_info, 0); - retval = scd_tray_move(&scd_info, 1); - break; - case CDROMCLOSETRAY: - retval = scd_tray_move(&scd_info, 0); - break; - case CDROMREADAUDIO: - retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg); - break; - default: - retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg); - } - return retval; -} - -static int scd_block_media_changed(struct gendisk *disk) -{ - return cdrom_media_changed(&scd_info); -} - -static struct block_device_operations scd_bdops = -{ - .owner = THIS_MODULE, - .open = scd_block_open, - .release = scd_block_release, - .ioctl = scd_block_ioctl, - .media_changed = scd_block_media_changed, -}; - -static struct gendisk *scd_gendisk; - -/* The different types of disc loading mechanisms supported */ -static char *load_mech[] __initdata = - { "caddy", "tray", "pop-up", "unknown" }; - -static int __init -get_drive_configuration(unsigned short base_io, - unsigned char res_reg[], unsigned int *res_size) -{ - unsigned long retry_count; - - - if (!request_region(base_io, 4, "cdu31a")) - return 0; - - /* Set the base address */ - cdu31a_port = base_io; - - /* Set up all the register locations */ - sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET; - sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET; - sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET; - sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET; - sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET; - sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET; - sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET; - sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET; - - /* - * Check to see if anything exists at the status register location. - * I don't know if this is a good way to check, but it seems to work - * ok for me. - */ - if (read_status_register() != 0xff) { - /* - * Reset the drive and wait for attention from it (to say it's reset). - * If you don't wait, the next operation will probably fail. - */ - reset_drive(); - retry_count = jiffies + SONY_RESET_TIMEOUT; - while (time_before(jiffies, retry_count) - && (!is_attention())) { - sony_sleep(); - } - -#if 0 - /* If attention is never seen probably not a CDU31a present */ - if (!is_attention()) { - res_reg[0] = 0x20; - goto out_err; - } -#endif - - /* - * Get the drive configuration. - */ - do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD, - NULL, - 0, (unsigned char *) res_reg, res_size); - if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0) - goto out_err; - return 1; - } - - /* Return an error */ - res_reg[0] = 0x20; -out_err: - release_region(cdu31a_port, 4); - cdu31a_port = 0; - return 0; -} - -#ifndef MODULE -/* - * Set up base I/O and interrupts, called from main.c. - */ - -static int __init cdu31a_setup(char *strings) -{ - int ints[4]; - - (void) get_options(strings, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) { - cdu31a_port = ints[1]; - } - if (ints[0] > 1) { - cdu31a_irq = ints[2]; - } - if ((strings != NULL) && (*strings != '\0')) { - if (strcmp(strings, "PAS") == 0) { - sony_pas_init = 1; - } else { - printk(KERN_NOTICE PFX "Unknown interface type: %s\n", - strings); - } - } - - return 1; -} - -__setup("cdu31a=", cdu31a_setup); - -#endif - -/* - * Initialize the driver. - */ -int __init cdu31a_init(void) -{ - struct s_sony_drive_config drive_config; - struct gendisk *disk; - int deficiency = 0; - unsigned int res_size; - char msg[255]; - char buf[40]; - int i; - int tmp_irq; - - /* - * According to Alex Freed (freed@europa.orion.adobe.com), this is - * required for the Fusion CD-16 package. If the sound driver is - * loaded, it should work fine, but just in case... - * - * The following turn on the CD-ROM interface for a Fusion CD-16. - */ - if (sony_pas_init) { - outb(0xbc, 0x9a01); - outb(0xe2, 0x9a01); - } - - /* Setting the base I/O address to 0xffff will disable it. */ - if (cdu31a_port == 0xffff) - goto errout3; - - if (cdu31a_port != 0) { - /* Need IRQ 0 because we can't sleep here. */ - tmp_irq = cdu31a_irq; - cdu31a_irq = 0; - if (!get_drive_configuration(cdu31a_port, - drive_config.exec_status, - &res_size)) - goto errout3; - cdu31a_irq = tmp_irq; - } else { - cdu31a_irq = 0; - for (i = 0; cdu31a_addresses[i].base; i++) { - if (get_drive_configuration(cdu31a_addresses[i].base, - drive_config.exec_status, - &res_size)) { - cdu31a_irq = cdu31a_addresses[i].int_num; - break; - } - } - if (!cdu31a_port) - goto errout3; - } - - if (register_blkdev(MAJOR_NR, "cdu31a")) - goto errout2; - - disk = alloc_disk(1); - if (!disk) - goto errout1; - disk->major = MAJOR_NR; - disk->first_minor = 0; - sprintf(disk->disk_name, "cdu31a"); - disk->fops = &scd_bdops; - disk->flags = GENHD_FL_CD; - - if (SONY_HWC_DOUBLE_SPEED(drive_config)) - is_double_speed = 1; - - tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */ - cdu31a_irq = 0; - - sony_speed = is_double_speed; /* Set 2X drives to 2X by default */ - set_drive_params(sony_speed); - - cdu31a_irq = tmp_irq; - - if (cdu31a_irq > 0) { - if (request_irq - (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED, - "cdu31a", NULL)) { - printk(KERN_WARNING PFX "Unable to grab IRQ%d for " - "the CDU31A driver\n", cdu31a_irq); - cdu31a_irq = 0; - } - } - - sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n", - drive_config.vendor_id, - drive_config.product_id, - drive_config.product_rev_level); - sprintf(buf, " Capabilities: %s", - load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]); - strcat(msg, buf); - if (SONY_HWC_AUDIO_PLAYBACK(drive_config)) - strcat(msg, ", audio"); - else - deficiency |= CDC_PLAY_AUDIO; - if (SONY_HWC_EJECT(drive_config)) - strcat(msg, ", eject"); - else - deficiency |= CDC_OPEN_TRAY; - if (SONY_HWC_LED_SUPPORT(drive_config)) - strcat(msg, ", LED"); - if (SONY_HWC_ELECTRIC_VOLUME(drive_config)) - strcat(msg, ", elec. Vol"); - if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config)) - strcat(msg, ", sep. Vol"); - if (is_double_speed) - strcat(msg, ", double speed"); - else - deficiency |= CDC_SELECT_SPEED; - if (cdu31a_irq > 0) { - sprintf(buf, ", irq %d", cdu31a_irq); - strcat(msg, buf); - } - strcat(msg, "\n"); - printk(KERN_INFO PFX "%s",msg); - - cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock); - if (!cdu31a_queue) - goto errout0; - blk_queue_hardsect_size(cdu31a_queue, 2048); - - init_timer(&cdu31a_abort_timer); - cdu31a_abort_timer.function = handle_abort_timeout; - - scd_info.mask = deficiency; - scd_gendisk = disk; - if (register_cdrom(&scd_info)) - goto err; - disk->queue = cdu31a_queue; - add_disk(disk); - - disk_changed = 1; - return 0; - -err: - blk_cleanup_queue(cdu31a_queue); -errout0: - if (cdu31a_irq) - free_irq(cdu31a_irq, NULL); - printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n"); - put_disk(disk); -errout1: - if (unregister_blkdev(MAJOR_NR, "cdu31a")) { - printk(KERN_WARNING PFX "Can't unregister block device\n"); - } -errout2: - release_region(cdu31a_port, 4); -errout3: - return -EIO; -} - - -static void __exit cdu31a_exit(void) -{ - del_gendisk(scd_gendisk); - put_disk(scd_gendisk); - if (unregister_cdrom(&scd_info)) { - printk(KERN_WARNING PFX "Can't unregister from Uniform " - "cdrom driver\n"); - return; - } - if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) { - printk(KERN_WARNING PFX "Can't unregister\n"); - return; - } - - blk_cleanup_queue(cdu31a_queue); - - if (cdu31a_irq > 0) - free_irq(cdu31a_irq, NULL); - - release_region(cdu31a_port, 4); - printk(KERN_INFO PFX "module released.\n"); -} - -#ifdef MODULE -module_init(cdu31a_init); -#endif -module_exit(cdu31a_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR); diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h deleted file mode 100644 index 61d4768c412e..000000000000 --- a/drivers/cdrom/cdu31a.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Definitions for a Sony interface CDROM drive. - * - * Corey Minyard (minyard@wf-rch.cirr.com) - * - * Copyright (C) 1993 Corey Minyard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * General defines. - */ -#define SONY_XA_DISK_TYPE 0x20 - -/* - * Offsets (from the base address) and bits for the various write registers - * of the drive. - */ -#define SONY_CMD_REG_OFFSET 0 -#define SONY_PARAM_REG_OFFSET 1 -#define SONY_WRITE_REG_OFFSET 2 -#define SONY_CONTROL_REG_OFFSET 3 -# define SONY_ATTN_CLR_BIT 0x01 -# define SONY_RES_RDY_CLR_BIT 0x02 -# define SONY_DATA_RDY_CLR_BIT 0x04 -# define SONY_ATTN_INT_EN_BIT 0x08 -# define SONY_RES_RDY_INT_EN_BIT 0x10 -# define SONY_DATA_RDY_INT_EN_BIT 0x20 -# define SONY_PARAM_CLR_BIT 0x40 -# define SONY_DRIVE_RESET_BIT 0x80 - -/* - * Offsets (from the base address) and bits for the various read registers - * of the drive. - */ -#define SONY_STATUS_REG_OFFSET 0 -# define SONY_ATTN_BIT 0x01 -# define SONY_RES_RDY_BIT 0x02 -# define SONY_DATA_RDY_BIT 0x04 -# define SONY_ATTN_INT_ST_BIT 0x08 -# define SONY_RES_RDY_INT_ST_BIT 0x10 -# define SONY_DATA_RDY_INT_ST_BIT 0x20 -# define SONY_DATA_REQUEST_BIT 0x40 -# define SONY_BUSY_BIT 0x80 -#define SONY_RESULT_REG_OFFSET 1 -#define SONY_READ_REG_OFFSET 2 -#define SONY_FIFOST_REG_OFFSET 3 -# define SONY_PARAM_WRITE_RDY_BIT 0x01 -# define SONY_PARAM_REG_EMPTY_BIT 0x02 -# define SONY_RES_REG_NOT_EMP_BIT 0x04 -# define SONY_RES_REG_FULL_BIT 0x08 - -#define LOG_START_OFFSET 150 /* Offset of first logical sector */ - -#define SONY_DETECT_TIMEOUT (8*HZ/10) /* Maximum amount of time - that drive detection code - will wait for response - from drive (in 1/100th's - of seconds). */ - -#define SONY_JIFFIES_TIMEOUT (10*HZ) /* Maximum number of times the - drive will wait/try for an - operation */ -#define SONY_RESET_TIMEOUT HZ /* Maximum number of times the - drive will wait/try a reset - operation */ -#define SONY_READY_RETRIES 20000 /* How many times to retry a - spin waiting for a register - to come ready */ - -#define MAX_CDU31A_RETRIES 3 /* How many times to retry an - operation */ - -/* Commands to request or set drive control parameters and disc information */ -#define SONY_REQ_DRIVE_CONFIG_CMD 0x00 /* Returns s_sony_drive_config */ -#define SONY_REQ_DRIVE_MODE_CMD 0x01 -#define SONY_REQ_DRIVE_PARAM_CMD 0x02 -#define SONY_REQ_MECH_STATUS_CMD 0x03 -#define SONY_REQ_AUDIO_STATUS_CMD 0x04 -#define SONY_SET_DRIVE_PARAM_CMD 0x10 -#define SONY_REQ_TOC_DATA_CMD 0x20 /* Returns s_sony_toc */ -#define SONY_REQ_SUBCODE_ADDRESS_CMD 0x21 /* Returns s_sony_subcode */ -#define SONY_REQ_UPC_EAN_CMD 0x22 -#define SONY_REQ_ISRC_CMD 0x23 -#define SONY_REQ_TOC_DATA_SPEC_CMD 0x24 /* Returns s_sony_session_toc */ - -/* Commands to request information from the drive */ -#define SONY_READ_TOC_CMD 0x30 /* let the drive firmware grab the TOC */ -#define SONY_SEEK_CMD 0x31 -#define SONY_READ_CMD 0x32 -#define SONY_READ_BLKERR_STAT_CMD 0x34 -#define SONY_ABORT_CMD 0x35 -#define SONY_READ_TOC_SPEC_CMD 0x36 - -/* Commands to control audio */ -#define SONY_AUDIO_PLAYBACK_CMD 0x40 -#define SONY_AUDIO_STOP_CMD 0x41 -#define SONY_AUDIO_SCAN_CMD 0x42 - -/* Miscellaneous control commands */ -#define SONY_EJECT_CMD 0x50 -#define SONY_SPIN_UP_CMD 0x51 -#define SONY_SPIN_DOWN_CMD 0x52 - -/* Diagnostic commands */ -#define SONY_WRITE_BUFFER_CMD 0x60 -#define SONY_READ_BUFFER_CMD 0x61 -#define SONY_DIAGNOSTICS_CMD 0x62 - - -/* - * The following are command parameters for the set drive parameter command - */ -#define SONY_SD_DECODE_PARAM 0x00 -#define SONY_SD_INTERFACE_PARAM 0x01 -#define SONY_SD_BUFFERING_PARAM 0x02 -#define SONY_SD_AUDIO_PARAM 0x03 -#define SONY_SD_AUDIO_VOLUME 0x04 -#define SONY_SD_MECH_CONTROL 0x05 -#define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06 - -/* - * The following are parameter bits for the mechanical control command - */ -#define SONY_AUTO_SPIN_UP_BIT 0x01 -#define SONY_AUTO_EJECT_BIT 0x02 -#define SONY_DOUBLE_SPEED_BIT 0x04 - -/* - * The following extract information from the drive configuration about - * the drive itself. - */ -#define SONY_HWC_GET_LOAD_MECH(c) (c.hw_config[0] & 0x03) -#define SONY_HWC_EJECT(c) (c.hw_config[0] & 0x04) -#define SONY_HWC_LED_SUPPORT(c) (c.hw_config[0] & 0x08) -#define SONY_HWC_DOUBLE_SPEED(c) (c.hw_config[0] & 0x10) -#define SONY_HWC_GET_BUF_MEM_SIZE(c) ((c.hw_config[0] & 0xc0) >> 6) -#define SONY_HWC_AUDIO_PLAYBACK(c) (c.hw_config[1] & 0x01) -#define SONY_HWC_ELECTRIC_VOLUME(c) (c.hw_config[1] & 0x02) -#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04) - -#define SONY_HWC_CADDY_LOAD_MECH 0x00 -#define SONY_HWC_TRAY_LOAD_MECH 0x01 -#define SONY_HWC_POPUP_LOAD_MECH 0x02 -#define SONY_HWC_UNKWN_LOAD_MECH 0x03 - -#define SONY_HWC_8KB_BUFFER 0x00 -#define SONY_HWC_32KB_BUFFER 0x01 -#define SONY_HWC_64KB_BUFFER 0x02 -#define SONY_HWC_UNKWN_BUFFER 0x03 - -/* - * This is the complete status returned from the drive configuration request - * command. - */ -struct s_sony_drive_config -{ - unsigned char exec_status[2]; - char vendor_id[8]; - char product_id[16]; - char product_rev_level[8]; - unsigned char hw_config[2]; -}; - -/* The following is returned from the request subcode address command */ -struct s_sony_subcode -{ - unsigned char exec_status[2]; - unsigned char address :4; - unsigned char control :4; - unsigned char track_num; - unsigned char index_num; - unsigned char rel_msf[3]; - unsigned char reserved1; - unsigned char abs_msf[3]; -}; - -#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */ -/* - * The following is returned from the request TOC (Table Of Contents) command. - * (last_track_num-first_track_num+1) values are valid in tracks. - */ -struct s_sony_toc -{ - unsigned char exec_status[2]; - unsigned char address0 :4; - unsigned char control0 :4; - unsigned char point0; - unsigned char first_track_num; - unsigned char disk_type; - unsigned char dummy0; - unsigned char address1 :4; - unsigned char control1 :4; - unsigned char point1; - unsigned char last_track_num; - unsigned char dummy1; - unsigned char dummy2; - unsigned char address2 :4; - unsigned char control2 :4; - unsigned char point2; - unsigned char lead_out_start_msf[3]; - struct - { - unsigned char address :4; - unsigned char control :4; - unsigned char track; - unsigned char track_start_msf[3]; - } tracks[MAX_TRACKS]; - - unsigned int lead_out_start_lba; -}; - -struct s_sony_session_toc -{ - unsigned char exec_status[2]; - unsigned char session_number; - unsigned char address0 :4; - unsigned char control0 :4; - unsigned char point0; - unsigned char first_track_num; - unsigned char disk_type; - unsigned char dummy0; - unsigned char address1 :4; - unsigned char control1 :4; - unsigned char point1; - unsigned char last_track_num; - unsigned char dummy1; - unsigned char dummy2; - unsigned char address2 :4; - unsigned char control2 :4; - unsigned char point2; - unsigned char lead_out_start_msf[3]; - unsigned char addressb0 :4; - unsigned char controlb0 :4; - unsigned char pointb0; - unsigned char next_poss_prog_area_msf[3]; - unsigned char num_mode_5_pointers; - unsigned char max_start_outer_leadout_msf[3]; - unsigned char addressb1 :4; - unsigned char controlb1 :4; - unsigned char pointb1; - unsigned char dummyb0_1[4]; - unsigned char num_skip_interval_pointers; - unsigned char num_skip_track_assignments; - unsigned char dummyb0_2; - unsigned char addressb2 :4; - unsigned char controlb2 :4; - unsigned char pointb2; - unsigned char tracksb2[7]; - unsigned char addressb3 :4; - unsigned char controlb3 :4; - unsigned char pointb3; - unsigned char tracksb3[7]; - unsigned char addressb4 :4; - unsigned char controlb4 :4; - unsigned char pointb4; - unsigned char tracksb4[7]; - unsigned char addressc0 :4; - unsigned char controlc0 :4; - unsigned char pointc0; - unsigned char dummyc0[7]; - struct - { - unsigned char address :4; - unsigned char control :4; - unsigned char track; - unsigned char track_start_msf[3]; - } tracks[MAX_TRACKS]; - - unsigned int start_track_lba; - unsigned int lead_out_start_lba; - unsigned int mint; - unsigned int maxt; -}; - -struct s_all_sessions_toc -{ - unsigned char sessions; - unsigned int track_entries; - unsigned char first_track_num; - unsigned char last_track_num; - unsigned char disk_type; - unsigned char lead_out_start_msf[3]; - struct - { - unsigned char address :4; - unsigned char control :4; - unsigned char track; - unsigned char track_start_msf[3]; - } tracks[MAX_TRACKS]; - - unsigned int start_track_lba; - unsigned int lead_out_start_lba; -}; - - -/* - * The following are errors returned from the drive. - */ - -/* Command error group */ -#define SONY_ILL_CMD_ERR 0x10 -#define SONY_ILL_PARAM_ERR 0x11 - -/* Mechanism group */ -#define SONY_NOT_LOAD_ERR 0x20 -#define SONY_NO_DISK_ERR 0x21 -#define SONY_NOT_SPIN_ERR 0x22 -#define SONY_SPIN_ERR 0x23 -#define SONY_SPINDLE_SERVO_ERR 0x25 -#define SONY_FOCUS_SERVO_ERR 0x26 -#define SONY_EJECT_MECH_ERR 0x29 -#define SONY_AUDIO_PLAYING_ERR 0x2a -#define SONY_EMERGENCY_EJECT_ERR 0x2c - -/* Seek error group */ -#define SONY_FOCUS_ERR 0x30 -#define SONY_FRAME_SYNC_ERR 0x31 -#define SONY_SUBCODE_ADDR_ERR 0x32 -#define SONY_BLOCK_SYNC_ERR 0x33 -#define SONY_HEADER_ADDR_ERR 0x34 - -/* Read error group */ -#define SONY_ILL_TRACK_R_ERR 0x40 -#define SONY_MODE_0_R_ERR 0x41 -#define SONY_ILL_MODE_R_ERR 0x42 -#define SONY_ILL_BLOCK_SIZE_R_ERR 0x43 -#define SONY_MODE_R_ERR 0x44 -#define SONY_FORM_R_ERR 0x45 -#define SONY_LEAD_OUT_R_ERR 0x46 -#define SONY_BUFFER_OVERRUN_R_ERR 0x47 - -/* Data error group */ -#define SONY_UNREC_CIRC_ERR 0x53 -#define SONY_UNREC_LECC_ERR 0x57 - -/* Subcode error group */ -#define SONY_NO_TOC_ERR 0x60 -#define SONY_SUBCODE_DATA_NVAL_ERR 0x61 -#define SONY_FOCUS_ON_TOC_READ_ERR 0x63 -#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64 -#define SONY_TOC_DATA_ERR 0x65 - -/* Hardware failure group */ -#define SONY_HW_FAILURE_ERR 0x70 -#define SONY_LEAD_IN_A_ERR 0x91 -#define SONY_LEAD_OUT_A_ERR 0x92 -#define SONY_DATA_TRACK_A_ERR 0x93 - -/* - * The following are returned from the Read With Block Error Status command. - * They are not errors but information (Errors from the 0x5x group above may - * also be returned - */ -#define SONY_NO_CIRC_ERR_BLK_STAT 0x50 -#define SONY_NO_LECC_ERR_BLK_STAT 0x54 -#define SONY_RECOV_LECC_ERR_BLK_STAT 0x55 -#define SONY_NO_ERR_DETECTION_STAT 0x59 - -/* - * The following is not an error returned by the drive, but by the code - * that talks to the drive. It is returned because of a timeout. - */ -#define SONY_TIMEOUT_OP_ERR 0x01 -#define SONY_SIGNAL_OP_ERR 0x02 -#define SONY_BAD_DATA_ERR 0x03 - - -/* - * The following are attention code for asynchronous events from the drive. - */ - -/* Standard attention group */ -#define SONY_EMER_EJECT_ATTN 0x2c -#define SONY_HW_FAILURE_ATTN 0x70 -#define SONY_MECH_LOADED_ATTN 0x80 -#define SONY_EJECT_PUSHED_ATTN 0x81 - -/* Audio attention group */ -#define SONY_AUDIO_PLAY_DONE_ATTN 0x90 -#define SONY_LEAD_IN_ERR_ATTN 0x91 -#define SONY_LEAD_OUT_ERR_ATTN 0x92 -#define SONY_DATA_TRACK_ERR_ATTN 0x93 -#define SONY_AUDIO_PLAYBACK_ERR_ATTN 0x94 - -/* Auto spin up group */ -#define SONY_SPIN_UP_COMPLETE_ATTN 0x24 -#define SONY_SPINDLE_SERVO_ERR_ATTN 0x25 -#define SONY_FOCUS_SERVO_ERR_ATTN 0x26 -#define SONY_TOC_READ_DONE_ATTN 0x62 -#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63 -#define SONY_SYNC_ON_TOC_READ_ERR_ATTN 0x65 - -/* Auto eject group */ -#define SONY_SPIN_DOWN_COMPLETE_ATTN 0x27 -#define SONY_EJECT_COMPLETE_ATTN 0x28 -#define SONY_EJECT_MECH_ERR_ATTN 0x29 diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c deleted file mode 100644 index 2f8fe3b6bbd0..000000000000 --- a/drivers/cdrom/cm206.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card. - Copyright (c) 1995--1997 David A. van Leeuwen. - $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -History: - Started 25 jan 1994. Waiting for documentation... - 22 feb 1995: 0.1a first reasonably safe polling driver. - Two major bugs, one in read_sector and one in - do_cm206_request, happened to cancel! - 25 feb 1995: 0.2a first reasonable interrupt driven version of above. - uart writes are still done in polling mode. - 25 feb 1995: 0.21a writes also in interrupt mode, still some - small bugs to be found... Larger buffer. - 2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in - initialization), read_ahead of 16. Timeouts implemented. - unclear if they do something... - 7 mrt 1995: 0.23 Start of background read-ahead. - 18 mrt 1995: 0.24 Working background read-ahead. (still problems) - 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2). - Statistics implemented, though separate stats206.h. - Accessible through ioctl 0x1000 (just a number). - Hard to choose between v1.2 development and 1.1.75. - Bottom-half doesn't work with 1.2... - 0.25a: fixed... typo. Still problems... - 1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n. - 5 apr 1995: 0.27 Auto-probe for the adapter card base address. - Auto-probe for the adaptor card irq line. - 7 apr 1995: 0.28 Added lilo setup support for base address and irq. - Use major number 32 (not in this source), officially - assigned to this driver. - 9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause, - resume, eject. Play_track ignores track info, because we can't - read a table-of-contents entry. Toc_entry is implemented - as a `placebo' function: always returns start of disc. - 3 may 1995: 0.30 Audio support completed. The get_toc_entry function - is implemented as a binary search. - 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to - satisfy; changed binary search into linear search. - Auto-probe for base address somewhat relaxed. - 1 jun 1995: 0.32 Removed probe_irq_on/off for module version. - 10 jun 1995: 0.33 Workman still behaves funny, but you should be - able to eject and substitute another disc. - - An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg - - 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering - verify_area's in the ioctls. Some bugs introduced by - EM considering the base port and irq fixed. - - 18 dec 1995: 0.35 Add some code for error checking... no luck... - - We jump to reach our goal: version 1.0 in the next stable linux kernel. - - 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on - request of Thomas Quinot. - 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR: - open only for ioctl operation, e.g., for operation of - tray etc. - 4 apr 1996: 0.97 First implementation of layer between VFS and cdrom - driver, a generic interface. Much of the functionality - of cm206_open() and cm206_ioctl() is transferred to a - new file cdrom.c and its header ucdrom.h. - - Upgrade to Linux kernel 1.3.78. - - 11 apr 1996 0.98 Upgrade to Linux kernel 1.3.85 - More code moved to cdrom.c - - 0.99 Some more small changes to decrease number - of oopses at module load; - - 27 jul 1996 0.100 Many hours of debugging, kernel change from 1.2.13 - to 2.0.7 seems to have introduced some weird behavior - in (interruptible_)sleep_on(&cd->data): the process - seems to be woken without any explicit wake_up in my own - code. Patch to try 100x in case such untriggered wake_up's - occur. - - 28 jul 1996 0.101 Rewriting of the code that receives the command echo, - using a fifo to store echoed bytes. - - Branch from 0.99: - - 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t - (emoenke) various typos found by others. extra - module-load oops protection. - - 0.99.1.1 Initialization constant cdrom_dops.speed - changed from float (2.0) to int (2); Cli()-sti() pair - around cm260_reset() in module initialization code. - - 0.99.1.2 Changes literally as proposed by Scott Snyder - for the 2.1 kernel line, which - have to do mainly with the poor minor support i had. The - major new concept is to change a cdrom driver's - operations struct from the capabilities struct. This - reflects the fact that there is one major for a driver, - whilst there can be many minors whith completely - different capabilities. - - 0.99.1.3 More changes for operations/info separation. - - 0.99.1.4 Added speed selection (someone had to do this - first). - - 23 jan 1997 0.99.1.5 MODULE_PARMS call added. - - 23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as - 0.99.1.1--0.99.1.5. I get too many complaints about the - drive making read errors. What't wrong with the 2.0+ - kernel line? Why get i (and othe cm206 owners) weird - results? Why were things good in the good old 1.1--1.2 - era? Why don't i throw away the drive? - - 2 feb 1997 0.102 Added `volatile' to values in cm206_struct. Seems to - reduce many of the problems. Rewrote polling routines - to use fixed delays between polls. - 0.103 Changed printk behavior. - 0.104 Added a 0.100 -> 0.100.1.1 change - -11 feb 1997 0.105 Allow auto_probe during module load, disable - with module option "auto_probe=0". Moved some debugging - statements to lower priority. Implemented select_speed() - function. - -13 feb 1997 1.0 Final version for 2.0 kernel line. - - All following changes will be for the 2.1 kernel line. - -15 feb 1997 1.1 Keep up with kernel 2.1.26, merge in changes from - cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS. - -14 sep 1997 1.2 Upgrade to Linux 2.1.55. Added blksize_size[], patch - sent by James Bottomley . - -21 dec 1997 1.4 Upgrade to Linux 2.1.72. - -24 jan 1998 Removed the cm206_disc_status() function, as it was now dead - code. The Uniform CDROM driver now provides this functionality. - -9 Nov. 1999 Make kernel-parameter implementation work with 2.3.x - Removed init_module & cleanup_module in favor of - module_init & module_exit. - Torben Mathiasen - * - * Parts of the code are based upon lmscd.c written by Kai Petzke, - * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin - * Harriss, but any off-the-shelf dynamic programming algorithm won't - * be able to find them. - * - * The cm206 drive interface and the cm260 adapter card seem to be - * sufficiently different from their cm205/cm250 counterparts - * in order to write a complete new driver. - * - * I call all routines connected to the Linux kernel something - * with `cm206' in it, as this stuff is too series-dependent. - * - * Currently, my limited knowledge is based on: - * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson - * - Linux Kernel Programmierung, by Michael Beck and others - * - Philips/LMS cm206 and cm226 product specification - * - Philips/LMS cm260 product specification - * - * David van Leeuwen, david@tm.tno.nl. */ -#define REVISION "$Revision: 1.5 $" - -#include - -#include /* These include what we really need */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #include */ - -#include - -#define MAJOR_NR CM206_CDROM_MAJOR - -#include - -#undef DEBUG -#define STATISTICS /* record times and frequencies of events */ -#define AUTO_PROBE_MODULE -#define USE_INSW - -#include "cm206.h" - -/* This variable defines whether or not to probe for adapter base port - address and interrupt request. It can be overridden by the boot - parameter `auto'. -*/ -static int auto_probe = 1; /* Yes, why not? */ - -static int cm206_base = CM206_BASE; -static int cm206_irq = CM206_IRQ; -#ifdef MODULE -static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */ -module_param_array(cm206, int, NULL, 0); /* base,irq or irq,base */ -#endif - -module_param(cm206_base, int, 0); /* base */ -module_param(cm206_irq, int, 0); /* irq */ -module_param(auto_probe, bool, 0); /* auto probe base and irq */ -MODULE_LICENSE("GPL"); - -#define POLLOOP 100 /* milliseconds */ -#define READ_AHEAD 1 /* defines private buffer, waste! */ -#define BACK_AHEAD 1 /* defines adapter-read ahead */ -#define DATA_TIMEOUT (3*HZ) /* measured in jiffies (10 ms) */ -#define UART_TIMEOUT (5*HZ/100) -#define DSB_TIMEOUT (7*HZ) /* time for the slowest command to finish */ -#define UR_SIZE 4 /* uart receive buffer fifo size */ - -#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */ -#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */ -#define ISO_SECTOR_SIZE 2048 -#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */ -#define CD_SYNC_HEAD 16 /* CD_SYNC + CD_HEAD */ - -#ifdef STATISTICS /* keep track of errors in counters */ -#define stats(i) { ++cd->stats[st_ ## i]; \ - cd->last_stat[st_ ## i] = cd->stat_counter++; \ - } -#else -#define stats(i) (void) 0; -#endif - -#define Debug(a) {printk (KERN_DEBUG); printk a;} -#ifdef DEBUG -#define debug(a) Debug(a) -#else -#define debug(a) (void) 0; -#endif - -typedef unsigned char uch; /* 8-bits */ -typedef unsigned short ush; /* 16-bits */ - -struct toc_struct { /* private copy of Table of Contents */ - uch track, fsm[3], q0; -}; - -struct cm206_struct { - volatile ush intr_ds; /* data status read on last interrupt */ - volatile ush intr_ls; /* uart line status read on last interrupt */ - volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */ - volatile uch ur_w, ur_r; /* write/read buffer index */ - volatile uch dsb, cc; /* drive status byte and condition (error) code */ - int command; /* command to be written to the uart */ - int openfiles; - ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2]; /* buffered cd-sector */ - int sector_first, sector_last; /* range of these sectors */ - wait_queue_head_t uart; /* wait queues for interrupt */ - wait_queue_head_t data; - struct timer_list timer; /* time-out */ - char timed_out; - signed char max_sectors; /* number of sectors that fit in adapter mem */ - char wait_back; /* we're waiting for a background-read */ - char background; /* is a read going on in the background? */ - int adapter_first; /* if so, that's the starting sector */ - int adapter_last; - char fifo_overflowed; - uch disc_status[7]; /* result of get_disc_status command */ -#ifdef STATISTICS - int stats[NR_STATS]; - int last_stat[NR_STATS]; /* `time' at which stat was stat */ - int stat_counter; -#endif - struct toc_struct toc[101]; /* The whole table of contents + lead-out */ - uch q[10]; /* Last read q-channel info */ - uch audio_status[5]; /* last read position on pause */ - uch media_changed; /* record if media changed */ -}; - -#define DISC_STATUS cd->disc_status[0] -#define FIRST_TRACK cd->disc_status[1] -#define LAST_TRACK cd->disc_status[2] -#define PAUSED cd->audio_status[0] /* misuse this memory byte! */ -#define PLAY_TO cd->toc[0] /* toc[0] records end-time in play */ - -static struct cm206_struct *cd; /* the main memory structure */ -static struct request_queue *cm206_queue; -static DEFINE_SPINLOCK(cm206_lock); - -/* First, we define some polling functions. These are actually - only being used in the initialization. */ - -static void send_command_polled(int command) -{ - int loop = POLLOOP; - while (!(inw(r_line_status) & ls_transmitter_buffer_empty) - && loop > 0) { - mdelay(1); /* one millisec delay */ - --loop; - } - outw(command, r_uart_transmit); -} - -static uch receive_echo_polled(void) -{ - int loop = POLLOOP; - while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) { - mdelay(1); - --loop; - } - return ((uch) inw(r_uart_receive)); -} - -static uch send_receive_polled(int command) -{ - send_command_polled(command); - return receive_echo_polled(); -} - -static inline void clear_ur(void) -{ - if (cd->ur_r != cd->ur_w) { - debug(("Deleting bytes from fifo:")); - for (; cd->ur_r != cd->ur_w; - cd->ur_r++, cd->ur_r %= UR_SIZE) - debug((" 0x%x", cd->ur[cd->ur_r])); - debug(("\n")); - } -} - -static struct tasklet_struct cm206_tasklet; - -/* The interrupt handler. When the cm260 generates an interrupt, very - much care has to be taken in reading out the registers in the right - order; in case of a receive_buffer_full interrupt, first the - uart_receive must be read, and then the line status again to - de-assert the interrupt line. It took me a couple of hours to find - this out:-( - - The function reset_cm206 appears to cause an interrupt, because - pulling up the INIT line clears both the uart-write-buffer /and/ - the uart-write-buffer-empty mask. We call this a `lost interrupt,' - as there seems so reason for this to happen. -*/ - -static irqreturn_t cm206_interrupt(int sig, void *dev_id) -{ - volatile ush fool; - cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error, - crc_error, sync_error, toc_ready - interrupts */ - cd->intr_ls = inw(r_line_status); /* resets overrun bit */ - debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls, - cd->background)); - if (cd->intr_ls & ls_attention) - stats(attention); - /* receive buffer full? */ - if (cd->intr_ls & ls_receive_buffer_full) { - cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */ - cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */ - debug(("receiving #%d: 0x%x\n", cd->ur_w, - cd->ur[cd->ur_w])); - cd->ur_w++; - cd->ur_w %= UR_SIZE; - if (cd->ur_w == cd->ur_r) - debug(("cd->ur overflow!\n")); - if (waitqueue_active(&cd->uart) && cd->background < 2) { - del_timer(&cd->timer); - wake_up_interruptible(&cd->uart); - } - } - /* data ready in fifo? */ - else if (cd->intr_ds & ds_data_ready) { - if (cd->background) - ++cd->adapter_last; - if (waitqueue_active(&cd->data) - && (cd->wait_back || !cd->background)) { - del_timer(&cd->timer); - wake_up_interruptible(&cd->data); - } - stats(data_ready); - } - /* ready to issue a write command? */ - else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) { - outw(dc_normal | (inw(r_data_status) & 0x7f), - r_data_control); - outw(cd->command, r_uart_transmit); - cd->command = 0; - if (!cd->background) - wake_up_interruptible(&cd->uart); - } - /* now treat errors (at least, identify them for debugging) */ - else if (cd->intr_ds & ds_fifo_overflow) { - debug(("Fifo overflow at sectors 0x%x\n", - cd->sector_first)); - fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */ - cd->fifo_overflowed = 1; /* signal one word less should be read */ - stats(fifo_overflow); - } else if (cd->intr_ds & ds_data_error) { - debug(("Data error at sector 0x%x\n", cd->sector_first)); - stats(data_error); - } else if (cd->intr_ds & ds_crc_error) { - debug(("CRC error at sector 0x%x\n", cd->sector_first)); - stats(crc_error); - } else if (cd->intr_ds & ds_sync_error) { - debug(("Sync at sector 0x%x\n", cd->sector_first)); - stats(sync_error); - } else if (cd->intr_ds & ds_toc_ready) { - /* do something appropriate */ - } - /* couldn't see why this interrupt, maybe due to init */ - else { - outw(dc_normal | READ_AHEAD, r_data_control); - stats(lost_intr); - } - if (cd->background - && (cd->adapter_last - cd->adapter_first == cd->max_sectors - || cd->fifo_overflowed)) - tasklet_schedule(&cm206_tasklet); /* issue a stop read command */ - stats(interrupt); - return IRQ_HANDLED; -} - -/* we have put the address of the wait queue in who */ -static void cm206_timeout(unsigned long who) -{ - cd->timed_out = 1; - debug(("Timing out\n")); - wake_up_interruptible((wait_queue_head_t *) who); -} - -/* This function returns 1 if a timeout occurred, 0 if an interrupt - happened */ -static int sleep_or_timeout(wait_queue_head_t * wait, int timeout) -{ - cd->timed_out = 0; - init_timer(&cd->timer); - cd->timer.data = (unsigned long) wait; - cd->timer.expires = jiffies + timeout; - add_timer(&cd->timer); - debug(("going to sleep\n")); - interruptible_sleep_on(wait); - del_timer(&cd->timer); - if (cd->timed_out) { - cd->timed_out = 0; - return 1; - } else - return 0; -} - -static void send_command(int command) -{ - debug(("Sending 0x%x\n", command)); - if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) { - cd->command = command; - cli(); /* don't interrupt before sleep */ - outw(dc_mask_sync_error | dc_no_stop_on_error | - (inw(r_data_status) & 0x7f), r_data_control); - /* interrupt routine sends command */ - if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) { - debug(("Time out on write-buffer\n")); - stats(write_timeout); - outw(command, r_uart_transmit); - } - debug(("Write commmand delayed\n")); - } else - outw(command, r_uart_transmit); -} - -static uch receive_byte(int timeout) -{ - uch ret; - cli(); - debug(("cli\n")); - ret = cd->ur[cd->ur_r]; - if (cd->ur_r != cd->ur_w) { - sti(); - debug(("returning #%d: 0x%x\n", cd->ur_r, - cd->ur[cd->ur_r])); - cd->ur_r++; - cd->ur_r %= UR_SIZE; - return ret; - } else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */ - debug(("Time out on receive-buffer\n")); -#ifdef STATISTICS - if (timeout == UART_TIMEOUT) - stats(receive_timeout) /* no `;'! */ - else - stats(dsb_timeout); -#endif - return 0xda; - } - ret = cd->ur[cd->ur_r]; - debug(("slept; returning #%d: 0x%x\n", cd->ur_r, - cd->ur[cd->ur_r])); - cd->ur_r++; - cd->ur_r %= UR_SIZE; - return ret; -} - -static inline uch receive_echo(void) -{ - return receive_byte(UART_TIMEOUT); -} - -static inline uch send_receive(int command) -{ - send_command(command); - return receive_echo(); -} - -static inline uch wait_dsb(void) -{ - return receive_byte(DSB_TIMEOUT); -} - -static int type_0_command(int command, int expect_dsb) -{ - int e; - clear_ur(); - if (command != (e = send_receive(command))) { - debug(("command 0x%x echoed as 0x%x\n", command, e)); - stats(echo); - return -1; - } - if (expect_dsb) { - cd->dsb = wait_dsb(); /* wait for command to finish */ - } - return 0; -} - -static int type_1_command(int command, int bytes, uch * status) -{ /* returns info */ - int i; - if (type_0_command(command, 0)) - return -1; - for (i = 0; i < bytes; i++) - status[i] = send_receive(c_gimme); - return 0; -} - -/* This function resets the adapter card. We'd better not do this too - * often, because it tends to generate `lost interrupts.' */ -static void reset_cm260(void) -{ - outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control); - udelay(10); /* 3.3 mu sec minimum */ - outw(dc_normal | READ_AHEAD, r_data_control); -} - -/* fsm: frame-sec-min from linear address; one of many */ -static void fsm(int lba, uch * fsm) -{ - fsm[0] = lba % 75; - lba /= 75; - lba += 2; - fsm[1] = lba % 60; - fsm[2] = lba / 60; -} - -static inline int fsm2lba(uch * fsm) -{ - return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]); -} - -static inline int f_s_m2lba(uch f, uch s, uch m) -{ - return f + 75 * (s - 2 + 60 * m); -} - -static int start_read(int start) -{ - uch read_sector[4] = { c_read_data, }; - int i, e; - - fsm(start, &read_sector[1]); - clear_ur(); - for (i = 0; i < 4; i++) - if (read_sector[i] != (e = send_receive(read_sector[i]))) { - debug(("read_sector: %x echoes %x\n", - read_sector[i], e)); - stats(echo); - if (e == 0xff) { /* this seems to happen often */ - e = receive_echo(); - debug(("Second try %x\n", e)); - if (e != read_sector[i]) - return -1; - } - } - return 0; -} - -static int stop_read(void) -{ - int e; - type_0_command(c_stop, 0); - if ((e = receive_echo()) != 0xff) { - debug(("c_stop didn't send 0xff, but 0x%x\n", e)); - stats(stop_0xff); - return -1; - } - return 0; -} - -/* This function starts to read sectors in adapter memory, the - interrupt routine should stop the read. In fact, the bottom_half - routine takes care of this. Set a flag `background' in the cd - struct to indicate the process. */ - -static int read_background(int start, int reading) -{ - if (cd->background) - return -1; /* can't do twice */ - outw(dc_normal | BACK_AHEAD, r_data_control); - if (!reading && start_read(start)) - return -2; - cd->adapter_first = cd->adapter_last = start; - cd->background = 1; /* flag a read is going on */ - return 0; -} - -#ifdef USE_INSW -#define transport_data insw -#else -/* this routine implements insw(,,). There was a time i had the - impression that there would be any difference in error-behaviour. */ -void transport_data(int port, ush * dest, int count) -{ - int i; - ush *d; - for (i = 0, d = dest; i < count; i++, d++) - *d = inw(port); -} -#endif - - -#define MAX_TRIES 100 -static int read_sector(int start) -{ - int tries = 0; - if (cd->background) { - cd->background = 0; - cd->adapter_last = -1; /* invalidate adapter memory */ - stop_read(); - } - cd->fifo_overflowed = 0; - reset_cm260(); /* empty fifo etc. */ - if (start_read(start)) - return -1; - do { - if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) { - debug(("Read timed out sector 0x%x\n", start)); - stats(read_timeout); - stop_read(); - return -3; - } - tries++; - } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES); - if (tries > 1) - debug(("Took me some tries\n")) - else - if (tries == MAX_TRIES) - debug(("MAX_TRIES tries for read sector\n")); - transport_data(r_fifo_output_buffer, cd->sector, - READ_AHEAD * RAW_SECTOR_SIZE / 2); - if (read_background(start + READ_AHEAD, 1)) - stats(read_background); - cd->sector_first = start; - cd->sector_last = start + READ_AHEAD; - stats(read_restarted); - return 0; -} - -/* The function of bottom-half is to send a stop command to the drive - This isn't easy because the routine is not `owned' by any process; - we can't go to sleep! The variable cd->background gives the status: - 0 no read pending - 1 a read is pending - 2 c_stop waits for write_buffer_empty - 3 c_stop waits for receive_buffer_full: echo - 4 c_stop waits for receive_buffer_full: 0xff -*/ - -static void cm206_tasklet_func(unsigned long ignore) -{ - debug(("bh: %d\n", cd->background)); - switch (cd->background) { - case 1: - stats(bh); - if (!(cd->intr_ls & ls_transmitter_buffer_empty)) { - cd->command = c_stop; - outw(dc_mask_sync_error | dc_no_stop_on_error | - (inw(r_data_status) & 0x7f), r_data_control); - cd->background = 2; - break; /* we'd better not time-out here! */ - } else - outw(c_stop, r_uart_transmit); - /* fall into case 2: */ - case 2: - /* the write has been satisfied by interrupt routine */ - cd->background = 3; - break; - case 3: - if (cd->ur_r != cd->ur_w) { - if (cd->ur[cd->ur_r] != c_stop) { - debug(("cm206_bh: c_stop echoed 0x%x\n", - cd->ur[cd->ur_r])); - stats(echo); - } - cd->ur_r++; - cd->ur_r %= UR_SIZE; - } - cd->background++; - break; - case 4: - if (cd->ur_r != cd->ur_w) { - if (cd->ur[cd->ur_r] != 0xff) { - debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r])); - stats(stop_0xff); - } - cd->ur_r++; - cd->ur_r %= UR_SIZE; - } - cd->background = 0; - } -} - -static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0); - -/* This command clears the dsb_possible_media_change flag, so we must - * retain it. - */ -static void get_drive_status(void) -{ - uch status[2]; - type_1_command(c_drive_status, 2, status); /* this might be done faster */ - cd->dsb = status[0]; - cd->cc = status[1]; - cd->media_changed |= - !!(cd->dsb & (dsb_possible_media_change | - dsb_drive_not_ready | dsb_tray_not_closed)); -} - -static void get_disc_status(void) -{ - if (type_1_command(c_disc_status, 7, cd->disc_status)) { - debug(("get_disc_status: error\n")); - } -} - -/* The new open. The real opening strategy is defined in cdrom.c. */ - -static int cm206_open(struct cdrom_device_info *cdi, int purpose) -{ - if (!cd->openfiles) { /* reset only first time */ - cd->background = 0; - reset_cm260(); - cd->adapter_last = -1; /* invalidate adapter memory */ - cd->sector_last = -1; - } - ++cd->openfiles; - stats(open); - return 0; -} - -static void cm206_release(struct cdrom_device_info *cdi) -{ - if (cd->openfiles == 1) { - if (cd->background) { - cd->background = 0; - stop_read(); - } - cd->sector_last = -1; /* Make our internal buffer invalid */ - FIRST_TRACK = 0; /* No valid disc status */ - } - --cd->openfiles; -} - -/* Empty buffer empties $sectors$ sectors of the adapter card buffer, - * and then reads a sector in kernel memory. */ -static void empty_buffer(int sectors) -{ - while (sectors >= 0) { - transport_data(r_fifo_output_buffer, - cd->sector + cd->fifo_overflowed, - RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed); - --sectors; - ++cd->adapter_first; /* update the current adapter sector */ - cd->fifo_overflowed = 0; /* reset overflow bit */ - stats(sector_transferred); - } - cd->sector_first = cd->adapter_first - 1; - cd->sector_last = cd->adapter_first; /* update the buffer sector */ -} - -/* try_adapter. This function determines if the requested sector is - in adapter memory, or will appear there soon. Returns 0 upon - success */ -static int try_adapter(int sector) -{ - if (cd->adapter_first <= sector && sector < cd->adapter_last) { - /* sector is in adapter memory */ - empty_buffer(sector - cd->adapter_first); - return 0; - } else if (cd->background == 1 && cd->adapter_first <= sector - && sector < cd->adapter_first + cd->max_sectors) { - /* a read is going on, we can wait for it */ - cd->wait_back = 1; - while (sector >= cd->adapter_last) { - if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) { - debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background)); - stats(back_read_timeout); - cd->wait_back = 0; - return -1; - } - } - cd->wait_back = 0; - empty_buffer(sector - cd->adapter_first); - return 0; - } else - return -2; -} - -/* This is not a very smart implementation. We could optimize for - consecutive block numbers. I'm not convinced this would really - bring down the processor load. */ -static void do_cm206_request(request_queue_t * q) -{ - long int i, cd_sec_no; - int quarter, error; - uch *source, *dest; - struct request *req; - - while (1) { /* repeat until all requests have been satisfied */ - req = elv_next_request(q); - if (!req) - return; - - if (rq_data_dir(req) != READ) { - debug(("Non-read command %d on cdrom\n", req->cmd)); - end_request(req, 0); - continue; - } - spin_unlock_irq(q->queue_lock); - error = 0; - for (i = 0; i < req->nr_sectors; i++) { - int e1, e2; - cd_sec_no = (req->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */ - quarter = (req->sector + i) % BLOCKS_ISO; - dest = req->buffer + i * LINUX_BLOCK_SIZE; - /* is already in buffer memory? */ - if (cd->sector_first <= cd_sec_no - && cd_sec_no < cd->sector_last) { - source = - ((uch *) cd->sector) + 16 + - quarter * LINUX_BLOCK_SIZE + - (cd_sec_no - - cd->sector_first) * RAW_SECTOR_SIZE; - memcpy(dest, source, LINUX_BLOCK_SIZE); - } else if (!(e1 = try_adapter(cd_sec_no)) || - !(e2 = read_sector(cd_sec_no))) { - source = - ((uch *) cd->sector) + 16 + - quarter * LINUX_BLOCK_SIZE; - memcpy(dest, source, LINUX_BLOCK_SIZE); - } else { - error = 1; - debug(("cm206_request: %d %d\n", e1, e2)); - } - } - spin_lock_irq(q->queue_lock); - end_request(req, !error); - } -} - -/* Audio support. I've tried very hard, but the cm206 drive doesn't - seem to have a get_toc (table-of-contents) function, while i'm - pretty sure it must read the toc upon disc insertion. Therefore - this function has been implemented through a binary search - strategy. All track starts that happen to be found are stored in - cd->toc[], for future use. - - I've spent a whole day on a bug that only shows under Workman--- - I don't get it. Tried everything, nothing works. If workman asks - for track# 0xaa, it'll get the wrong time back. Any other program - receives the correct value. I'm stymied. -*/ - -/* seek seeks to address lba. It does wait to arrive there. */ -static void seek(int lba) -{ - int i; - uch seek_command[4] = { c_seek, }; - - fsm(lba, &seek_command[1]); - for (i = 0; i < 4; i++) - type_0_command(seek_command[i], 0); - cd->dsb = wait_dsb(); -} - -static uch bcdbin(unsigned char bcd) -{ /* stolen from mcd.c! */ - return (bcd >> 4) * 10 + (bcd & 0xf); -} - -static inline uch normalize_track(uch track) -{ - if (track < 1) - return 1; - if (track > LAST_TRACK) - return LAST_TRACK + 1; - return track; -} - -/* This function does a binary search for track start. It records all - * tracks seen in the process. Input $track$ must be between 1 and - * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm. - */ -static int get_toc_lba(uch track) -{ - int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm); - int i, lba, l, old_lba = 0; - uch *q = cd->q; - uch ct; /* current track */ - int binary = 0; - const int skip = 3 * 60 * 75; /* 3 minutes */ - - for (i = track; i > 0; i--) - if (cd->toc[i].track) { - min = fsm2lba(cd->toc[i].fsm); - break; - } - lba = min + skip; - do { - seek(lba); - type_1_command(c_read_current_q, 10, q); - ct = normalize_track(q[1]); - if (!cd->toc[ct].track) { - l = q[9] - bcdbin(q[5]) + 75 * (q[8] - - bcdbin(q[4]) - 2 + - 60 * (q[7] - - bcdbin(q - [3]))); - cd->toc[ct].track = q[1]; /* lead out still 0xaa */ - fsm(l, cd->toc[ct].fsm); - cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */ - if (ct == track) - return l; - } - old_lba = lba; - if (binary) { - if (ct < track) - min = lba; - else - max = lba; - lba = (min + max) / 2; - } else { - if (ct < track) - lba += skip; - else { - binary = 1; - max = lba; - min = lba - skip; - lba = (min + max) / 2; - } - } - } while (lba != old_lba); - return lba; -} - -static void update_toc_entry(uch track) -{ - track = normalize_track(track); - if (!cd->toc[track].track) - get_toc_lba(track); -} - -/* return 0 upon success */ -static int read_toc_header(struct cdrom_tochdr *hp) -{ - if (!FIRST_TRACK) - get_disc_status(); - if (hp) { - int i; - hp->cdth_trk0 = FIRST_TRACK; - hp->cdth_trk1 = LAST_TRACK; - /* fill in first track position */ - for (i = 0; i < 3; i++) - cd->toc[1].fsm[i] = cd->disc_status[3 + i]; - update_toc_entry(LAST_TRACK + 1); /* find most entries */ - return 0; - } - return -1; -} - -static void play_from_to_msf(struct cdrom_msf *msfp) -{ - uch play_command[] = { c_play, - msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0, - msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, - 2 - }; - int i; - for (i = 0; i < 9; i++) - type_0_command(play_command[i], 0); - for (i = 0; i < 3; i++) - PLAY_TO.fsm[i] = play_command[i + 4]; - PLAY_TO.track = 0; /* say no track end */ - cd->dsb = wait_dsb(); -} - -static void play_from_to_track(int from, int to) -{ - uch play_command[8] = { c_play, }; - int i; - - if (from == 0) { /* continue paused play */ - for (i = 0; i < 3; i++) { - play_command[i + 1] = cd->audio_status[i + 2]; - play_command[i + 4] = PLAY_TO.fsm[i]; - } - } else { - update_toc_entry(from); - update_toc_entry(to + 1); - for (i = 0; i < 3; i++) { - play_command[i + 1] = cd->toc[from].fsm[i]; - PLAY_TO.fsm[i] = play_command[i + 4] = - cd->toc[to + 1].fsm[i]; - } - PLAY_TO.track = to; - } - for (i = 0; i < 7; i++) - type_0_command(play_command[i], 0); - for (i = 0; i < 2; i++) - type_0_command(0x2, 0); /* volume */ - cd->dsb = wait_dsb(); -} - -static int get_current_q(struct cdrom_subchnl *qp) -{ - int i; - uch *q = cd->q; - if (type_1_command(c_read_current_q, 10, q)) - return 0; -/* q[0] = bcdbin(q[0]); Don't think so! */ - for (i = 2; i < 6; i++) - q[i] = bcdbin(q[i]); - qp->cdsc_adr = q[0] & 0xf; - qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */ - qp->cdsc_trk = q[1]; - qp->cdsc_ind = q[2]; - if (qp->cdsc_format == CDROM_MSF) { - qp->cdsc_reladdr.msf.minute = q[3]; - qp->cdsc_reladdr.msf.second = q[4]; - qp->cdsc_reladdr.msf.frame = q[5]; - qp->cdsc_absaddr.msf.minute = q[7]; - qp->cdsc_absaddr.msf.second = q[8]; - qp->cdsc_absaddr.msf.frame = q[9]; - } else { - qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]); - qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]); - } - get_drive_status(); - if (cd->dsb & dsb_play_in_progress) - qp->cdsc_audiostatus = CDROM_AUDIO_PLAY; - else if (PAUSED) - qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED; - else - qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS; - return 0; -} - -static void invalidate_toc(void) -{ - memset(cd->toc, 0, sizeof(cd->toc)); - memset(cd->disc_status, 0, sizeof(cd->disc_status)); -} - -/* cdrom.c guarantees that cdte_format == CDROM_MSF */ -static void get_toc_entry(struct cdrom_tocentry *ep) -{ - uch track = normalize_track(ep->cdte_track); - update_toc_entry(track); - ep->cdte_addr.msf.frame = cd->toc[track].fsm[0]; - ep->cdte_addr.msf.second = cd->toc[track].fsm[1]; - ep->cdte_addr.msf.minute = cd->toc[track].fsm[2]; - ep->cdte_adr = cd->toc[track].q0 & 0xf; - ep->cdte_ctrl = cd->toc[track].q0 >> 4; - ep->cdte_datamode = 0; -} - -/* Audio ioctl. Ioctl commands connected to audio are in such an - * idiosyncratic i/o format, that we leave these untouched. Return 0 - * upon success. Memory checking has been done by cdrom_ioctl(), the - * calling function, as well as LBA/MSF sanitization. -*/ -static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, - void *arg) -{ - switch (cmd) { - case CDROMREADTOCHDR: - return read_toc_header((struct cdrom_tochdr *) arg); - case CDROMREADTOCENTRY: - get_toc_entry((struct cdrom_tocentry *) arg); - return 0; - case CDROMPLAYMSF: - play_from_to_msf((struct cdrom_msf *) arg); - return 0; - case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */ - play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0, - ((struct cdrom_ti *) arg)->cdti_trk1); - return 0; - case CDROMSTOP: - PAUSED = 0; - if (cd->dsb & dsb_play_in_progress) - return type_0_command(c_stop, 1); - else - return 0; - case CDROMPAUSE: - get_drive_status(); - if (cd->dsb & dsb_play_in_progress) { - type_0_command(c_stop, 1); - type_1_command(c_audio_status, 5, - cd->audio_status); - PAUSED = 1; /* say we're paused */ - } - return 0; - case CDROMRESUME: - if (PAUSED) - play_from_to_track(0, 0); - PAUSED = 0; - return 0; - case CDROMSTART: - case CDROMVOLCTRL: - return 0; - case CDROMSUBCHNL: - return get_current_q((struct cdrom_subchnl *) arg); - default: - return -EINVAL; - } -} - -static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) -{ - if (cd != NULL) { - int r; - get_drive_status(); /* ensure cd->media_changed OK */ - r = cd->media_changed; - cd->media_changed = 0; /* clear bit */ - return r; - } else - return -EIO; -} - -/* The new generic cdrom support. Routines should be concise, most of - the logic should be in cdrom.c */ - - -/* controls tray movement */ -static int cm206_tray_move(struct cdrom_device_info *cdi, int position) -{ - if (position) { /* 1: eject */ - type_0_command(c_open_tray, 1); - invalidate_toc(); - } else - type_0_command(c_close_tray, 1); /* 0: close */ - return 0; -} - -/* gives current state of the drive */ -static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr) -{ - get_drive_status(); - if (cd->dsb & dsb_tray_not_closed) - return CDS_TRAY_OPEN; - if (!(cd->dsb & dsb_disc_present)) - return CDS_NO_DISC; - if (cd->dsb & dsb_drive_not_ready) - return CDS_DRIVE_NOT_READY; - return CDS_DISC_OK; -} - -/* locks or unlocks door lock==1: lock; return 0 upon success */ -static int cm206_lock_door(struct cdrom_device_info *cdi, int lock) -{ - uch command = (lock) ? c_lock_tray : c_unlock_tray; - type_0_command(command, 1); /* wait and get dsb */ - /* the logic calculates the success, 0 means successful */ - return lock ^ ((cd->dsb & dsb_tray_locked) != 0); -} - -/* Although a session start should be in LBA format, we return it in - MSF format because it is slightly easier, and the new generic ioctl - will take care of the necessary conversion. */ -static int cm206_get_last_session(struct cdrom_device_info *cdi, - struct cdrom_multisession *mssp) -{ - if (!FIRST_TRACK) - get_disc_status(); - if (mssp != NULL) { - if (DISC_STATUS & cds_multi_session) { /* multi-session */ - mssp->addr.msf.frame = cd->disc_status[3]; - mssp->addr.msf.second = cd->disc_status[4]; - mssp->addr.msf.minute = cd->disc_status[5]; - mssp->addr_format = CDROM_MSF; - mssp->xa_flag = 1; - } else { - mssp->xa_flag = 0; - } - return 1; - } - return 0; -} - -static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) -{ - uch upc[10]; - char *ret = mcn->medium_catalog_number; - int i; - - if (type_1_command(c_read_upc, 10, upc)) - return -EIO; - for (i = 0; i < 13; i++) { - int w = i / 2 + 1, r = i % 2; - if (r) - ret[i] = 0x30 | (upc[w] & 0x0f); - else - ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f); - } - ret[13] = '\0'; - return 0; -} - -static int cm206_reset(struct cdrom_device_info *cdi) -{ - stop_read(); - reset_cm260(); - outw(dc_normal | dc_break | READ_AHEAD, r_data_control); - mdelay(1); /* 750 musec minimum */ - outw(dc_normal | READ_AHEAD, r_data_control); - cd->sector_last = -1; /* flag no data buffered */ - cd->adapter_last = -1; - invalidate_toc(); - return 0; -} - -static int cm206_select_speed(struct cdrom_device_info *cdi, int speed) -{ - int r; - switch (speed) { - case 0: - r = type_0_command(c_auto_mode, 1); - break; - case 1: - r = type_0_command(c_force_1x, 1); - break; - case 2: - r = type_0_command(c_force_2x, 1); - break; - default: - return -1; - } - if (r < 0) - return r; - else - return 1; -} - -static struct cdrom_device_ops cm206_dops = { - .open = cm206_open, - .release = cm206_release, - .drive_status = cm206_drive_status, - .media_changed = cm206_media_changed, - .tray_move = cm206_tray_move, - .lock_door = cm206_lock_door, - .select_speed = cm206_select_speed, - .get_last_session = cm206_get_last_session, - .get_mcn = cm206_get_upc, - .reset = cm206_reset, - .audio_ioctl = cm206_audio_ioctl, - .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | - CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | - CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED | - CDC_DRIVE_STATUS, - .n_minors = 1, -}; - - -static struct cdrom_device_info cm206_info = { - .ops = &cm206_dops, - .speed = 2, - .capacity = 1, - .name = "cm206", -}; - -static int cm206_block_open(struct inode *inode, struct file *file) -{ - return cdrom_open(&cm206_info, inode, file); -} - -static int cm206_block_release(struct inode *inode, struct file *file) -{ - return cdrom_release(&cm206_info, file); -} - -static int cm206_block_ioctl(struct inode *inode, struct file *file, - unsigned cmd, unsigned long arg) -{ - switch (cmd) { -#ifdef STATISTICS - case CM206CTL_GET_STAT: - if (arg >= NR_STATS) - return -EINVAL; - return cd->stats[arg]; - case CM206CTL_GET_LAST_STAT: - if (arg >= NR_STATS) - return -EINVAL; - return cd->last_stat[arg]; -#endif - default: - break; - } - - return cdrom_ioctl(file, &cm206_info, inode, cmd, arg); -} - -static int cm206_block_media_changed(struct gendisk *disk) -{ - return cdrom_media_changed(&cm206_info); -} - -static struct block_device_operations cm206_bdops = -{ - .owner = THIS_MODULE, - .open = cm206_block_open, - .release = cm206_block_release, - .ioctl = cm206_block_ioctl, - .media_changed = cm206_block_media_changed, -}; - -static struct gendisk *cm206_gendisk; - -/* This function probes for the adapter card. It returns the base - address if it has found the adapter card. One can specify a base - port to probe specifically, or 0 which means span all possible - bases. - - Linus says it is too dangerous to use writes for probing, so we - stick with pure reads for a while. Hope that 8 possible ranges, - request_region, 15 bits of one port and 6 of another make things - likely enough to accept the region on the first hit... - */ -static int __init probe_base_port(int base) -{ - int b = 0x300, e = 0x370; /* this is the range of start addresses */ - volatile int fool, i; - - if (base) - b = e = base; - for (base = b; base <= e; base += 0x10) { - if (!request_region(base, 0x10,"cm206")) - continue; - for (i = 0; i < 3; i++) - fool = inw(base + 2); /* empty possibly uart_receive_buffer */ - if ((inw(base + 6) & 0xffef) != 0x0001 || /* line_status */ - (inw(base) & 0xad00) != 0) { /* data status */ - release_region(base,0x10); - continue; - } - return (base); - } - return 0; -} - -#if !defined(MODULE) || defined(AUTO_PROBE_MODULE) -/* Probe for irq# nr. If nr==0, probe for all possible irq's. */ -static int __init probe_irq(int nr) -{ - int irqs, irq; - outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */ - sti(); - irqs = probe_irq_on(); - reset_cm260(); /* causes interrupt */ - udelay(100); /* wait for it */ - irq = probe_irq_off(irqs); - outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */ - if (nr && irq != nr && irq > 0) - return 0; /* wrong interrupt happened */ - else - return irq; -} -#endif - -int __init cm206_init(void) -{ - uch e = 0; - long int size = sizeof(struct cm206_struct); - struct gendisk *disk; - - printk(KERN_INFO "cm206 cdrom driver " REVISION); - cm206_base = probe_base_port(auto_probe ? 0 : cm206_base); - if (!cm206_base) { - printk(" can't find adapter!\n"); - return -EIO; - } - printk(" adapter at 0x%x", cm206_base); - cd = kmalloc(size, GFP_KERNEL); - if (!cd) - goto out_base; - /* Now we have found the adaptor card, try to reset it. As we have - * found out earlier, this process generates an interrupt as well, - * so we might just exploit that fact for irq probing! */ -#if !defined(MODULE) || defined(AUTO_PROBE_MODULE) - cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq); - if (cm206_irq <= 0) { - printk("can't find IRQ!\n"); - goto out_probe; - } else - printk(" IRQ %d found\n", cm206_irq); -#else - cli(); - reset_cm260(); - /* Now, the problem here is that reset_cm260 can generate an - interrupt. It seems that this can cause a kernel oops some time - later. So we wait a while and `service' this interrupt. */ - mdelay(1); - outw(dc_normal | READ_AHEAD, r_data_control); - sti(); - printk(" using IRQ %d\n", cm206_irq); -#endif - if (send_receive_polled(c_drive_configuration) != - c_drive_configuration) { - printk(KERN_INFO " drive not there\n"); - goto out_probe; - } - e = send_receive_polled(c_gimme); - printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code); - if (e & dcf_transfer_rate) - printk(" double"); - else - printk(" single"); - printk(" speed drive"); - if (e & dcf_motorized_tray) - printk(", motorized tray"); - if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) { - printk("\nUnable to reserve IRQ---aborted\n"); - goto out_probe; - } - printk(".\n"); - - if (register_blkdev(MAJOR_NR, "cm206")) - goto out_blkdev; - - disk = alloc_disk(1); - if (!disk) - goto out_disk; - disk->major = MAJOR_NR; - disk->first_minor = 0; - sprintf(disk->disk_name, "cm206cd"); - disk->fops = &cm206_bdops; - disk->flags = GENHD_FL_CD; - cm206_gendisk = disk; - if (register_cdrom(&cm206_info) != 0) { - printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR); - goto out_cdrom; - } - cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock); - if (!cm206_queue) - goto out_queue; - - blk_queue_hardsect_size(cm206_queue, 2048); - disk->queue = cm206_queue; - add_disk(disk); - - memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */ - cd->sector_last = -1; /* flag no data buffered */ - cd->adapter_last = -1; - init_timer(&cd->timer); - cd->timer.function = cm206_timeout; - cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97; - printk(KERN_INFO "%d kB adapter memory available, " - " %ld bytes kernel memory used.\n", cd->max_sectors * 2, - size); - return 0; - -out_queue: - unregister_cdrom(&cm206_info); -out_cdrom: - put_disk(disk); -out_disk: - unregister_blkdev(MAJOR_NR, "cm206"); -out_blkdev: - free_irq(cm206_irq, NULL); -out_probe: - kfree(cd); -out_base: - release_region(cm206_base, 16); - return -EIO; -} - -#ifdef MODULE - - -static void __init parse_options(void) -{ - int i; - for (i = 0; i < 2; i++) { - if (0x300 <= cm206[i] && i <= 0x370 - && cm206[i] % 0x10 == 0) { - cm206_base = cm206[i]; - auto_probe = 0; - } else if (3 <= cm206[i] && cm206[i] <= 15) { - cm206_irq = cm206[i]; - auto_probe = 0; - } - } -} - -static int __init __cm206_init(void) -{ - parse_options(); -#if !defined(AUTO_PROBE_MODULE) - auto_probe = 0; -#endif - return cm206_init(); -} - -static void __exit cm206_exit(void) -{ - del_gendisk(cm206_gendisk); - put_disk(cm206_gendisk); - if (unregister_cdrom(&cm206_info)) { - printk("Can't unregister cdrom cm206\n"); - return; - } - if (unregister_blkdev(MAJOR_NR, "cm206")) { - printk("Can't unregister major cm206\n"); - return; - } - blk_cleanup_queue(cm206_queue); - free_irq(cm206_irq, NULL); - kfree(cd); - release_region(cm206_base, 16); - printk(KERN_INFO "cm206 removed\n"); -} - -module_init(__cm206_init); -module_exit(cm206_exit); - -#else /* !MODULE */ - -/* This setup function accepts either `auto' or numbers in the range - * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */ - -static int __init cm206_setup(char *s) -{ - int i, p[4]; - - (void) get_options(s, ARRAY_SIZE(p), p); - - if (!strcmp(s, "auto")) - auto_probe = 1; - for (i = 1; i <= p[0]; i++) { - if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) { - cm206_base = p[i]; - auto_probe = 0; - } else if (3 <= p[i] && p[i] <= 15) { - cm206_irq = p[i]; - auto_probe = 0; - } - } - return 1; -} - -__setup("cm206=", cm206_setup); - -#endif /* !MODULE */ -MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR); - diff --git a/drivers/cdrom/cm206.h b/drivers/cdrom/cm206.h deleted file mode 100644 index 0ae51c1a0dac..000000000000 --- a/drivers/cdrom/cm206.h +++ /dev/null @@ -1,171 +0,0 @@ -/* cm206.h Header file for cm206.c. - Copyright (c) 1995 David van Leeuwen -*/ - -#ifndef LINUX_CM206_H -#define LINUX_CM206_H - -#include - -/* First, the cm260 stuff */ -/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined - below, the values are not used unless autoprobing is turned off and - no LILO boot options or module command line options are given. Change - these values to your own as last resort if autoprobing and options - don't work. */ - -#define CM206_BASE 0x340 -#define CM206_IRQ 11 - -#define r_data_status (cm206_base) -#define r_uart_receive (cm206_base+0x2) -#define r_fifo_output_buffer (cm206_base+0x4) -#define r_line_status (cm206_base+0x6) -#define r_data_control (cm206_base+0x8) -#define r_uart_transmit (cm206_base+0xa) -#define r_test_clock (cm206_base+0xc) -#define r_test_control (cm206_base+0xe) - -/* the data_status flags */ -#define ds_ram_size 0x4000 -#define ds_toc_ready 0x2000 -#define ds_fifo_empty 0x1000 -#define ds_sync_error 0x800 -#define ds_crc_error 0x400 -#define ds_data_error 0x200 -#define ds_fifo_overflow 0x100 -#define ds_data_ready 0x80 - -/* the line_status flags */ -#define ls_attention 0x10 -#define ls_parity_error 0x8 -#define ls_overrun 0x4 -#define ls_receive_buffer_full 0x2 -#define ls_transmitter_buffer_empty 0x1 - -/* the data control register flags */ -#define dc_read_q_channel 0x4000 -#define dc_mask_sync_error 0x2000 -#define dc_toc_enable 0x1000 -#define dc_no_stop_on_error 0x800 -#define dc_break 0x400 -#define dc_initialize 0x200 -#define dc_mask_transmit_ready 0x100 -#define dc_flag_enable 0x80 - -/* Define the default data control register flags here */ -#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \ - dc_mask_transmit_ready) - -/* now some constants related to the cm206 */ -/* another drive status byte, echoed by the cm206 on most commands */ - -#define dsb_error_condition 0x1 -#define dsb_play_in_progress 0x4 -#define dsb_possible_media_change 0x8 -#define dsb_disc_present 0x10 -#define dsb_drive_not_ready 0x20 -#define dsb_tray_locked 0x40 -#define dsb_tray_not_closed 0x80 - -#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed) - -/* the cm206 command set */ - -#define c_close_tray 0 -#define c_lock_tray 0x01 -#define c_unlock_tray 0x04 -#define c_open_tray 0x05 -#define c_seek 0x10 -#define c_read_data 0x20 -#define c_force_1x 0x21 -#define c_force_2x 0x22 -#define c_auto_mode 0x23 -#define c_play 0x30 -#define c_set_audio_mode 0x31 -#define c_read_current_q 0x41 -#define c_stream_q 0x42 -#define c_drive_status 0x50 -#define c_disc_status 0x51 -#define c_audio_status 0x52 -#define c_drive_configuration 0x53 -#define c_read_upc 0x60 -#define c_stop 0x70 -#define c_calc_checksum 0xe5 - -#define c_gimme 0xf8 - -/* finally, the (error) condition that the drive can be in * - * OK, this is not always an error, but let's prefix it with e_ */ - -#define e_none 0 -#define e_illegal_command 0x01 -#define e_sync 0x02 -#define e_seek 0x03 -#define e_parity 0x04 -#define e_focus 0x05 -#define e_header_sync 0x06 -#define e_code_incompatibility 0x07 -#define e_reset_done 0x08 -#define e_bad_parameter 0x09 -#define e_radial 0x0a -#define e_sub_code 0x0b -#define e_no_data_track 0x0c -#define e_scan 0x0d -#define e_tray_open 0x0f -#define e_no_disc 0x10 -#define e_tray stalled 0x11 - -/* drive configuration masks */ - -#define dcf_revision_code 0x7 -#define dcf_transfer_rate 0x60 -#define dcf_motorized_tray 0x80 - -/* disc status byte */ - -#define cds_multi_session 0x2 -#define cds_all_audio 0x8 -#define cds_xa_mode 0xf0 - -/* finally some ioctls for the driver */ - -#define CM206CTL_GET_STAT _IO( 0x20, 0 ) -#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 ) - -#ifdef STATISTICS - -/* This is an ugly way to guarantee that the names of the statistics - * are the same in the code and in the diagnostics program. */ - -#ifdef __KERNEL__ -#define x(a) st_ ## a -#define y enum -#else -#define x(a) #a -#define y char * stats_name[] = -#endif - -y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error), - x(crc_error), x(sync_error), x(lost_intr), x(echo), - x(write_timeout), x(receive_timeout), x(read_timeout), - x(dsb_timeout), x(stop_0xff), x(back_read_timeout), - x(sector_transferred), x(read_restarted), x(read_background), - x(bh), x(open), x(ioctl_multisession), x(attention) -#ifdef __KERNEL__ - , x(last_entry) -#endif - }; - -#ifdef __KERNEL__ -#define NR_STATS st_last_entry -#else -#define NR_STATS (sizeof(stats_name)/sizeof(char*)) -#endif - -#undef y -#undef x - -#endif /* STATISTICS */ - -#endif /* LINUX_CM206_H */ diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c deleted file mode 100644 index 176742ed007b..000000000000 --- a/drivers/cdrom/gscd.c +++ /dev/null @@ -1,1029 +0,0 @@ -#define GSCD_VERSION "0.4a Oliver Raupach " - -/* - linux/drivers/block/gscd.c - GoldStar R420 CDROM driver - - Copyright (C) 1995 Oliver Raupach - based upon pre-works by Eberhard Moenkeberg - - - For all kind of other information about the GoldStar CDROM - and this Linux device driver I installed a WWW-URL: - http://linux.rz.fh-hannover.de/~raupach - - - If you are the editor of a Linux CD, you should - enable gscd.c within your boot floppy kernel and - send me one of your CDs for free. - - - -------------------------------------------------------------------- - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - -------------------------------------------------------------------- - - 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x - Removed init_module & cleanup_module in favor of - module_init & module_exit. - Torben Mathiasen - -*/ - -/* These settings are for various debug-level. Leave they untouched ... */ -#define NO_GSCD_DEBUG -#define NO_IOCTL_DEBUG -#define NO_MODULE_DEBUG -#define NO_FUTURE_WORK -/*------------------------*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define MAJOR_NR GOLDSTAR_CDROM_MAJOR -#include -#include "gscd.h" - -static int gscdPresent = 0; - -static unsigned char gscd_buf[2048]; /* buffer for block size conversion */ -static int gscd_bn = -1; -static short gscd_port = GSCD_BASE_ADDR; -module_param_named(gscd, gscd_port, short, 0); - -/* Kommt spaeter vielleicht noch mal dran ... - * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq); - */ - -static void gscd_read_cmd(struct request *req); -static void gscd_hsg2msf(long hsg, struct msf *msf); -static void gscd_bin2bcd(unsigned char *p); - -/* Schnittstellen zum Kern/FS */ - -static void __do_gscd_request(unsigned long dummy); -static int gscd_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -static int gscd_open(struct inode *, struct file *); -static int gscd_release(struct inode *, struct file *); -static int check_gscd_med_chg(struct gendisk *disk); - -/* GoldStar Funktionen */ - -static void cmd_out(int, char *, char *, int); -static void cmd_status(void); -static void init_cd_drive(int); - -static int get_status(void); -static void clear_Audio(void); -static void cc_invalidate(void); - -/* some things for the next version */ -#ifdef FUTURE_WORK -static void update_state(void); -static long gscd_msf2hsg(struct msf *mp); -static int gscd_bcd2bin(unsigned char bcd); -#endif - - -/* lo-level cmd-Funktionen */ - -static void cmd_info_in(char *, int); -static void cmd_end(void); -static void cmd_read_b(char *, int, int); -static void cmd_read_w(char *, int, int); -static int cmd_unit_alive(void); -static void cmd_write_cmd(char *); - - -/* GoldStar Variablen */ - -static int curr_drv_state; -static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static int drv_mode; -static int disk_state; -static int speed; -static int ndrives; - -static unsigned char drv_num_read; -static unsigned char f_dsk_valid; -static unsigned char current_drive; -static unsigned char f_drv_ok; - - -static char f_AudioPlay; -static char f_AudioPause; -static int AudioStart_m; -static int AudioStart_f; -static int AudioEnd_m; -static int AudioEnd_f; - -static DEFINE_TIMER(gscd_timer, NULL, 0, 0); -static DEFINE_SPINLOCK(gscd_lock); -static struct request_queue *gscd_queue; - -static struct block_device_operations gscd_fops = { - .owner = THIS_MODULE, - .open = gscd_open, - .release = gscd_release, - .ioctl = gscd_ioctl, - .media_changed = check_gscd_med_chg, -}; - -/* - * Checking if the media has been changed - * (not yet implemented) - */ -static int check_gscd_med_chg(struct gendisk *disk) -{ -#ifdef GSCD_DEBUG - printk("gscd: check_med_change\n"); -#endif - return 0; -} - - -#ifndef MODULE -/* Using new interface for kernel-parameters */ - -static int __init gscd_setup(char *str) -{ - int ints[2]; - (void) get_options(str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) { - gscd_port = ints[1]; - } - return 1; -} - -__setup("gscd=", gscd_setup); - -#endif - -static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg) -{ - unsigned char to_do[10]; - unsigned char dummy; - - - switch (cmd) { - case CDROMSTART: /* Spin up the drive */ - /* Don't think we can do this. Even if we could, - * I think the drive times out and stops after a while - * anyway. For now, ignore it. - */ - return 0; - - case CDROMRESUME: /* keine Ahnung was das ist */ - return 0; - - - case CDROMEJECT: - cmd_status(); - to_do[0] = CMD_TRAY_CTL; - cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0); - - return 0; - - default: - return -EINVAL; - } - -} - - -/* - * Take care of the different block sizes between cdrom and Linux. - * When Linux gets variable block sizes this will probably go away. - */ - -static void gscd_transfer(struct request *req) -{ - while (req->nr_sectors > 0 && gscd_bn == req->sector / 4) { - long offs = (req->sector & 3) * 512; - memcpy(req->buffer, gscd_buf + offs, 512); - req->nr_sectors--; - req->sector++; - req->buffer += 512; - } -} - - -/* - * I/O request routine called from Linux kernel. - */ - -static void do_gscd_request(request_queue_t * q) -{ - __do_gscd_request(0); -} - -static void __do_gscd_request(unsigned long dummy) -{ - struct request *req; - unsigned int block; - unsigned int nsect; - -repeat: - req = elv_next_request(gscd_queue); - if (!req) - return; - - block = req->sector; - nsect = req->nr_sectors; - - if (req->sector == -1) - goto out; - - if (rq_data_dir(req) != READ) { - printk("GSCD: bad cmd %u\n", rq_data_dir(req)); - end_request(req, 0); - goto repeat; - } - - gscd_transfer(req); - - /* if we satisfied the request from the buffer, we're done. */ - - if (req->nr_sectors == 0) { - end_request(req, 1); - goto repeat; - } -#ifdef GSCD_DEBUG - printk("GSCD: block %d, nsect %d\n", block, nsect); -#endif - gscd_read_cmd(req); -out: - return; -} - - - -/* - * Check the result of the set-mode command. On success, send the - * read-data command. - */ - -static void gscd_read_cmd(struct request *req) -{ - long block; - struct gscd_Play_msf gscdcmd; - char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */ - - cmd_status(); - if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) { - printk("GSCD: no disk or door open\n"); - end_request(req, 0); - } else { - if (disk_state & ST_INVALID) { - printk("GSCD: disk invalid\n"); - end_request(req, 0); - } else { - gscd_bn = -1; /* purge our buffer */ - block = req->sector / 4; - gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */ - - cmd[2] = gscdcmd.start.min; - cmd[3] = gscdcmd.start.sec; - cmd[4] = gscdcmd.start.frame; - -#ifdef GSCD_DEBUG - printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], - cmd[4]); -#endif - cmd_out(TYPE_DATA, (char *) &cmd, - (char *) &gscd_buf[0], 1); - - gscd_bn = req->sector / 4; - gscd_transfer(req); - end_request(req, 1); - } - } - SET_TIMER(__do_gscd_request, 1); -} - - -/* - * Open the device special file. Check that a disk is in. - */ - -static int gscd_open(struct inode *ip, struct file *fp) -{ - int st; - -#ifdef GSCD_DEBUG - printk("GSCD: open\n"); -#endif - - if (gscdPresent == 0) - return -ENXIO; /* no hardware */ - - get_status(); - st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN); - if (st) { - printk("GSCD: no disk or door open\n"); - return -ENXIO; - } - -/* if (updateToc() < 0) - return -EIO; -*/ - - return 0; -} - - -/* - * On close, we flush all gscd blocks from the buffer cache. - */ - -static int gscd_release(struct inode *inode, struct file *file) -{ - -#ifdef GSCD_DEBUG - printk("GSCD: release\n"); -#endif - - gscd_bn = -1; - - return 0; -} - - -static int get_status(void) -{ - int status; - - cmd_status(); - status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01); - - if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) { - cc_invalidate(); - return 1; - } else { - return 0; - } -} - - -static void cc_invalidate(void) -{ - drv_num_read = 0xFF; - f_dsk_valid = 0xFF; - current_drive = 0xFF; - f_drv_ok = 0xFF; - - clear_Audio(); - -} - -static void clear_Audio(void) -{ - - f_AudioPlay = 0; - f_AudioPause = 0; - AudioStart_m = 0; - AudioStart_f = 0; - AudioEnd_m = 0; - AudioEnd_f = 0; - -} - -/* - * waiting ? - */ - -static int wait_drv_ready(void) -{ - int found, read; - - do { - found = inb(GSCDPORT(0)); - found &= 0x0f; - read = inb(GSCDPORT(0)); - read &= 0x0f; - } while (read != found); - -#ifdef GSCD_DEBUG - printk("Wait for: %d\n", read); -#endif - - return read; -} - -static void cc_Ident(char *respons) -{ - char to_do[] = { CMD_IDENT, 0, 0 }; - - cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E); - -} - -static void cc_SetSpeed(void) -{ - char to_do[] = { CMD_SETSPEED, 0, 0 }; - char dummy; - - if (speed > 0) { - to_do[1] = speed & 0x0F; - cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0); - } -} - -static void cc_Reset(void) -{ - char to_do[] = { CMD_RESET, 0 }; - char dummy; - - cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0); -} - -static void cmd_status(void) -{ - char to_do[] = { CMD_STATUS, 0 }; - char dummy; - - cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0); - -#ifdef GSCD_DEBUG - printk("GSCD: Status: %d\n", disk_state); -#endif - -} - -static void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count) -{ - int result; - - - result = wait_drv_ready(); - if (result != drv_mode) { - unsigned long test_loops = 0xFFFF; - int i, dummy; - - outb(curr_drv_state, GSCDPORT(0)); - - /* LOCLOOP_170 */ - do { - result = wait_drv_ready(); - test_loops--; - } while ((result != drv_mode) && (test_loops > 0)); - - if (result != drv_mode) { - disk_state = ST_x08 | ST_x04 | ST_INVALID; - return; - } - - /* ...and waiting */ - for (i = 1, dummy = 1; i < 0xFFFF; i++) { - dummy *= i; - } - } - - /* LOC_172 */ - /* check the unit */ - /* and wake it up */ - if (cmd_unit_alive() != 0x08) { - /* LOC_174 */ - /* game over for this unit */ - disk_state = ST_x08 | ST_x04 | ST_INVALID; - return; - } - - /* LOC_176 */ -#ifdef GSCD_DEBUG - printk("LOC_176 "); -#endif - if (drv_mode == 0x09) { - /* magic... */ - printk("GSCD: magic ...\n"); - outb(result, GSCDPORT(2)); - } - - /* write the command to the drive */ - cmd_write_cmd(cmd); - - /* LOC_178 */ - for (;;) { - result = wait_drv_ready(); - if (result != drv_mode) { - /* LOC_179 */ - if (result == 0x04) { /* Mode 4 */ - /* LOC_205 */ -#ifdef GSCD_DEBUG - printk("LOC_205 "); -#endif - disk_state = inb(GSCDPORT(2)); - - do { - result = wait_drv_ready(); - } while (result != drv_mode); - return; - - } else { - if (result == 0x06) { /* Mode 6 */ - /* LOC_181 */ -#ifdef GSCD_DEBUG - printk("LOC_181 "); -#endif - - if (cmd_type == TYPE_DATA) { - /* read data */ - /* LOC_184 */ - if (drv_mode == 9) { - /* read the data to the buffer (word) */ - - /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */ - cmd_read_w - (respo_buf, - respo_count, - CD_FRAMESIZE / - 2); - return; - } else { - /* read the data to the buffer (byte) */ - - /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */ - cmd_read_b - (respo_buf, - respo_count, - CD_FRAMESIZE); - return; - } - } else { - /* read the info to the buffer */ - cmd_info_in(respo_buf, - respo_count); - return; - } - - return; - } - } - - } else { - disk_state = ST_x08 | ST_x04 | ST_INVALID; - return; - } - } /* for (;;) */ - - -#ifdef GSCD_DEBUG - printk("\n"); -#endif -} - - -static void cmd_write_cmd(char *pstr) -{ - int i, j; - - /* LOC_177 */ -#ifdef GSCD_DEBUG - printk("LOC_177 "); -#endif - - /* calculate the number of parameter */ - j = *pstr & 0x0F; - - /* shift it out */ - for (i = 0; i < j; i++) { - outb(*pstr, GSCDPORT(2)); - pstr++; - } -} - - -static int cmd_unit_alive(void) -{ - int result; - unsigned long max_test_loops; - - - /* LOC_172 */ -#ifdef GSCD_DEBUG - printk("LOC_172 "); -#endif - - outb(curr_drv_state, GSCDPORT(0)); - max_test_loops = 0xFFFF; - - do { - result = wait_drv_ready(); - max_test_loops--; - } while ((result != 0x08) && (max_test_loops > 0)); - - return result; -} - - -static void cmd_info_in(char *pb, int count) -{ - int result; - char read; - - - /* read info */ - /* LOC_182 */ -#ifdef GSCD_DEBUG - printk("LOC_182 "); -#endif - - do { - read = inb(GSCDPORT(2)); - if (count > 0) { - *pb = read; - pb++; - count--; - } - - /* LOC_183 */ - do { - result = wait_drv_ready(); - } while (result == 0x0E); - } while (result == 6); - - cmd_end(); - return; -} - - -static void cmd_read_b(char *pb, int count, int size) -{ - int result; - int i; - - - /* LOC_188 */ - /* LOC_189 */ -#ifdef GSCD_DEBUG - printk("LOC_189 "); -#endif - - do { - do { - result = wait_drv_ready(); - } while (result != 6 || result == 0x0E); - - if (result != 6) { - cmd_end(); - return; - } -#ifdef GSCD_DEBUG - printk("LOC_191 "); -#endif - - for (i = 0; i < size; i++) { - *pb = inb(GSCDPORT(2)); - pb++; - } - count--; - } while (count > 0); - - cmd_end(); - return; -} - - -static void cmd_end(void) -{ - int result; - - - /* LOC_204 */ -#ifdef GSCD_DEBUG - printk("LOC_204 "); -#endif - - do { - result = wait_drv_ready(); - if (result == drv_mode) { - return; - } - } while (result != 4); - - /* LOC_205 */ -#ifdef GSCD_DEBUG - printk("LOC_205 "); -#endif - - disk_state = inb(GSCDPORT(2)); - - do { - result = wait_drv_ready(); - } while (result != drv_mode); - return; - -} - - -static void cmd_read_w(char *pb, int count, int size) -{ - int result; - int i; - - -#ifdef GSCD_DEBUG - printk("LOC_185 "); -#endif - - do { - /* LOC_185 */ - do { - result = wait_drv_ready(); - } while (result != 6 || result == 0x0E); - - if (result != 6) { - cmd_end(); - return; - } - - for (i = 0; i < size; i++) { - /* na, hier muss ich noch mal drueber nachdenken */ - *pb = inw(GSCDPORT(2)); - pb++; - } - count--; - } while (count > 0); - - cmd_end(); - return; -} - -static int __init find_drives(void) -{ - int *pdrv; - int drvnum; - int subdrv; - int i; - - speed = 0; - pdrv = (int *) &drv_states; - curr_drv_state = 0xFE; - subdrv = 0; - drvnum = 0; - - for (i = 0; i < 8; i++) { - subdrv++; - cmd_status(); - disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01; - if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) { - /* LOC_240 */ - *pdrv = curr_drv_state; - init_cd_drive(drvnum); - pdrv++; - drvnum++; - } else { - if (subdrv < 2) { - continue; - } else { - subdrv = 0; - } - } - -/* curr_drv_state<<1; <-- das geht irgendwie nicht */ -/* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */ - curr_drv_state *= 2; - curr_drv_state |= 1; -#ifdef GSCD_DEBUG - printk("DriveState: %d\n", curr_drv_state); -#endif - } - - ndrives = drvnum; - return drvnum; -} - -static void __init init_cd_drive(int num) -{ - char resp[50]; - int i; - - printk("GSCD: init unit %d\n", num); - cc_Ident((char *) &resp); - - printk("GSCD: identification: "); - for (i = 0; i < 0x1E; i++) { - printk("%c", resp[i]); - } - printk("\n"); - - cc_SetSpeed(); - -} - -#ifdef FUTURE_WORK -/* return_done */ -static void update_state(void) -{ - unsigned int AX; - - - if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) { - if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) { - AX = ST_INVALID; - } - - if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) - == 0) { - invalidate(); - f_drv_ok = 0; - } - - AX |= 0x8000; - } - - if (disk_state & ST_PLAYING) { - AX |= 0x200; - } - - AX |= 0x100; - /* pkt_esbx = AX; */ - - disk_state = 0; - -} -#endif - -static struct gendisk *gscd_disk; - -static void __exit gscd_exit(void) -{ - CLEAR_TIMER; - - del_gendisk(gscd_disk); - put_disk(gscd_disk); - if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) { - printk("What's that: can't unregister GoldStar-module\n"); - return; - } - blk_cleanup_queue(gscd_queue); - release_region(gscd_port, GSCD_IO_EXTENT); - printk(KERN_INFO "GoldStar-module released.\n"); -} - -/* This is the common initialisation for the GoldStar drive. */ -/* It is called at boot time AND for module init. */ -static int __init gscd_init(void) -{ - int i; - int result; - int ret=0; - - printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION); - printk(KERN_INFO - "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", - gscd_port); - - if (!request_region(gscd_port, GSCD_IO_EXTENT, "gscd")) { - printk(KERN_WARNING "GSCD: Init failed, I/O port (%X) already" - " in use.\n", gscd_port); - return -EIO; - } - - - /* check for card */ - result = wait_drv_ready(); - if (result == 0x09) { - printk(KERN_WARNING "GSCD: DMA kann ich noch nicht!\n"); - ret = -EIO; - goto err_out1; - } - - if (result == 0x0b) { - drv_mode = result; - i = find_drives(); - if (i == 0) { - printk(KERN_WARNING "GSCD: GoldStar CD-ROM Drive is" - " not found.\n"); - ret = -EIO; - goto err_out1; - } - } - - if ((result != 0x0b) && (result != 0x09)) { - printk(KERN_WARNING "GSCD: GoldStar Interface Adapter does not " - "exist or H/W error\n"); - ret = -EIO; - goto err_out1; - } - - /* reset all drives */ - i = 0; - while (drv_states[i] != 0) { - curr_drv_state = drv_states[i]; - printk(KERN_INFO "GSCD: Reset unit %d ... ", i); - cc_Reset(); - printk("done\n"); - i++; - } - - gscd_disk = alloc_disk(1); - if (!gscd_disk) - goto err_out1; - gscd_disk->major = MAJOR_NR; - gscd_disk->first_minor = 0; - gscd_disk->fops = &gscd_fops; - sprintf(gscd_disk->disk_name, "gscd"); - - if (register_blkdev(MAJOR_NR, "gscd")) { - ret = -EIO; - goto err_out2; - } - - gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock); - if (!gscd_queue) { - ret = -ENOMEM; - goto err_out3; - } - - disk_state = 0; - gscdPresent = 1; - - gscd_disk->queue = gscd_queue; - add_disk(gscd_disk); - - printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n"); - return 0; - -err_out3: - unregister_blkdev(MAJOR_NR, "gscd"); -err_out2: - put_disk(gscd_disk); -err_out1: - release_region(gscd_port, GSCD_IO_EXTENT); - return ret; -} - -static void gscd_hsg2msf(long hsg, struct msf *msf) -{ - hsg += CD_MSF_OFFSET; - msf->min = hsg / (CD_FRAMES * CD_SECS); - hsg %= CD_FRAMES * CD_SECS; - msf->sec = hsg / CD_FRAMES; - msf->frame = hsg % CD_FRAMES; - - gscd_bin2bcd(&msf->min); /* convert to BCD */ - gscd_bin2bcd(&msf->sec); - gscd_bin2bcd(&msf->frame); -} - - -static void gscd_bin2bcd(unsigned char *p) -{ - int u, t; - - u = *p % 10; - t = *p / 10; - *p = u | (t << 4); -} - - -#ifdef FUTURE_WORK -static long gscd_msf2hsg(struct msf *mp) -{ - return gscd_bcd2bin(mp->frame) - + gscd_bcd2bin(mp->sec) * CD_FRAMES - + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET; -} - -static int gscd_bcd2bin(unsigned char bcd) -{ - return (bcd >> 4) * 10 + (bcd & 0xF); -} -#endif - -MODULE_AUTHOR("Oliver Raupach "); -MODULE_LICENSE("GPL"); -module_init(gscd_init); -module_exit(gscd_exit); -MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR); diff --git a/drivers/cdrom/gscd.h b/drivers/cdrom/gscd.h deleted file mode 100644 index a41e64bfc061..000000000000 --- a/drivers/cdrom/gscd.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Definitions for a GoldStar R420 CD-ROM interface - * - * Copyright (C) 1995 Oliver Raupach - * Eberhard Moenkeberg - * - * Published under the GPL. - * - */ - - -/* The Interface Card default address is 0x340. This will work for most - applications. Address selection is accomplished by jumpers PN801-1 to - PN801-4 on the GoldStar Interface Card. - Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360 - 0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0 */ - -/* insert here the I/O port address and extent */ -#define GSCD_BASE_ADDR 0x340 -#define GSCD_IO_EXTENT 4 - - -/************** nothing to set up below here *********************/ - -/* port access macro */ -#define GSCDPORT(x) (gscd_port + (x)) - -/* - * commands - * the lower nibble holds the command length - */ -#define CMD_STATUS 0x01 -#define CMD_READSUBQ 0x02 /* 1: ?, 2: UPC, 5: ? */ -#define CMD_SEEK 0x05 /* read_mode M-S-F */ -#define CMD_READ 0x07 /* read_mode M-S-F nsec_h nsec_l */ -#define CMD_RESET 0x11 -#define CMD_SETMODE 0x15 -#define CMD_PLAY 0x17 /* M-S-F M-S-F */ -#define CMD_LOCK_CTL 0x22 /* 0: unlock, 1: lock */ -#define CMD_IDENT 0x31 -#define CMD_SETSPEED 0x32 /* 0: auto */ /* ??? */ -#define CMD_GETMODE 0x41 -#define CMD_PAUSE 0x51 -#define CMD_READTOC 0x61 -#define CMD_DISKINFO 0x71 -#define CMD_TRAY_CTL 0x81 - -/* - * disk_state: - */ -#define ST_PLAYING 0x80 -#define ST_UNLOCKED 0x40 -#define ST_NO_DISK 0x20 -#define ST_DOOR_OPEN 0x10 -#define ST_x08 0x08 -#define ST_x04 0x04 -#define ST_INVALID 0x02 -#define ST_x01 0x01 - -/* - * cmd_type: - */ -#define TYPE_INFO 0x01 -#define TYPE_DATA 0x02 - -/* - * read_mode: - */ -#define MOD_POLLED 0x80 -#define MOD_x08 0x08 -#define MOD_RAW 0x04 - -#define READ_DATA(port, buf, nr) insb(port, buf, nr) - -#define SET_TIMER(func, jifs) \ - ((mod_timer(&gscd_timer, jiffies + jifs)), \ - (gscd_timer.function = func)) - -#define CLEAR_TIMER del_timer_sync(&gscd_timer) - -#define MAX_TRACKS 104 - -struct msf { - unsigned char min; - unsigned char sec; - unsigned char frame; -}; - -struct gscd_Play_msf { - struct msf start; - struct msf end; -}; - -struct gscd_DiskInfo { - unsigned char first; - unsigned char last; - struct msf diskLength; - struct msf firstTrack; -}; - -struct gscd_Toc { - unsigned char ctrl_addr; - unsigned char track; - unsigned char pointIndex; - struct msf trackTime; - struct msf diskTime; -}; - diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c deleted file mode 100644 index db0fd9a240e3..000000000000 --- a/drivers/cdrom/isp16.c +++ /dev/null @@ -1,374 +0,0 @@ -/* -- ISP16 cdrom detection and configuration - * - * Copyright (c) 1995,1996 Eric van der Maarel - * - * Version 0.6 - * - * History: - * 0.5 First release. - * Was included in the sjcd and optcd cdrom drivers. - * 0.6 First "stand-alone" version. - * Removed sound configuration. - * Added "module" support. - * - * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - * - * 19 June 2004 -- check_region() converted to request_region() - * and return statement cleanups. - * - Jesper Juhl - * - * Detect cdrom interface on ISP16 sound card. - * Configure cdrom interface. - * - * Algorithm for the card with OPTi 82C928 taken - * from the CDSETUP.SYS driver for MSDOS, - * by OPTi Computers, version 2.03. - * Algorithm for the card with OPTi 82C929 as communicated - * to me by Vadim Model and Leo Spiekman. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#define ISP16_VERSION_MAJOR 0 -#define ISP16_VERSION_MINOR 6 - -#include - -#include -#include -#include -#include -#include -#include -#include "isp16.h" - -static short isp16_detect(void); -static short isp16_c928__detect(void); -static short isp16_c929__detect(void); -static short isp16_cdi_config(int base, u_char drive_type, int irq, - int dma); -static short isp16_type; /* dependent on type of interface card */ -static u_char isp16_ctrl; -static u_short isp16_enable_port; - -static int isp16_cdrom_base = ISP16_CDROM_IO_BASE; -static int isp16_cdrom_irq = ISP16_CDROM_IRQ; -static int isp16_cdrom_dma = ISP16_CDROM_DMA; -static char *isp16_cdrom_type = ISP16_CDROM_TYPE; - -module_param(isp16_cdrom_base, int, 0); -module_param(isp16_cdrom_irq, int, 0); -module_param(isp16_cdrom_dma, int, 0); -module_param(isp16_cdrom_type, charp, 0); - -#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p)) -#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p)) - -#ifndef MODULE - -static int -__init isp16_setup(char *str) -{ - int ints[4]; - - (void) get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] > 0) - isp16_cdrom_base = ints[1]; - if (ints[0] > 1) - isp16_cdrom_irq = ints[2]; - if (ints[0] > 2) - isp16_cdrom_dma = ints[3]; - if (str) - isp16_cdrom_type = str; - - return 1; -} - -__setup("isp16=", isp16_setup); - -#endif /* MODULE */ - -/* - * ISP16 initialisation. - * - */ -static int __init isp16_init(void) -{ - u_char expected_drive; - - printk(KERN_INFO - "ISP16: configuration cdrom interface, version %d.%d.\n", - ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR); - - if (!strcmp(isp16_cdrom_type, "noisp16")) { - printk("ISP16: no cdrom interface configured.\n"); - return 0; - } - - if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) { - printk("ISP16: i/o ports already in use.\n"); - goto out; - } - - if ((isp16_type = isp16_detect()) < 0) { - printk("ISP16: no cdrom interface found.\n"); - goto cleanup_out; - } - - printk(KERN_INFO - "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n", - (isp16_type == 2) ? 9 : 8); - - if (!strcmp(isp16_cdrom_type, "Sanyo")) - expected_drive = - (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0); - else if (!strcmp(isp16_cdrom_type, "Sony")) - expected_drive = ISP16_SONY; - else if (!strcmp(isp16_cdrom_type, "Panasonic")) - expected_drive = - (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0); - else if (!strcmp(isp16_cdrom_type, "Mitsumi")) - expected_drive = ISP16_MITSUMI; - else { - printk("ISP16: %s not supported by cdrom interface.\n", - isp16_cdrom_type); - goto cleanup_out; - } - - if (isp16_cdi_config(isp16_cdrom_base, expected_drive, - isp16_cdrom_irq, isp16_cdrom_dma) < 0) { - printk - ("ISP16: cdrom interface has not been properly configured.\n"); - goto cleanup_out; - } - printk(KERN_INFO - "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d," - " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq, - isp16_cdrom_dma, isp16_cdrom_type); - return 0; - -cleanup_out: - release_region(ISP16_IO_BASE, ISP16_IO_SIZE); -out: - return -EIO; -} - -static short __init isp16_detect(void) -{ - - if (isp16_c929__detect() >= 0) - return 2; - else - return (isp16_c928__detect()); -} - -static short __init isp16_c928__detect(void) -{ - u_char ctrl; - u_char enable_cdrom; - u_char io; - short i = -1; - - isp16_ctrl = ISP16_C928__CTRL; - isp16_enable_port = ISP16_C928__ENABLE_PORT; - - /* read' and write' are a special read and write, respectively */ - - /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */ - ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC; - ISP16_OUT(ISP16_CTRL_PORT, ctrl); - - /* read' 3,4 and 5-bit from the cdrom enable port */ - enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38; - - if (!(enable_cdrom & 0x20)) { /* 5-bit not set */ - /* read' last 2 bits of ISP16_IO_SET_PORT */ - io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03; - if (((io & 0x01) << 1) == (io & 0x02)) { /* bits are the same */ - if (io == 0) { /* ...the same and 0 */ - i = 0; - enable_cdrom |= 0x20; - } else { /* ...the same and 1 *//* my card, first time 'round */ - i = 1; - enable_cdrom |= 0x28; - } - ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom); - } else { /* bits are not the same */ - ISP16_OUT(ISP16_CTRL_PORT, ctrl); - return i; /* -> not detected: possibly incorrect conclusion */ - } - } else if (enable_cdrom == 0x20) - i = 0; - else if (enable_cdrom == 0x28) /* my card, already initialised */ - i = 1; - - ISP16_OUT(ISP16_CTRL_PORT, ctrl); - - return i; -} - -static short __init isp16_c929__detect(void) -{ - u_char ctrl; - u_char tmp; - - isp16_ctrl = ISP16_C929__CTRL; - isp16_enable_port = ISP16_C929__ENABLE_PORT; - - /* read' and write' are a special read and write, respectively */ - - /* read' ISP16_CTRL_PORT and save */ - ctrl = ISP16_IN(ISP16_CTRL_PORT); - - /* write' zero to the ctrl port and get response */ - ISP16_OUT(ISP16_CTRL_PORT, 0); - tmp = ISP16_IN(ISP16_CTRL_PORT); - - if (tmp != 2) /* isp16 with 82C929 not detected */ - return -1; - - /* restore ctrl port value */ - ISP16_OUT(ISP16_CTRL_PORT, ctrl); - - return 2; -} - -static short __init -isp16_cdi_config(int base, u_char drive_type, int irq, int dma) -{ - u_char base_code; - u_char irq_code; - u_char dma_code; - u_char i; - - if ((drive_type == ISP16_MITSUMI) && (dma != 0)) - printk("ISP16: Mitsumi cdrom drive has no dma support.\n"); - - switch (base) { - case 0x340: - base_code = ISP16_BASE_340; - break; - case 0x330: - base_code = ISP16_BASE_330; - break; - case 0x360: - base_code = ISP16_BASE_360; - break; - case 0x320: - base_code = ISP16_BASE_320; - break; - default: - printk - ("ISP16: base address 0x%03X not supported by cdrom interface.\n", - base); - return -1; - } - switch (irq) { - case 0: - irq_code = ISP16_IRQ_X; - break; /* disable irq */ - case 5: - irq_code = ISP16_IRQ_5; - printk("ISP16: irq 5 shouldn't be used by cdrom interface," - " due to possible conflicts with the sound card.\n"); - break; - case 7: - irq_code = ISP16_IRQ_7; - printk("ISP16: irq 7 shouldn't be used by cdrom interface," - " due to possible conflicts with the sound card.\n"); - break; - case 3: - irq_code = ISP16_IRQ_3; - break; - case 9: - irq_code = ISP16_IRQ_9; - break; - case 10: - irq_code = ISP16_IRQ_10; - break; - case 11: - irq_code = ISP16_IRQ_11; - break; - default: - printk("ISP16: irq %d not supported by cdrom interface.\n", - irq); - return -1; - } - switch (dma) { - case 0: - dma_code = ISP16_DMA_X; - break; /* disable dma */ - case 1: - printk("ISP16: dma 1 cannot be used by cdrom interface," - " due to conflict with the sound card.\n"); - return -1; - break; - case 3: - dma_code = ISP16_DMA_3; - break; - case 5: - dma_code = ISP16_DMA_5; - break; - case 6: - dma_code = ISP16_DMA_6; - break; - case 7: - dma_code = ISP16_DMA_7; - break; - default: - printk("ISP16: dma %d not supported by cdrom interface.\n", - dma); - return -1; - } - - if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 && - drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 && - drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI && - drive_type != ISP16_DRIVE_X) { - printk - ("ISP16: drive type (code 0x%02X) not supported by cdrom" - " interface.\n", drive_type); - return -1; - } - - /* set type of interface */ - i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */ - ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type); - - /* enable cdrom on interface with 82C929 chip */ - if (isp16_type > 1) - ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM); - - /* set base address, irq and dma */ - i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */ - ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code); - - return 0; -} - -static void __exit isp16_exit(void) -{ - release_region(ISP16_IO_BASE, ISP16_IO_SIZE); - printk(KERN_INFO "ISP16: module released.\n"); -} - -module_init(isp16_init); -module_exit(isp16_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h deleted file mode 100644 index 5bd22c8f7a96..000000000000 --- a/drivers/cdrom/isp16.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -- isp16.h - * - * Header for detection and initialisation of cdrom interface (only) on - * ISP16 (MAD16, Mozart) sound card. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* These are the default values */ -#define ISP16_CDROM_TYPE "Sanyo" -#define ISP16_CDROM_IO_BASE 0x340 -#define ISP16_CDROM_IRQ 0 -#define ISP16_CDROM_DMA 0 - -/* Some (Media)Magic */ -/* define types of drive the interface on an ISP16 card may be looking at */ -#define ISP16_DRIVE_X 0x00 -#define ISP16_SONY 0x02 -#define ISP16_PANASONIC0 0x02 -#define ISP16_SANYO0 0x02 -#define ISP16_MITSUMI 0x04 -#define ISP16_PANASONIC1 0x06 -#define ISP16_SANYO1 0x06 -#define ISP16_DRIVE_NOT_USED 0x08 /* not used */ -#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/ -/* ...for port */ -#define ISP16_DRIVE_SET_PORT 0xF8D -/* set io parameters */ -#define ISP16_BASE_340 0x00 -#define ISP16_BASE_330 0x40 -#define ISP16_BASE_360 0x80 -#define ISP16_BASE_320 0xC0 -#define ISP16_IRQ_X 0x00 -#define ISP16_IRQ_5 0x04 /* shouldn't be used to avoid sound card conflicts */ -#define ISP16_IRQ_7 0x08 /* shouldn't be used to avoid sound card conflicts */ -#define ISP16_IRQ_3 0x0C -#define ISP16_IRQ_9 0x10 -#define ISP16_IRQ_10 0x14 -#define ISP16_IRQ_11 0x18 -#define ISP16_DMA_X 0x03 -#define ISP16_DMA_3 0x00 -#define ISP16_DMA_5 0x00 -#define ISP16_DMA_6 0x01 -#define ISP16_DMA_7 0x02 -#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */ -/* ...for port */ -#define ISP16_IO_SET_PORT 0xF8E -/* enable the card */ -#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */ -#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */ -#define ISP16_ENABLE_CDROM 0x80 /* seven bit */ - -/* the magic stuff */ -#define ISP16_CTRL_PORT 0xF8F -#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */ -#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */ - -#define ISP16_IO_BASE 0xF8D -#define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */ diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c deleted file mode 100644 index 972ee9c8247c..000000000000 --- a/drivers/cdrom/mcdx.c +++ /dev/null @@ -1,1943 +0,0 @@ -/* - * The Mitsumi CDROM interface - * Copyright (C) 1995 1996 Heiko Schlittermann - * VERSION: 2.14(hs) - * - * ... anyway, I'm back again, thanks to Marcin, he adopted - * large portions of my code (at least the parts containing - * my main thoughts ...) - * - ****************** H E L P ********************************* - * If you ever plan to update your CD ROM drive and perhaps - * want to sell or simply give away your Mitsumi FX-001[DS] - * -- Please -- - * mail me (heiko@lotte.sax.de). When my last drive goes - * ballistic no more driver support will be available from me! - ************************************************************* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Thanks to - * The Linux Community at all and ... - * Martin Harriss (he wrote the first Mitsumi Driver) - * Eberhard Moenkeberg (he gave me much support and the initial kick) - * Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they - * improved the original driver) - * Jon Tombs, Bjorn Ekwall (module support) - * Daniel v. Mosnenck (he sent me the Technical and Programming Reference) - * Gerd Knorr (he lent me his PhotoCD) - * Nils Faerber and Roger E. Wolff (extensively tested the LU portion) - * Andreas Kies (testing the mysterious hang-ups) - * Heiko Eissfeldt (VERIFY_READ/WRITE) - * Marcin Dalecki (improved performance, shortened code) - * ... somebody forgotten? - * - * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - */ - - -#ifdef RCS -static const char *mcdx_c_version - = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $"; -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#define MAJOR_NR MITSUMI_X_CDROM_MAJOR -#include - -#include "mcdx.h" - -#ifndef HZ -#error HZ not defined -#endif - -#define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args) - -#if !MCDX_QUIET -#define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args) -#else -#define xinfo(fmt, args...) { ; } -#endif - -#if MCDX_DEBUG -#define xtrace(lvl, fmt, args...) \ - { if (lvl > 0) \ - { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } } -#define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args) -#else -#define xtrace(lvl, fmt, args...) { ; } -#define xdebug(fmt, args...) { ; } -#endif - -/* CONSTANTS *******************************************************/ - -/* Following are the number of sectors we _request_ from the drive - every time an access outside the already requested range is done. - The _direct_ size is the number of sectors we're allowed to skip - directly (performing a read instead of requesting the new sector - needed */ -static const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */ -static const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */ - -enum drivemodes { TOC, DATA, RAW, COOKED }; -enum datamodes { MODE0, MODE1, MODE2 }; -enum resetmodes { SOFT, HARD }; - -static const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */ -static const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */ -static const int DOOR = 0x04; /* door locking capability */ -static const int MULTI = 0x08; /* multi session capability */ - -static const unsigned char READ1X = 0xc0; -static const unsigned char READ2X = 0xc1; - - -/* DECLARATIONS ****************************************************/ -struct s_subqcode { - unsigned char control; - unsigned char tno; - unsigned char index; - struct cdrom_msf0 tt; - struct cdrom_msf0 dt; -}; - -struct s_diskinfo { - unsigned int n_first; - unsigned int n_last; - struct cdrom_msf0 msf_leadout; - struct cdrom_msf0 msf_first; -}; - -struct s_multi { - unsigned char multi; - struct cdrom_msf0 msf_last; -}; - -struct s_version { - unsigned char code; - unsigned char ver; -}; - -/* Per drive/controller stuff **************************************/ - -struct s_drive_stuff { - /* waitqueues */ - wait_queue_head_t busyq; - wait_queue_head_t lockq; - wait_queue_head_t sleepq; - - /* flags */ - volatile int introk; /* status of last irq operation */ - volatile int busy; /* drive performs an operation */ - volatile int lock; /* exclusive usage */ - - /* cd infos */ - struct s_diskinfo di; - struct s_multi multi; - struct s_subqcode *toc; /* first entry of the toc array */ - struct s_subqcode start; - struct s_subqcode stop; - int xa; /* 1 if xa disk */ - int audio; /* 1 if audio disk */ - int audiostatus; - - /* `buffer' control */ - volatile int valid; /* pending, ..., values are valid */ - volatile int pending; /* next sector to be read */ - volatile int low_border; /* first sector not to be skipped direct */ - volatile int high_border; /* first sector `out of area' */ -#ifdef AK2 - volatile int int_err; -#endif /* AK2 */ - - /* adds and odds */ - unsigned wreg_data; /* w data */ - unsigned wreg_reset; /* w hardware reset */ - unsigned wreg_hcon; /* w hardware conf */ - unsigned wreg_chn; /* w channel */ - unsigned rreg_data; /* r data */ - unsigned rreg_status; /* r status */ - - int irq; /* irq used by this drive */ - int present; /* drive present and its capabilities */ - unsigned char readcmd; /* read cmd depends on single/double speed */ - unsigned char playcmd; /* play should always be single speed */ - unsigned int xxx; /* set if changed, reset while open */ - unsigned int yyy; /* set if changed, reset by media_changed */ - int users; /* keeps track of open/close */ - int lastsector; /* last block accessible */ - int status; /* last operation's error / status */ - int readerrs; /* # of blocks read w/o error */ - struct cdrom_device_info info; - struct gendisk *disk; -}; - - -/* Prototypes ******************************************************/ - -/* The following prototypes are already declared elsewhere. They are - repeated here to show what's going on. And to sense, if they're - changed elsewhere. */ - -static int mcdx_init(void); - -static int mcdx_block_open(struct inode *inode, struct file *file) -{ - struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data; - return cdrom_open(&p->info, inode, file); -} - -static int mcdx_block_release(struct inode *inode, struct file *file) -{ - struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data; - return cdrom_release(&p->info, file); -} - -static int mcdx_block_ioctl(struct inode *inode, struct file *file, - unsigned cmd, unsigned long arg) -{ - struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(file, &p->info, inode, cmd, arg); -} - -static int mcdx_block_media_changed(struct gendisk *disk) -{ - struct s_drive_stuff *p = disk->private_data; - return cdrom_media_changed(&p->info); -} - -static struct block_device_operations mcdx_bdops = -{ - .owner = THIS_MODULE, - .open = mcdx_block_open, - .release = mcdx_block_release, - .ioctl = mcdx_block_ioctl, - .media_changed = mcdx_block_media_changed, -}; - - -/* Indirect exported functions. These functions are exported by their - addresses, such as mcdx_open and mcdx_close in the - structure mcdx_dops. */ - -/* exported by file_ops */ -static int mcdx_open(struct cdrom_device_info *cdi, int purpose); -static void mcdx_close(struct cdrom_device_info *cdi); -static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr); -static int mcdx_tray_move(struct cdrom_device_info *cdi, int position); -static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock); -static int mcdx_audio_ioctl(struct cdrom_device_info *cdi, - unsigned int cmd, void *arg); - -/* misc internal support functions */ -static void log2msf(unsigned int, struct cdrom_msf0 *); -static unsigned int msf2log(const struct cdrom_msf0 *); -static unsigned int uint2bcd(unsigned int); -static unsigned int bcd2uint(unsigned char); -static unsigned port(int *); -static int irq(int *); -static void mcdx_delay(struct s_drive_stuff *, long jifs); -static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector, - int nr_sectors); -static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector, - int nr_sectors); - -static int mcdx_config(struct s_drive_stuff *, int); -static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *, - int); -static int mcdx_stop(struct s_drive_stuff *, int); -static int mcdx_hold(struct s_drive_stuff *, int); -static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int); -static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int); -static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int); -static int mcdx_requestsubqcode(struct s_drive_stuff *, - struct s_subqcode *, int); -static int mcdx_requestmultidiskinfo(struct s_drive_stuff *, - struct s_multi *, int); -static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *, - int); -static int mcdx_getstatus(struct s_drive_stuff *, int); -static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *); -static int mcdx_talk(struct s_drive_stuff *, - const unsigned char *cmd, size_t, - void *buffer, size_t size, unsigned int timeout, int); -static int mcdx_readtoc(struct s_drive_stuff *); -static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *); -static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *); -static int mcdx_setattentuator(struct s_drive_stuff *, - struct cdrom_volctrl *, int); - -/* static variables ************************************************/ - -static int mcdx_drive_map[][2] = MCDX_DRIVEMAP; -static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES]; -static DEFINE_SPINLOCK(mcdx_lock); -static struct request_queue *mcdx_queue; - -/* You can only set the first two pairs, from old MODULE_PARM code. */ -static int mcdx_set(const char *val, struct kernel_param *kp) -{ - get_options((char *)val, 4, (int *)mcdx_drive_map); - return 0; -} -module_param_call(mcdx, mcdx_set, NULL, NULL, 0); - -static struct cdrom_device_ops mcdx_dops = { - .open = mcdx_open, - .release = mcdx_close, - .media_changed = mcdx_media_changed, - .tray_move = mcdx_tray_move, - .lock_door = mcdx_lockdoor, - .audio_ioctl = mcdx_audio_ioctl, - .capability = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED | - CDC_PLAY_AUDIO | CDC_DRIVE_STATUS, -}; - -/* KERNEL INTERFACE FUNCTIONS **************************************/ - - -static int mcdx_audio_ioctl(struct cdrom_device_info *cdi, - unsigned int cmd, void *arg) -{ - struct s_drive_stuff *stuffp = cdi->handle; - - if (!stuffp->present) - return -ENXIO; - - if (stuffp->xxx) { - if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) { - stuffp->lastsector = -1; - } else { - stuffp->lastsector = (CD_FRAMESIZE / 512) - * msf2log(&stuffp->di.msf_leadout) - 1; - } - - if (stuffp->toc) { - kfree(stuffp->toc); - stuffp->toc = NULL; - if (-1 == mcdx_readtoc(stuffp)) - return -1; - } - - stuffp->xxx = 0; - } - - switch (cmd) { - case CDROMSTART:{ - xtrace(IOCTL, "ioctl() START\n"); - /* Spin up the drive. Don't think we can do this. - * For now, ignore it. - */ - return 0; - } - - case CDROMSTOP:{ - xtrace(IOCTL, "ioctl() STOP\n"); - stuffp->audiostatus = CDROM_AUDIO_INVALID; - if (-1 == mcdx_stop(stuffp, 1)) - return -EIO; - return 0; - } - - case CDROMPLAYTRKIND:{ - struct cdrom_ti *ti = (struct cdrom_ti *) arg; - - xtrace(IOCTL, "ioctl() PLAYTRKIND\n"); - if ((ti->cdti_trk0 < stuffp->di.n_first) - || (ti->cdti_trk0 > stuffp->di.n_last) - || (ti->cdti_trk1 < stuffp->di.n_first)) - return -EINVAL; - if (ti->cdti_trk1 > stuffp->di.n_last) - ti->cdti_trk1 = stuffp->di.n_last; - xtrace(PLAYTRK, "ioctl() track %d to %d\n", - ti->cdti_trk0, ti->cdti_trk1); - return mcdx_playtrk(stuffp, ti); - } - - case CDROMPLAYMSF:{ - struct cdrom_msf *msf = (struct cdrom_msf *) arg; - - xtrace(IOCTL, "ioctl() PLAYMSF\n"); - - if ((stuffp->audiostatus == CDROM_AUDIO_PLAY) - && (-1 == mcdx_hold(stuffp, 1))) - return -EIO; - - msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0); - msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0); - msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0); - - msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1); - msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1); - msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1); - - stuffp->stop.dt.minute = msf->cdmsf_min1; - stuffp->stop.dt.second = msf->cdmsf_sec1; - stuffp->stop.dt.frame = msf->cdmsf_frame1; - - return mcdx_playmsf(stuffp, msf); - } - - case CDROMRESUME:{ - xtrace(IOCTL, "ioctl() RESUME\n"); - return mcdx_playtrk(stuffp, NULL); - } - - case CDROMREADTOCENTRY:{ - struct cdrom_tocentry *entry = - (struct cdrom_tocentry *) arg; - struct s_subqcode *tp = NULL; - xtrace(IOCTL, "ioctl() READTOCENTRY\n"); - - if (-1 == mcdx_readtoc(stuffp)) - return -1; - if (entry->cdte_track == CDROM_LEADOUT) - tp = &stuffp->toc[stuffp->di.n_last - - stuffp->di.n_first + 1]; - else if (entry->cdte_track > stuffp->di.n_last - || entry->cdte_track < stuffp->di.n_first) - return -EINVAL; - else - tp = &stuffp->toc[entry->cdte_track - - stuffp->di.n_first]; - - if (NULL == tp) - return -EIO; - entry->cdte_adr = tp->control; - entry->cdte_ctrl = tp->control >> 4; - /* Always return stuff in MSF, and let the Uniform cdrom driver - worry about what the user actually wants */ - entry->cdte_addr.msf.minute = - bcd2uint(tp->dt.minute); - entry->cdte_addr.msf.second = - bcd2uint(tp->dt.second); - entry->cdte_addr.msf.frame = - bcd2uint(tp->dt.frame); - return 0; - } - - case CDROMSUBCHNL:{ - struct cdrom_subchnl *sub = - (struct cdrom_subchnl *) arg; - struct s_subqcode q; - - xtrace(IOCTL, "ioctl() SUBCHNL\n"); - - if (-1 == mcdx_requestsubqcode(stuffp, &q, 2)) - return -EIO; - - xtrace(SUBCHNL, "audiostatus: %x\n", - stuffp->audiostatus); - sub->cdsc_audiostatus = stuffp->audiostatus; - sub->cdsc_adr = q.control; - sub->cdsc_ctrl = q.control >> 4; - sub->cdsc_trk = bcd2uint(q.tno); - sub->cdsc_ind = bcd2uint(q.index); - - xtrace(SUBCHNL, "trk %d, ind %d\n", - sub->cdsc_trk, sub->cdsc_ind); - /* Always return stuff in MSF, and let the Uniform cdrom driver - worry about what the user actually wants */ - sub->cdsc_absaddr.msf.minute = - bcd2uint(q.dt.minute); - sub->cdsc_absaddr.msf.second = - bcd2uint(q.dt.second); - sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame); - sub->cdsc_reladdr.msf.minute = - bcd2uint(q.tt.minute); - sub->cdsc_reladdr.msf.second = - bcd2uint(q.tt.second); - sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame); - xtrace(SUBCHNL, - "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n", - sub->cdsc_absaddr.msf.minute, - sub->cdsc_absaddr.msf.second, - sub->cdsc_absaddr.msf.frame, - sub->cdsc_reladdr.msf.minute, - sub->cdsc_reladdr.msf.second, - sub->cdsc_reladdr.msf.frame); - - return 0; - } - - case CDROMREADTOCHDR:{ - struct cdrom_tochdr *toc = - (struct cdrom_tochdr *) arg; - - xtrace(IOCTL, "ioctl() READTOCHDR\n"); - toc->cdth_trk0 = stuffp->di.n_first; - toc->cdth_trk1 = stuffp->di.n_last; - xtrace(TOCHDR, - "ioctl() track0 = %d, track1 = %d\n", - stuffp->di.n_first, stuffp->di.n_last); - return 0; - } - - case CDROMPAUSE:{ - xtrace(IOCTL, "ioctl() PAUSE\n"); - if (stuffp->audiostatus != CDROM_AUDIO_PLAY) - return -EINVAL; - if (-1 == mcdx_stop(stuffp, 1)) - return -EIO; - stuffp->audiostatus = CDROM_AUDIO_PAUSED; - if (-1 == - mcdx_requestsubqcode(stuffp, &stuffp->start, - 1)) - return -EIO; - return 0; - } - - case CDROMMULTISESSION:{ - struct cdrom_multisession *ms = - (struct cdrom_multisession *) arg; - xtrace(IOCTL, "ioctl() MULTISESSION\n"); - /* Always return stuff in LBA, and let the Uniform cdrom driver - worry about what the user actually wants */ - ms->addr.lba = msf2log(&stuffp->multi.msf_last); - ms->xa_flag = !!stuffp->multi.multi; - xtrace(MS, - "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n", - ms->xa_flag, ms->addr.lba, - stuffp->multi.msf_last.minute, - stuffp->multi.msf_last.second, - stuffp->multi.msf_last.frame); - - return 0; - } - - case CDROMEJECT:{ - xtrace(IOCTL, "ioctl() EJECT\n"); - if (stuffp->users > 1) - return -EBUSY; - return (mcdx_tray_move(cdi, 1)); - } - - case CDROMCLOSETRAY:{ - xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n"); - return (mcdx_tray_move(cdi, 0)); - } - - case CDROMVOLCTRL:{ - struct cdrom_volctrl *volctrl = - (struct cdrom_volctrl *) arg; - xtrace(IOCTL, "ioctl() VOLCTRL\n"); - -#if 0 /* not tested! */ - /* adjust for the weirdness of workman (md) */ - /* can't test it (hs) */ - volctrl.channel2 = volctrl.channel1; - volctrl.channel1 = volctrl.channel3 = 0x00; -#endif - return mcdx_setattentuator(stuffp, volctrl, 2); - } - - default: - return -EINVAL; - } -} - -static void do_mcdx_request(request_queue_t * q) -{ - struct s_drive_stuff *stuffp; - struct request *req; - - again: - - req = elv_next_request(q); - if (!req) - return; - - stuffp = req->rq_disk->private_data; - - if (!stuffp->present) { - xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name); - xtrace(REQUEST, "end_request(0): bad device\n"); - end_request(req, 0); - return; - } - - if (stuffp->audio) { - xwarn("do_request() attempt to read from audio cd\n"); - xtrace(REQUEST, "end_request(0): read from audio\n"); - end_request(req, 0); - return; - } - - xtrace(REQUEST, "do_request() (%lu + %lu)\n", - req->sector, req->nr_sectors); - - if (rq_data_dir(req) != READ) { - xwarn("do_request(): non-read command to cd!!\n"); - xtrace(REQUEST, "end_request(0): write\n"); - end_request(req, 0); - return; - } - else { - stuffp->status = 0; - while (req->nr_sectors) { - int i; - - i = mcdx_transfer(stuffp, - req->buffer, - req->sector, - req->nr_sectors); - - if (i == -1) { - end_request(req, 0); - goto again; - } - req->sector += i; - req->nr_sectors -= i; - req->buffer += (i * 512); - } - end_request(req, 1); - goto again; - - xtrace(REQUEST, "end_request(1)\n"); - end_request(req, 1); - } - - goto again; -} - -static int mcdx_open(struct cdrom_device_info *cdi, int purpose) -{ - struct s_drive_stuff *stuffp; - xtrace(OPENCLOSE, "open()\n"); - stuffp = cdi->handle; - if (!stuffp->present) - return -ENXIO; - - /* Make the modules looking used ... (thanx bjorn). - * But we shouldn't forget to decrement the module counter - * on error return */ - - /* this is only done to test if the drive talks with us */ - if (-1 == mcdx_getstatus(stuffp, 1)) - return -EIO; - - if (stuffp->xxx) { - - xtrace(OPENCLOSE, "open() media changed\n"); - stuffp->audiostatus = CDROM_AUDIO_INVALID; - stuffp->readcmd = 0; - xtrace(OPENCLOSE, "open() Request multisession info\n"); - if (-1 == - mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6)) - xinfo("No multidiskinfo\n"); - } else { - /* multisession ? */ - if (!stuffp->multi.multi) - stuffp->multi.msf_last.second = 2; - - xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n", - stuffp->multi.multi, - stuffp->multi.msf_last.minute, - stuffp->multi.msf_last.second, - stuffp->multi.msf_last.frame); - - {; - } /* got multisession information */ - /* request the disks table of contents (aka diskinfo) */ - if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) { - - stuffp->lastsector = -1; - - } else { - - stuffp->lastsector = (CD_FRAMESIZE / 512) - * msf2log(&stuffp->di.msf_leadout) - 1; - - xtrace(OPENCLOSE, - "open() start %d (%02x:%02x.%02x) %d\n", - stuffp->di.n_first, - stuffp->di.msf_first.minute, - stuffp->di.msf_first.second, - stuffp->di.msf_first.frame, - msf2log(&stuffp->di.msf_first)); - xtrace(OPENCLOSE, - "open() last %d (%02x:%02x.%02x) %d\n", - stuffp->di.n_last, - stuffp->di.msf_leadout.minute, - stuffp->di.msf_leadout.second, - stuffp->di.msf_leadout.frame, - msf2log(&stuffp->di.msf_leadout)); - } - - if (stuffp->toc) { - xtrace(MALLOC, "open() free old toc @ %p\n", - stuffp->toc); - kfree(stuffp->toc); - - stuffp->toc = NULL; - } - - xtrace(OPENCLOSE, "open() init irq generation\n"); - if (-1 == mcdx_config(stuffp, 1)) - return -EIO; -#ifdef FALLBACK - /* Set the read speed */ - xwarn("AAA %x AAA\n", stuffp->readcmd); - if (stuffp->readerrs) - stuffp->readcmd = READ1X; - else - stuffp->readcmd = - stuffp->present | SINGLE ? READ1X : READ2X; - xwarn("XXX %x XXX\n", stuffp->readcmd); -#else - stuffp->readcmd = - stuffp->present | SINGLE ? READ1X : READ2X; -#endif - - /* try to get the first sector, iff any ... */ - if (stuffp->lastsector >= 0) { - char buf[512]; - int ans; - int tries; - - stuffp->xa = 0; - stuffp->audio = 0; - - for (tries = 6; tries; tries--) { - - stuffp->introk = 1; - - xtrace(OPENCLOSE, "open() try as %s\n", - stuffp->xa ? "XA" : "normal"); - /* set data mode */ - if (-1 == (ans = mcdx_setdatamode(stuffp, - stuffp-> - xa ? - MODE2 : - MODE1, - 1))) { - /* return -EIO; */ - stuffp->xa = 0; - break; - } - - if ((stuffp->audio = e_audio(ans))) - break; - - while (0 == - (ans = - mcdx_transfer(stuffp, buf, 0, 1))); - - if (ans == 1) - break; - stuffp->xa = !stuffp->xa; - } - } - /* xa disks will be read in raw mode, others not */ - if (-1 == mcdx_setdrivemode(stuffp, - stuffp->xa ? RAW : COOKED, - 1)) - return -EIO; - if (stuffp->audio) { - xinfo("open() audio disk found\n"); - } else if (stuffp->lastsector >= 0) { - xinfo("open() %s%s disk found\n", - stuffp->xa ? "XA / " : "", - stuffp->multi. - multi ? "Multi Session" : "Single Session"); - } - } - stuffp->xxx = 0; - stuffp->users++; - return 0; -} - -static void mcdx_close(struct cdrom_device_info *cdi) -{ - struct s_drive_stuff *stuffp; - - xtrace(OPENCLOSE, "close()\n"); - - stuffp = cdi->handle; - - --stuffp->users; -} - -static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr) -/* Return: 1 if media changed since last call to this function - 0 otherwise */ -{ - struct s_drive_stuff *stuffp; - - xinfo("mcdx_media_changed called for device %s\n", cdi->name); - - stuffp = cdi->handle; - mcdx_getstatus(stuffp, 1); - - if (stuffp->yyy == 0) - return 0; - - stuffp->yyy = 0; - return 1; -} - -#ifndef MODULE -static int __init mcdx_setup(char *str) -{ - int pi[4]; - (void) get_options(str, ARRAY_SIZE(pi), pi); - - if (pi[0] > 0) - mcdx_drive_map[0][0] = pi[1]; - if (pi[0] > 1) - mcdx_drive_map[0][1] = pi[2]; - return 1; -} - -__setup("mcdx=", mcdx_setup); - -#endif - -/* DIRTY PART ******************************************************/ - -static void mcdx_delay(struct s_drive_stuff *stuff, long jifs) -/* This routine is used for sleeping. - * A jifs value <0 means NO sleeping, - * =0 means minimal sleeping (let the kernel - * run for other processes) - * >0 means at least sleep for that amount. - * May be we could use a simple count loop w/ jumps to itself, but - * I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */ -{ - if (jifs < 0) - return; - - xtrace(SLEEP, "*** delay: sleepq\n"); - interruptible_sleep_on_timeout(&stuff->sleepq, jifs); - xtrace(SLEEP, "delay awoken\n"); - if (signal_pending(current)) { - xtrace(SLEEP, "got signal\n"); - } -} - -static irqreturn_t mcdx_intr(int irq, void *dev_id) -{ - struct s_drive_stuff *stuffp = dev_id; - unsigned char b; - -#ifdef AK2 - if (!stuffp->busy && stuffp->pending) - stuffp->int_err = 1; - -#endif /* AK2 */ - /* get the interrupt status */ - b = inb(stuffp->rreg_status); - stuffp->introk = ~b & MCDX_RBIT_DTEN; - - /* NOTE: We only should get interrupts if the data we - * requested are ready to transfer. - * But the drive seems to generate ``asynchronous'' interrupts - * on several error conditions too. (Despite the err int enable - * setting during initialisation) */ - - /* if not ok, read the next byte as the drives status */ - if (!stuffp->introk) { - xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b); - if (~b & MCDX_RBIT_STEN) { - xinfo("intr() irq %d status 0x%02x\n", - irq, inb(stuffp->rreg_data)); - } else { - xinfo("intr() irq %d ambiguous hw status\n", irq); - } - } else { - xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b); - } - - stuffp->busy = 0; - wake_up_interruptible(&stuffp->busyq); - return IRQ_HANDLED; -} - - -static int mcdx_talk(struct s_drive_stuff *stuffp, - const unsigned char *cmd, size_t cmdlen, - void *buffer, size_t size, unsigned int timeout, int tries) -/* Send a command to the drive, wait for the result. - * returns -1 on timeout, drive status otherwise - * If buffer is not zero, the result (length size) is stored there. - * If buffer is zero the size should be the number of bytes to read - * from the drive. These bytes are discarded. - */ -{ - int st; - char c; - int discard; - - /* Somebody wants the data read? */ - if ((discard = (buffer == NULL))) - buffer = &c; - - while (stuffp->lock) { - xtrace(SLEEP, "*** talk: lockq\n"); - interruptible_sleep_on(&stuffp->lockq); - xtrace(SLEEP, "talk: awoken\n"); - } - - stuffp->lock = 1; - - /* An operation other then reading data destroys the - * data already requested and remembered in stuffp->request, ... */ - stuffp->valid = 0; - -#if MCDX_DEBUG & TALK - { - unsigned char i; - xtrace(TALK, - "talk() %d / %d tries, res.size %d, command 0x%02x", - tries, timeout, size, (unsigned char) cmd[0]); - for (i = 1; i < cmdlen; i++) - xtrace(TALK, " 0x%02x", cmd[i]); - xtrace(TALK, "\n"); - } -#endif - - /* give up if all tries are done (bad) or if the status - * st != -1 (good) */ - for (st = -1; st == -1 && tries; tries--) { - - char *bp = (char *) buffer; - size_t sz = size; - - outsb(stuffp->wreg_data, cmd, cmdlen); - xtrace(TALK, "talk() command sent\n"); - - /* get the status byte */ - if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) { - xinfo("talk() %02x timed out (status), %d tr%s left\n", - cmd[0], tries - 1, tries == 2 ? "y" : "ies"); - continue; - } - st = *bp; - sz--; - if (!discard) - bp++; - - xtrace(TALK, "talk() got status 0x%02x\n", st); - - /* command error? */ - if (e_cmderr(st)) { - xwarn("command error cmd = %02x %s \n", - cmd[0], cmdlen > 1 ? "..." : ""); - st = -1; - continue; - } - - /* audio status? */ - if (stuffp->audiostatus == CDROM_AUDIO_INVALID) - stuffp->audiostatus = - e_audiobusy(st) ? CDROM_AUDIO_PLAY : - CDROM_AUDIO_NO_STATUS; - else if (stuffp->audiostatus == CDROM_AUDIO_PLAY - && e_audiobusy(st) == 0) - stuffp->audiostatus = CDROM_AUDIO_COMPLETED; - - /* media change? */ - if (e_changed(st)) { - xinfo("talk() media changed\n"); - stuffp->xxx = stuffp->yyy = 1; - } - - /* now actually get the data */ - while (sz--) { - if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) { - xinfo("talk() %02x timed out (data), %d tr%s left\n", - cmd[0], tries - 1, - tries == 2 ? "y" : "ies"); - st = -1; - break; - } - if (!discard) - bp++; - xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1)); - } - } - -#if !MCDX_QUIET - if (!tries && st == -1) - xinfo("talk() giving up\n"); -#endif - - stuffp->lock = 0; - wake_up_interruptible(&stuffp->lockq); - - xtrace(TALK, "talk() done with 0x%02x\n", st); - return st; -} - -/* MODULE STUFF ***********************************************************/ - -static int __init __mcdx_init(void) -{ - int i; - int drives = 0; - - mcdx_init(); - for (i = 0; i < MCDX_NDRIVES; i++) { - if (mcdx_stuffp[i]) { - xtrace(INIT, "init_module() drive %d stuff @ %p\n", - i, mcdx_stuffp[i]); - drives++; - } - } - - if (!drives) - return -EIO; - - return 0; -} - -static void __exit mcdx_exit(void) -{ - int i; - - xinfo("cleanup_module called\n"); - - for (i = 0; i < MCDX_NDRIVES; i++) { - struct s_drive_stuff *stuffp = mcdx_stuffp[i]; - if (!stuffp) - continue; - del_gendisk(stuffp->disk); - if (unregister_cdrom(&stuffp->info)) { - printk(KERN_WARNING "Can't unregister cdrom mcdx\n"); - continue; - } - put_disk(stuffp->disk); - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - free_irq(stuffp->irq, NULL); - if (stuffp->toc) { - xtrace(MALLOC, "cleanup_module() free toc @ %p\n", - stuffp->toc); - kfree(stuffp->toc); - } - xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", - stuffp); - mcdx_stuffp[i] = NULL; - kfree(stuffp); - } - - if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) { - xwarn("cleanup() unregister_blkdev() failed\n"); - } -#if !MCDX_QUIET - else - xinfo("cleanup() succeeded\n"); -#endif - blk_cleanup_queue(mcdx_queue); -} - -#ifdef MODULE -module_init(__mcdx_init); -#endif -module_exit(mcdx_exit); - - -/* Support functions ************************************************/ - -static int __init mcdx_init_drive(int drive) -{ - struct s_version version; - struct gendisk *disk; - struct s_drive_stuff *stuffp; - int size = sizeof(*stuffp); - char msg[80]; - - xtrace(INIT, "init() try drive %d\n", drive); - - xtrace(INIT, "kmalloc space for stuffpt's\n"); - xtrace(MALLOC, "init() malloc %d bytes\n", size); - if (!(stuffp = kzalloc(size, GFP_KERNEL))) { - xwarn("init() malloc failed\n"); - return 1; - } - - disk = alloc_disk(1); - if (!disk) { - xwarn("init() malloc failed\n"); - kfree(stuffp); - return 1; - } - - xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n", - sizeof(*stuffp), stuffp); - - /* set default values */ - stuffp->present = 0; /* this should be 0 already */ - stuffp->toc = NULL; /* this should be NULL already */ - - /* setup our irq and i/o addresses */ - stuffp->irq = irq(mcdx_drive_map[drive]); - stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]); - stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1; - stuffp->wreg_hcon = stuffp->wreg_reset + 1; - stuffp->wreg_chn = stuffp->wreg_hcon + 1; - - init_waitqueue_head(&stuffp->busyq); - init_waitqueue_head(&stuffp->lockq); - init_waitqueue_head(&stuffp->sleepq); - - /* check if i/o addresses are available */ - if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) { - xwarn("0x%03x,%d: Init failed. " - "I/O ports (0x%03x..0x%03x) already in use.\n", - stuffp->wreg_data, stuffp->irq, - stuffp->wreg_data, - stuffp->wreg_data + MCDX_IO_SIZE - 1); - xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp); - kfree(stuffp); - put_disk(disk); - xtrace(INIT, "init() continue at next drive\n"); - return 0; /* next drive */ - } - - xtrace(INIT, "init() i/o port is available at 0x%03x\n" - stuffp->wreg_data); - xtrace(INIT, "init() hardware reset\n"); - mcdx_reset(stuffp, HARD, 1); - - xtrace(INIT, "init() get version\n"); - if (-1 == mcdx_requestversion(stuffp, &version, 4)) { - /* failed, next drive */ - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n", - MCDX, stuffp->wreg_data, stuffp->irq); - xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp); - kfree(stuffp); - put_disk(disk); - xtrace(INIT, "init() continue at next drive\n"); - return 0; - } - - switch (version.code) { - case 'D': - stuffp->readcmd = READ2X; - stuffp->present = DOUBLE | DOOR | MULTI; - break; - case 'F': - stuffp->readcmd = READ1X; - stuffp->present = SINGLE | DOOR | MULTI; - break; - case 'M': - stuffp->readcmd = READ1X; - stuffp->present = SINGLE; - break; - default: - stuffp->present = 0; - break; - } - - stuffp->playcmd = READ1X; - - if (!stuffp->present) { - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n", - MCDX, stuffp->wreg_data, stuffp->irq); - kfree(stuffp); - put_disk(disk); - return 0; /* next drive */ - } - - xtrace(INIT, "init() register blkdev\n"); - if (register_blkdev(MAJOR_NR, "mcdx")) { - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - kfree(stuffp); - put_disk(disk); - return 1; - } - - mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock); - if (!mcdx_queue) { - unregister_blkdev(MAJOR_NR, "mcdx"); - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - kfree(stuffp); - put_disk(disk); - return 1; - } - - xtrace(INIT, "init() subscribe irq and i/o\n"); - if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) { - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n", - MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq); - stuffp->irq = 0; - blk_cleanup_queue(mcdx_queue); - kfree(stuffp); - put_disk(disk); - return 0; - } - - xtrace(INIT, "init() get garbage\n"); - { - int i; - mcdx_delay(stuffp, HZ / 2); - for (i = 100; i; i--) - (void) inb(stuffp->rreg_status); - } - - -#ifdef WE_KNOW_WHY - /* irq 11 -> channel register */ - outb(0x50, stuffp->wreg_chn); -#endif - - xtrace(INIT, "init() set non dma but irq mode\n"); - mcdx_config(stuffp, 1); - - stuffp->info.ops = &mcdx_dops; - stuffp->info.speed = 2; - stuffp->info.capacity = 1; - stuffp->info.handle = stuffp; - sprintf(stuffp->info.name, "mcdx%d", drive); - disk->major = MAJOR_NR; - disk->first_minor = drive; - strcpy(disk->disk_name, stuffp->info.name); - disk->fops = &mcdx_bdops; - disk->flags = GENHD_FL_CD; - stuffp->disk = disk; - - sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d." - " (Firmware version %c %x)\n", - stuffp->wreg_data, stuffp->irq, version.code, version.ver); - mcdx_stuffp[drive] = stuffp; - xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp); - if (register_cdrom(&stuffp->info) != 0) { - printk("Cannot register Mitsumi CD-ROM!\n"); - free_irq(stuffp->irq, NULL); - release_region(stuffp->wreg_data, MCDX_IO_SIZE); - kfree(stuffp); - put_disk(disk); - if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) - xwarn("cleanup() unregister_blkdev() failed\n"); - blk_cleanup_queue(mcdx_queue); - return 2; - } - disk->private_data = stuffp; - disk->queue = mcdx_queue; - add_disk(disk); - printk(msg); - return 0; -} - -static int __init mcdx_init(void) -{ - int drive; - xwarn("Version 2.14(hs) \n"); - - xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n"); - - /* zero the pointer array */ - for (drive = 0; drive < MCDX_NDRIVES; drive++) - mcdx_stuffp[drive] = NULL; - - /* do the initialisation */ - for (drive = 0; drive < MCDX_NDRIVES; drive++) { - switch (mcdx_init_drive(drive)) { - case 2: - return -EIO; - case 1: - break; - } - } - return 0; -} - -static int mcdx_transfer(struct s_drive_stuff *stuffp, - char *p, int sector, int nr_sectors) -/* This seems to do the actually transfer. But it does more. It - keeps track of errors occurred and will (if possible) fall back - to single speed on error. - Return: -1 on timeout or other error - else status byte (as in stuff->st) */ -{ - int ans; - - ans = mcdx_xfer(stuffp, p, sector, nr_sectors); - return ans; -#ifdef FALLBACK - if (-1 == ans) - stuffp->readerrs++; - else - return ans; - - if (stuffp->readerrs && stuffp->readcmd == READ1X) { - xwarn("XXX Already reading 1x -- no chance\n"); - return -1; - } - - xwarn("XXX Fallback to 1x\n"); - - stuffp->readcmd = READ1X; - return mcdx_transfer(stuffp, p, sector, nr_sectors); -#endif - -} - - -static int mcdx_xfer(struct s_drive_stuff *stuffp, - char *p, int sector, int nr_sectors) -/* This does actually the transfer from the drive. - Return: -1 on timeout or other error - else status byte (as in stuff->st) */ -{ - int border; - int done = 0; - long timeout; - - if (stuffp->audio) { - xwarn("Attempt to read from audio CD.\n"); - return -1; - } - - if (!stuffp->readcmd) { - xinfo("Can't transfer from missing disk.\n"); - return -1; - } - - while (stuffp->lock) { - interruptible_sleep_on(&stuffp->lockq); - } - - if (stuffp->valid && (sector >= stuffp->pending) - && (sector < stuffp->low_border)) { - - /* All (or at least a part of the sectors requested) seems - * to be already requested, so we don't need to bother the - * drive with new requests ... - * Wait for the drive become idle, but first - * check for possible occurred errors --- the drive - * seems to report them asynchronously */ - - - border = stuffp->high_border < (border = - sector + nr_sectors) - ? stuffp->high_border : border; - - stuffp->lock = current->pid; - - do { - - while (stuffp->busy) { - - timeout = - interruptible_sleep_on_timeout - (&stuffp->busyq, 5 * HZ); - - if (!stuffp->introk) { - xtrace(XFER, - "error via interrupt\n"); - } else if (!timeout) { - xtrace(XFER, "timeout\n"); - } else if (signal_pending(current)) { - xtrace(XFER, "signal\n"); - } else - continue; - - stuffp->lock = 0; - stuffp->busy = 0; - stuffp->valid = 0; - - wake_up_interruptible(&stuffp->lockq); - xtrace(XFER, "transfer() done (-1)\n"); - return -1; - } - - /* check if we need to set the busy flag (as we - * expect an interrupt */ - stuffp->busy = (3 == (stuffp->pending & 3)); - - /* Test if it's the first sector of a block, - * there we have to skip some bytes as we read raw data */ - if (stuffp->xa && (0 == (stuffp->pending & 3))) { - const int HEAD = - CD_FRAMESIZE_RAW - CD_XA_TAIL - - CD_FRAMESIZE; - insb(stuffp->rreg_data, p, HEAD); - } - - /* now actually read the data */ - insb(stuffp->rreg_data, p, 512); - - /* test if it's the last sector of a block, - * if so, we have to handle XA special */ - if ((3 == (stuffp->pending & 3)) && stuffp->xa) { - char dummy[CD_XA_TAIL]; - insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL); - } - - if (stuffp->pending == sector) { - p += 512; - done++; - sector++; - } - } while (++(stuffp->pending) < border); - - stuffp->lock = 0; - wake_up_interruptible(&stuffp->lockq); - - } else { - - /* The requested sector(s) is/are out of the - * already requested range, so we have to bother the drive - * with a new request. */ - - static unsigned char cmd[] = { - 0, - 0, 0, 0, - 0, 0, 0 - }; - - cmd[0] = stuffp->readcmd; - - /* The numbers held in ->pending, ..., should be valid */ - stuffp->valid = 1; - stuffp->pending = sector & ~3; - - /* do some sanity checks */ - if (stuffp->pending > stuffp->lastsector) { - xwarn - ("transfer() sector %d from nirvana requested.\n", - stuffp->pending); - stuffp->status = MCDX_ST_EOM; - stuffp->valid = 0; - xtrace(XFER, "transfer() done (-1)\n"); - return -1; - } - - if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE) - > stuffp->lastsector + 1) { - xtrace(XFER, "cut low_border\n"); - stuffp->low_border = stuffp->lastsector + 1; - } - if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE) - > stuffp->lastsector + 1) { - xtrace(XFER, "cut high_border\n"); - stuffp->high_border = stuffp->lastsector + 1; - } - - { /* Convert the sector to be requested to MSF format */ - struct cdrom_msf0 pending; - log2msf(stuffp->pending / 4, &pending); - cmd[1] = pending.minute; - cmd[2] = pending.second; - cmd[3] = pending.frame; - } - - cmd[6] = - (unsigned - char) ((stuffp->high_border - stuffp->pending) / 4); - xtrace(XFER, "[%2d]\n", cmd[6]); - - stuffp->busy = 1; - /* Now really issue the request command */ - outsb(stuffp->wreg_data, cmd, sizeof cmd); - - } -#ifdef AK2 - if (stuffp->int_err) { - stuffp->valid = 0; - stuffp->int_err = 0; - return -1; - } -#endif /* AK2 */ - - stuffp->low_border = (stuffp->low_border += - done) < - stuffp->high_border ? stuffp->low_border : stuffp->high_border; - - return done; -} - - -/* Access to elements of the mcdx_drive_map members */ - -static unsigned port(int *ip) -{ - return ip[0]; -} -static int irq(int *ip) -{ - return ip[1]; -} - -/* Misc number converters */ - -static unsigned int bcd2uint(unsigned char c) -{ - return (c >> 4) * 10 + (c & 0x0f); -} - -static unsigned int uint2bcd(unsigned int ival) -{ - return ((ival / 10) << 4) | (ival % 10); -} - -static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf) -{ - l += CD_MSF_OFFSET; - pmsf->minute = uint2bcd(l / 4500), l %= 4500; - pmsf->second = uint2bcd(l / 75); - pmsf->frame = uint2bcd(l % 75); -} - -static unsigned int msf2log(const struct cdrom_msf0 *pmsf) -{ - return bcd2uint(pmsf->frame) - + bcd2uint(pmsf->second) * 75 - + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET; -} - -int mcdx_readtoc(struct s_drive_stuff *stuffp) -/* Read the toc entries from the CD, - * Return: -1 on failure, else 0 */ -{ - - if (stuffp->toc) { - xtrace(READTOC, "ioctl() toc already read\n"); - return 0; - } - - xtrace(READTOC, "ioctl() readtoc for %d tracks\n", - stuffp->di.n_last - stuffp->di.n_first + 1); - - if (-1 == mcdx_hold(stuffp, 1)) - return -1; - - xtrace(READTOC, "ioctl() tocmode\n"); - if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) - return -EIO; - - /* all seems to be ok so far ... malloc */ - { - int size; - size = - sizeof(struct s_subqcode) * (stuffp->di.n_last - - stuffp->di.n_first + 2); - - xtrace(MALLOC, "ioctl() malloc %d bytes\n", size); - stuffp->toc = kmalloc(size, GFP_KERNEL); - if (!stuffp->toc) { - xwarn("Cannot malloc %d bytes for toc\n", size); - mcdx_setdrivemode(stuffp, DATA, 1); - return -EIO; - } - } - - /* now read actually the index */ - { - int trk; - int retries; - - for (trk = 0; - trk < (stuffp->di.n_last - stuffp->di.n_first + 1); - trk++) - stuffp->toc[trk].index = 0; - - for (retries = 300; retries; retries--) { /* why 300? */ - struct s_subqcode q; - unsigned int idx; - - if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) { - mcdx_setdrivemode(stuffp, DATA, 1); - return -EIO; - } - - idx = bcd2uint(q.index); - - if ((idx > 0) - && (idx <= stuffp->di.n_last) - && (q.tno == 0) - && (stuffp->toc[idx - stuffp->di.n_first]. - index == 0)) { - stuffp->toc[idx - stuffp->di.n_first] = q; - xtrace(READTOC, - "ioctl() toc idx %d (trk %d)\n", - idx, trk); - trk--; - } - if (trk == 0) - break; - } - memset(&stuffp-> - toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0, - sizeof(stuffp->toc[0])); - stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + - 1].dt = stuffp->di.msf_leadout; - } - - /* unset toc mode */ - xtrace(READTOC, "ioctl() undo toc mode\n"); - if (-1 == mcdx_setdrivemode(stuffp, DATA, 2)) - return -EIO; - -#if MCDX_DEBUG && READTOC - { - int trk; - for (trk = 0; - trk < (stuffp->di.n_last - stuffp->di.n_first + 2); - trk++) - xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x" - " %02x:%02x.%02x %02x:%02x.%02x\n", - trk + stuffp->di.n_first, - stuffp->toc[trk].control, - stuffp->toc[trk].tno, - stuffp->toc[trk].index, - stuffp->toc[trk].tt.minute, - stuffp->toc[trk].tt.second, - stuffp->toc[trk].tt.frame, - stuffp->toc[trk].dt.minute, - stuffp->toc[trk].dt.second, - stuffp->toc[trk].dt.frame); - } -#endif - - return 0; -} - -static int -mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf) -{ - unsigned char cmd[7] = { - 0, 0, 0, 0, 0, 0, 0 - }; - - if (!stuffp->readcmd) { - xinfo("Can't play from missing disk.\n"); - return -1; - } - - cmd[0] = stuffp->playcmd; - - cmd[1] = msf->cdmsf_min0; - cmd[2] = msf->cdmsf_sec0; - cmd[3] = msf->cdmsf_frame0; - cmd[4] = msf->cdmsf_min1; - cmd[5] = msf->cdmsf_sec1; - cmd[6] = msf->cdmsf_frame1; - - xtrace(PLAYMSF, "ioctl(): play %x " - "%02x:%02x:%02x -- %02x:%02x:%02x\n", - cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]); - - outsb(stuffp->wreg_data, cmd, sizeof cmd); - - if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) { - xwarn("playmsf() timeout\n"); - return -1; - } - - stuffp->audiostatus = CDROM_AUDIO_PLAY; - return 0; -} - -static int -mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti) -{ - struct s_subqcode *p; - struct cdrom_msf msf; - - if (-1 == mcdx_readtoc(stuffp)) - return -1; - - if (ti) - p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first]; - else - p = &stuffp->start; - - msf.cdmsf_min0 = p->dt.minute; - msf.cdmsf_sec0 = p->dt.second; - msf.cdmsf_frame0 = p->dt.frame; - - if (ti) { - p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1]; - stuffp->stop = *p; - } else - p = &stuffp->stop; - - msf.cdmsf_min1 = p->dt.minute; - msf.cdmsf_sec1 = p->dt.second; - msf.cdmsf_frame1 = p->dt.frame; - - return mcdx_playmsf(stuffp, &msf); -} - - -/* Drive functions ************************************************/ - -static int mcdx_tray_move(struct cdrom_device_info *cdi, int position) -{ - struct s_drive_stuff *stuffp = cdi->handle; - - if (!stuffp->present) - return -ENXIO; - if (!(stuffp->present & DOOR)) - return -ENOSYS; - - if (position) /* 1: eject */ - return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3); - else /* 0: close */ - return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3); - return 1; -} - -static int mcdx_stop(struct s_drive_stuff *stuffp, int tries) -{ - return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries); -} - -static int mcdx_hold(struct s_drive_stuff *stuffp, int tries) -{ - return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries); -} - -static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp, - struct s_subqcode *sub, int tries) -{ - char buf[11]; - int ans; - - if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf), - 2 * HZ, tries))) - return -1; - sub->control = buf[1]; - sub->tno = buf[2]; - sub->index = buf[3]; - sub->tt.minute = buf[4]; - sub->tt.second = buf[5]; - sub->tt.frame = buf[6]; - sub->dt.minute = buf[8]; - sub->dt.second = buf[9]; - sub->dt.frame = buf[10]; - - return ans; -} - -static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp, - struct s_multi *multi, int tries) -{ - char buf[5]; - int ans; - - if (stuffp->present & MULTI) { - ans = - mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ, - tries); - multi->multi = buf[1]; - multi->msf_last.minute = buf[2]; - multi->msf_last.second = buf[3]; - multi->msf_last.frame = buf[4]; - return ans; - } else { - multi->multi = 0; - return 0; - } -} - -static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info, - int tries) -{ - char buf[9]; - int ans; - ans = - mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries); - if (ans == -1) { - info->n_first = 0; - info->n_last = 0; - } else { - info->n_first = bcd2uint(buf[1]); - info->n_last = bcd2uint(buf[2]); - info->msf_leadout.minute = buf[3]; - info->msf_leadout.second = buf[4]; - info->msf_leadout.frame = buf[5]; - info->msf_first.minute = buf[6]; - info->msf_first.second = buf[7]; - info->msf_first.frame = buf[8]; - } - return ans; -} - -static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode, - int tries) -{ - char cmd[2]; - int ans; - - xtrace(HW, "setdrivemode() %d\n", mode); - - if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries))) - return -1; - - switch (mode) { - case TOC: - cmd[1] |= 0x04; - break; - case DATA: - cmd[1] &= ~0x04; - break; - case RAW: - cmd[1] |= 0x40; - break; - case COOKED: - cmd[1] &= ~0x40; - break; - default: - break; - } - cmd[0] = 0x50; - return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries); -} - -static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode, - int tries) -{ - unsigned char cmd[2] = { 0xa0 }; - xtrace(HW, "setdatamode() %d\n", mode); - switch (mode) { - case MODE0: - cmd[1] = 0x00; - break; - case MODE1: - cmd[1] = 0x01; - break; - case MODE2: - cmd[1] = 0x02; - break; - default: - return -EINVAL; - } - return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries); -} - -static int mcdx_config(struct s_drive_stuff *stuffp, int tries) -{ - char cmd[4]; - - xtrace(HW, "config()\n"); - - cmd[0] = 0x90; - - cmd[1] = 0x10; /* irq enable */ - cmd[2] = 0x05; /* pre, err irq enable */ - - if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries)) - return -1; - - cmd[1] = 0x02; /* dma select */ - cmd[2] = 0x00; /* no dma */ - - return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries); -} - -static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver, - int tries) -{ - char buf[3]; - int ans; - - if (-1 == (ans = mcdx_talk(stuffp, "\xdc", - 1, buf, sizeof(buf), 2 * HZ, tries))) - return ans; - - ver->code = buf[1]; - ver->ver = buf[2]; - - return ans; -} - -static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries) -{ - if (mode == HARD) { - outb(0, stuffp->wreg_chn); /* no dma, no irq -> hardware */ - outb(0, stuffp->wreg_reset); /* hw reset */ - return 0; - } else - return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries); -} - -static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock) -{ - struct s_drive_stuff *stuffp = cdi->handle; - char cmd[2] = { 0xfe }; - - if (!(stuffp->present & DOOR)) - return -ENOSYS; - if (stuffp->present & DOOR) { - cmd[1] = lock ? 0x01 : 0x00; - return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3); - } else - return 0; -} - -static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries) -{ - return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries); -} - -static int -mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf) -{ - unsigned long timeout = to + jiffies; - char c; - - if (!buf) - buf = &c; - - while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) { - if (time_after(jiffies, timeout)) - return -1; - mcdx_delay(stuffp, delay); - } - - *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff; - - return 0; -} - -static int mcdx_setattentuator(struct s_drive_stuff *stuffp, - struct cdrom_volctrl *vol, int tries) -{ - char cmd[5]; - cmd[0] = 0xae; - cmd[1] = vol->channel0; - cmd[2] = 0; - cmd[3] = vol->channel1; - cmd[4] = 0; - - return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries); -} - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR); diff --git a/drivers/cdrom/mcdx.h b/drivers/cdrom/mcdx.h deleted file mode 100644 index 83c364a74dc4..000000000000 --- a/drivers/cdrom/mcdx.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Definitions for the Mitsumi CDROM interface - * Copyright (C) 1995 1996 Heiko Schlittermann - * VERSION: @VERSION@ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Thanks to - * The Linux Community at all and ... - * Martin Harris (he wrote the first Mitsumi Driver) - * Eberhard Moenkeberg (he gave me much support and the initial kick) - * Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they - * improved the original driver) - * Jon Tombs, Bjorn Ekwall (module support) - * Daniel v. Mosnenck (he sent me the Technical and Programming Reference) - * Gerd Knorr (he lent me his PhotoCD) - * Nils Faerber and Roger E. Wolff (extensively tested the LU portion) - * Andreas Kies (testing the mysterious hang up's) - * ... somebody forgotten? - * Marcin Dalecki - * - */ - -/* - * The following lines are for user configuration - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * {0|1} -- 1 if you want the driver detect your drive, may crash and - * needs a long time to seek. The higher the address the longer the - * seek. - * - * WARNING: AUTOPROBE doesn't work. - */ -#define MCDX_AUTOPROBE 0 - -/* - * Drive specific settings according to the jumpers on the controller - * board(s). - * o MCDX_NDRIVES : number of used entries of the following table - * o MCDX_DRIVEMAP : table of {i/o base, irq} per controller - * - * NOTE: I didn't get a drive at irq 9(2) working. Not even alone. - */ -#if MCDX_AUTOPROBE == 0 - #define MCDX_NDRIVES 1 - #define MCDX_DRIVEMAP { \ - {0x300, 11}, \ - {0x304, 05}, \ - {0x000, 00}, \ - {0x000, 00}, \ - {0x000, 00}, \ - } -#else - #error Autoprobing is not implemented yet. -#endif - -#ifndef MCDX_QUIET -#define MCDX_QUIET 1 -#endif - -#ifndef MCDX_DEBUG -#define MCDX_DEBUG 0 -#endif - -/* *** make the following line uncommented, if you're sure, - * *** all configuration is done */ -/* #define I_WAS_HERE */ - -/* The name of the device */ -#define MCDX "mcdx" - -/* Flags for DEBUGGING */ -#define INIT 0 -#define MALLOC 0 -#define IOCTL 0 -#define PLAYTRK 0 -#define SUBCHNL 0 -#define TOCHDR 0 -#define MS 0 -#define PLAYMSF 0 -#define READTOC 0 -#define OPENCLOSE 0 -#define HW 0 -#define TALK 0 -#define IRQ 0 -#define XFER 0 -#define REQUEST 0 -#define SLEEP 0 - -/* The following addresses are taken from the Mitsumi Reference - * and describe the possible i/o range for the controller. - */ -#define MCDX_IO_BEGIN ((char*) 0x300) /* first base of i/o addr */ -#define MCDX_IO_END ((char*) 0x3fc) /* last base of i/o addr */ - -/* Per controller 4 bytes i/o are needed. */ -#define MCDX_IO_SIZE 4 - -/* - * Bits - */ - -/* The status byte, returned from every command, set if - * the description is true */ -#define MCDX_RBIT_OPEN 0x80 /* door is open */ -#define MCDX_RBIT_DISKSET 0x40 /* disk set (recognised) */ -#define MCDX_RBIT_CHANGED 0x20 /* disk was changed */ -#define MCDX_RBIT_CHECK 0x10 /* disk rotates, servo is on */ -#define MCDX_RBIT_AUDIOTR 0x08 /* current track is audio */ -#define MCDX_RBIT_RDERR 0x04 /* read error, refer SENSE KEY */ -#define MCDX_RBIT_AUDIOBS 0x02 /* currently playing audio */ -#define MCDX_RBIT_CMDERR 0x01 /* command, param or format error */ - -/* The I/O Register holding the h/w status of the drive, - * can be read at i/o base + 1 */ -#define MCDX_RBIT_DOOR 0x10 /* door is open */ -#define MCDX_RBIT_STEN 0x04 /* if 0, i/o base contains drive status */ -#define MCDX_RBIT_DTEN 0x02 /* if 0, i/o base contains data */ - -/* - * The commands. - */ - -#define OPCODE 1 /* offset of opcode */ -#define MCDX_CMD_REQUEST_TOC 1, 0x10 -#define MCDX_CMD_REQUEST_STATUS 1, 0x40 -#define MCDX_CMD_RESET 1, 0x60 -#define MCDX_CMD_REQUEST_DRIVE_MODE 1, 0xc2 -#define MCDX_CMD_SET_INTERLEAVE 2, 0xc8, 0 -#define MCDX_CMD_DATAMODE_SET 2, 0xa0, 0 - #define MCDX_DATAMODE1 0x01 - #define MCDX_DATAMODE2 0x02 -#define MCDX_CMD_LOCK_DOOR 2, 0xfe, 0 - -#define READ_AHEAD 4 /* 8 Sectors (4K) */ - -/* Useful macros */ -#define e_door(x) ((x) & MCDX_RBIT_OPEN) -#define e_check(x) (~(x) & MCDX_RBIT_CHECK) -#define e_notset(x) (~(x) & MCDX_RBIT_DISKSET) -#define e_changed(x) ((x) & MCDX_RBIT_CHANGED) -#define e_audio(x) ((x) & MCDX_RBIT_AUDIOTR) -#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS) -#define e_cmderr(x) ((x) & MCDX_RBIT_CMDERR) -#define e_readerr(x) ((x) & MCDX_RBIT_RDERR) - -/** no drive specific */ -#define MCDX_CDBLK 2048 /* 2048 cooked data each blk */ - -#define MCDX_DATA_TIMEOUT (HZ/10) /* 0.1 second */ - -/* - * Access to the msf array - */ -#define MSF_MIN 0 /* minute */ -#define MSF_SEC 1 /* second */ -#define MSF_FRM 2 /* frame */ - -/* - * Errors - */ -#define MCDX_E 1 /* unspec error */ -#define MCDX_ST_EOM 0x0100 /* end of media */ -#define MCDX_ST_DRV 0x00ff /* mask to query the drive status */ - -#ifndef I_WAS_HERE -#ifndef MODULE -#warning You have not edited mcdx.h -#warning Perhaps irq and i/o settings are wrong. -#endif -#endif - -/* ex:set ts=4 sw=4: */ diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c deleted file mode 100644 index efd619c0fe10..000000000000 --- a/drivers/cdrom/optcd.c +++ /dev/null @@ -1,2105 +0,0 @@ -/* linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver - $Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $ - - Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl) - - - Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks - by Eberhard Moenkeberg (emoenke@gwdg.de). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* Revision history - - - 14-5-95 v0.0 Plays sound tracks. No reading of data CDs yet. - Detection of disk change doesn't work. - 21-5-95 v0.1 First ALPHA version. CD can be mounted. The - device major nr is borrowed from the Aztech - driver. Speed is around 240 kb/s, as measured - with "time dd if=/dev/cdrom of=/dev/null \ - bs=2048 count=4096". - 24-6-95 v0.2 Reworked the #defines for the command codes - and the like, as well as the structure of - the hardware communication protocol, to - reflect the "official" documentation, kindly - supplied by C.K. Tan, Optics Storage Pte. Ltd. - Also tidied up the state machine somewhat. - 28-6-95 v0.3 Removed the ISP-16 interface code, as this - should go into its own driver. The driver now - has its own major nr. - Disk change detection now seems to work, too. - This version became part of the standard - kernel as of version 1.3.7 - 24-9-95 v0.4 Re-inserted ISP-16 interface code which I - copied from sjcd.c, with a few changes. - Updated README.optcd. Submitted for - inclusion in 1.3.21 - 29-9-95 v0.4a Fixed bug that prevented compilation as module - 25-10-95 v0.5 Started multisession code. Implementation - copied from Werner Zimmermann, who copied it - from Heiko Schlittermann's mcdx. - 17-1-96 v0.6 Multisession works; some cleanup too. - 18-4-96 v0.7 Increased some timing constants; - thanks to Luke McFarlane. Also tidied up some - printk behaviour. ISP16 initialization - is now handled by a separate driver. - - 09-11-99 Make kernel-parameter implementation work with 2.3.x - Removed init_module & cleanup_module in favor of - module_init & module_exit. - Torben Mathiasen -*/ - -/* Includes */ - - -#include -#include -#include -#include - -#include -#include - -#include -#include "optcd.h" - -#include - -#define MAJOR_NR OPTICS_CDROM_MAJOR -#define QUEUE (opt_queue) -#define CURRENT elv_next_request(opt_queue) - - -/* Debug support */ - - -/* Don't forget to add new debug flags here. */ -#if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \ - DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS -#define DEBUG(x) debug x -static void debug(int debug_this, const char* fmt, ...) -{ - char s[1024]; - va_list args; - - if (!debug_this) - return; - - va_start(args, fmt); - vsnprintf(s, sizeof(s), fmt, args); - printk(KERN_DEBUG "optcd: %s\n", s); - va_end(args); -} -#else -#define DEBUG(x) -#endif - - -/* Drive hardware/firmware characteristics - Identifiers in accordance with Optics Storage documentation */ - - -#define optcd_port optcd /* Needed for the modutils. */ -static short optcd_port = OPTCD_PORTBASE; /* I/O base of drive. */ -module_param(optcd_port, short, 0); -/* Drive registers, read */ -#define DATA_PORT optcd_port /* Read data/status */ -#define STATUS_PORT optcd_port+1 /* Indicate data/status availability */ - -/* Drive registers, write */ -#define COMIN_PORT optcd_port /* For passing command/parameter */ -#define RESET_PORT optcd_port+1 /* Write anything and wait 0.5 sec */ -#define HCON_PORT optcd_port+2 /* Host Xfer Configuration */ - - -/* Command completion/status read from DATA register */ -#define ST_DRVERR 0x80 -#define ST_DOOR_OPEN 0x40 -#define ST_MIXEDMODE_DISK 0x20 -#define ST_MODE_BITS 0x1c -#define ST_M_STOP 0x00 -#define ST_M_READ 0x04 -#define ST_M_AUDIO 0x04 -#define ST_M_PAUSE 0x08 -#define ST_M_INITIAL 0x0c -#define ST_M_ERROR 0x10 -#define ST_M_OTHERS 0x14 -#define ST_MODE2TRACK 0x02 -#define ST_DSK_CHG 0x01 -#define ST_L_LOCK 0x01 -#define ST_CMD_OK 0x00 -#define ST_OP_OK 0x01 -#define ST_PA_OK 0x02 -#define ST_OP_ERROR 0x05 -#define ST_PA_ERROR 0x06 - - -/* Error codes (appear as command completion code from DATA register) */ -/* Player related errors */ -#define ERR_ILLCMD 0x11 /* Illegal command to player module */ -#define ERR_ILLPARM 0x12 /* Illegal parameter to player module */ -#define ERR_SLEDGE 0x13 -#define ERR_FOCUS 0x14 -#define ERR_MOTOR 0x15 -#define ERR_RADIAL 0x16 -#define ERR_PLL 0x17 /* PLL lock error */ -#define ERR_SUB_TIM 0x18 /* Subcode timeout error */ -#define ERR_SUB_NF 0x19 /* Subcode not found error */ -#define ERR_TRAY 0x1a -#define ERR_TOC 0x1b /* Table of Contents read error */ -#define ERR_JUMP 0x1c -/* Data errors */ -#define ERR_MODE 0x21 -#define ERR_FORM 0x22 -#define ERR_HEADADDR 0x23 /* Header Address not found */ -#define ERR_CRC 0x24 -#define ERR_ECC 0x25 /* Uncorrectable ECC error */ -#define ERR_CRC_UNC 0x26 /* CRC error and uncorrectable error */ -#define ERR_ILLBSYNC 0x27 /* Illegal block sync error */ -#define ERR_VDST 0x28 /* VDST not found */ -/* Timeout errors */ -#define ERR_READ_TIM 0x31 /* Read timeout error */ -#define ERR_DEC_STP 0x32 /* Decoder stopped */ -#define ERR_DEC_TIM 0x33 /* Decoder interrupt timeout error */ -/* Function abort codes */ -#define ERR_KEY 0x41 /* Key -Detected abort */ -#define ERR_READ_FINISH 0x42 /* Read Finish */ -/* Second Byte diagnostic codes */ -#define ERR_NOBSYNC 0x01 /* No block sync */ -#define ERR_SHORTB 0x02 /* Short block */ -#define ERR_LONGB 0x03 /* Long block */ -#define ERR_SHORTDSP 0x04 /* Short DSP word */ -#define ERR_LONGDSP 0x05 /* Long DSP word */ - - -/* Status availability flags read from STATUS register */ -#define FL_EJECT 0x20 -#define FL_WAIT 0x10 /* active low */ -#define FL_EOP 0x08 /* active low */ -#define FL_STEN 0x04 /* Status available when low */ -#define FL_DTEN 0x02 /* Data available when low */ -#define FL_DRQ 0x01 /* active low */ -#define FL_RESET 0xde /* These bits are high after a reset */ -#define FL_STDT (FL_STEN|FL_DTEN) - - -/* Transfer mode, written to HCON register */ -#define HCON_DTS 0x08 -#define HCON_SDRQB 0x04 -#define HCON_LOHI 0x02 -#define HCON_DMA16 0x01 - - -/* Drive command set, written to COMIN register */ -/* Quick response commands */ -#define COMDRVST 0x20 /* Drive Status Read */ -#define COMERRST 0x21 /* Error Status Read */ -#define COMIOCTLISTAT 0x22 /* Status Read; reset disk changed bit */ -#define COMINITSINGLE 0x28 /* Initialize Single Speed */ -#define COMINITDOUBLE 0x29 /* Initialize Double Speed */ -#define COMUNLOCK 0x30 /* Unlock */ -#define COMLOCK 0x31 /* Lock */ -#define COMLOCKST 0x32 /* Lock/Unlock Status */ -#define COMVERSION 0x40 /* Get Firmware Revision */ -#define COMVOIDREADMODE 0x50 /* Void Data Read Mode */ -/* Read commands */ -#define COMFETCH 0x60 /* Prefetch Data */ -#define COMREAD 0x61 /* Read */ -#define COMREADRAW 0x62 /* Read Raw Data */ -#define COMREADALL 0x63 /* Read All 2646 Bytes */ -/* Player control commands */ -#define COMLEADIN 0x70 /* Seek To Lead-in */ -#define COMSEEK 0x71 /* Seek */ -#define COMPAUSEON 0x80 /* Pause On */ -#define COMPAUSEOFF 0x81 /* Pause Off */ -#define COMSTOP 0x82 /* Stop */ -#define COMOPEN 0x90 /* Open Tray Door */ -#define COMCLOSE 0x91 /* Close Tray Door */ -#define COMPLAY 0xa0 /* Audio Play */ -#define COMPLAY_TNO 0xa2 /* Audio Play By Track Number */ -#define COMSUBQ 0xb0 /* Read Sub-q Code */ -#define COMLOCATION 0xb1 /* Read Head Position */ -/* Audio control commands */ -#define COMCHCTRL 0xc0 /* Audio Channel Control */ -/* Miscellaneous (test) commands */ -#define COMDRVTEST 0xd0 /* Write Test Bytes */ -#define COMTEST 0xd1 /* Diagnostic Test */ - -/* Low level drive interface. Only here we do actual I/O - Waiting for status / data available */ - - -/* Busy wait until FLAG goes low. Return 0 on timeout. */ -static inline int flag_low(int flag, unsigned long timeout) -{ - int flag_high; - unsigned long count = 0; - - while ((flag_high = (inb(STATUS_PORT) & flag))) - if (++count >= timeout) - break; - - DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s", - flag, count, flag_high ? " timeout" : "")); - return !flag_high; -} - - -/* Timed waiting for status or data */ -static int sleep_timeout; /* max # of ticks to sleep */ -static DECLARE_WAIT_QUEUE_HEAD(waitq); -static void sleep_timer(unsigned long data); -static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0); -static DEFINE_SPINLOCK(optcd_lock); -static struct request_queue *opt_queue; - -/* Timer routine: wake up when desired flag goes low, - or when timeout expires. */ -static void sleep_timer(unsigned long data) -{ - int flags = inb(STATUS_PORT) & FL_STDT; - - if (flags == FL_STDT && --sleep_timeout > 0) { - mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */ - } else - wake_up(&waitq); -} - - -/* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */ -static int sleep_flag_low(int flag, unsigned long timeout) -{ - int flag_high; - - DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low")); - - sleep_timeout = timeout; - flag_high = inb(STATUS_PORT) & flag; - if (flag_high && sleep_timeout > 0) { - mod_timer(&delay_timer, jiffies + HZ/100); - sleep_on(&waitq); - flag_high = inb(STATUS_PORT) & flag; - } - - DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s", - flag, timeout, flag_high ? " timeout" : "")); - return !flag_high; -} - -/* Low level drive interface. Only here we do actual I/O - Sending commands and parameters */ - - -/* Errors in the command protocol */ -#define ERR_IF_CMD_TIMEOUT 0x100 -#define ERR_IF_ERR_TIMEOUT 0x101 -#define ERR_IF_RESP_TIMEOUT 0x102 -#define ERR_IF_DATA_TIMEOUT 0x103 -#define ERR_IF_NOSTAT 0x104 - - -/* Send command code. Return <0 indicates error */ -static int send_cmd(int cmd) -{ - unsigned char ack; - - DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd)); - - outb(HCON_DTS, HCON_PORT); /* Enable Suspend Data Transfer */ - outb(cmd, COMIN_PORT); /* Send command code */ - if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */ - return -ERR_IF_CMD_TIMEOUT; - ack = inb(DATA_PORT); /* read command acknowledge */ - outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */ - return ack==ST_OP_OK ? 0 : -ack; -} - - -/* Send command parameters. Return <0 indicates error */ -static int send_params(struct cdrom_msf *params) -{ - unsigned char ack; - - DEBUG((DEBUG_DRIVE_IF, "sending parameters" - " %02x:%02x:%02x" - " %02x:%02x:%02x", - params->cdmsf_min0, - params->cdmsf_sec0, - params->cdmsf_frame0, - params->cdmsf_min1, - params->cdmsf_sec1, - params->cdmsf_frame1)); - - outb(params->cdmsf_min0, COMIN_PORT); - outb(params->cdmsf_sec0, COMIN_PORT); - outb(params->cdmsf_frame0, COMIN_PORT); - outb(params->cdmsf_min1, COMIN_PORT); - outb(params->cdmsf_sec1, COMIN_PORT); - outb(params->cdmsf_frame1, COMIN_PORT); - if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */ - return -ERR_IF_CMD_TIMEOUT; - ack = inb(DATA_PORT); /* read command acknowledge */ - return ack==ST_PA_OK ? 0 : -ack; -} - - -/* Send parameters for SEEK command. Return <0 indicates error */ -static int send_seek_params(struct cdrom_msf *params) -{ - unsigned char ack; - - DEBUG((DEBUG_DRIVE_IF, "sending seek parameters" - " %02x:%02x:%02x", - params->cdmsf_min0, - params->cdmsf_sec0, - params->cdmsf_frame0)); - - outb(params->cdmsf_min0, COMIN_PORT); - outb(params->cdmsf_sec0, COMIN_PORT); - outb(params->cdmsf_frame0, COMIN_PORT); - if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */ - return -ERR_IF_CMD_TIMEOUT; - ack = inb(DATA_PORT); /* read command acknowledge */ - return ack==ST_PA_OK ? 0 : -ack; -} - - -/* Wait for command execution status. Choice between busy waiting - and sleeping. Return value <0 indicates timeout. */ -static inline int get_exec_status(int busy_waiting) -{ - unsigned char exec_status; - - if (busy_waiting - ? !flag_low(FL_STEN, BUSY_TIMEOUT) - : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT)) - return -ERR_IF_CMD_TIMEOUT; - - exec_status = inb(DATA_PORT); - DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status)); - return exec_status; -} - - -/* Wait busy for extra byte of data that a command returns. - Return value <0 indicates timeout. */ -static inline int get_data(int short_timeout) -{ - unsigned char data; - - if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT)) - return -ERR_IF_DATA_TIMEOUT; - - data = inb(DATA_PORT); - DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data)); - return data; -} - - -/* Returns 0 if failed */ -static int reset_drive(void) -{ - unsigned long count = 0; - int flags; - - DEBUG((DEBUG_DRIVE_IF, "reset drive")); - - outb(0, RESET_PORT); - while (++count < RESET_WAIT) - inb(DATA_PORT); - - count = 0; - while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET) - if (++count >= BUSY_TIMEOUT) - break; - - DEBUG((DEBUG_DRIVE_IF, "reset %s", - flags == FL_RESET ? "succeeded" : "failed")); - - if (flags != FL_RESET) - return 0; /* Reset failed */ - outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */ - return 1; /* Reset succeeded */ -} - - -/* Facilities for asynchronous operation */ - -/* Read status/data availability flags FL_STEN and FL_DTEN */ -static inline int stdt_flags(void) -{ - return inb(STATUS_PORT) & FL_STDT; -} - - -/* Fetch status that has previously been waited for. <0 means not available */ -static inline int fetch_status(void) -{ - unsigned char status; - - if (inb(STATUS_PORT) & FL_STEN) - return -ERR_IF_NOSTAT; - - status = inb(DATA_PORT); - DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status)); - return status; -} - - -/* Fetch data that has previously been waited for. */ -static inline void fetch_data(char *buf, int n) -{ - insb(DATA_PORT, buf, n); - DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n)); -} - - -/* Flush status and data fifos */ -static inline void flush_data(void) -{ - while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT) - inb(DATA_PORT); - DEBUG((DEBUG_DRIVE_IF, "flushed fifos")); -} - -/* Command protocol */ - - -/* Send a simple command and wait for response. Command codes < COMFETCH - are quick response commands */ -static inline int exec_cmd(int cmd) -{ - int ack = send_cmd(cmd); - if (ack < 0) - return ack; - return get_exec_status(cmd < COMFETCH); -} - - -/* Send a command with parameters. Don't wait for the response, - * which consists of data blocks read from the CD. */ -static inline int exec_read_cmd(int cmd, struct cdrom_msf *params) -{ - int ack = send_cmd(cmd); - if (ack < 0) - return ack; - return send_params(params); -} - - -/* Send a seek command with parameters and wait for response */ -static inline int exec_seek_cmd(int cmd, struct cdrom_msf *params) -{ - int ack = send_cmd(cmd); - if (ack < 0) - return ack; - ack = send_seek_params(params); - if (ack < 0) - return ack; - return 0; -} - - -/* Send a command with parameters and wait for response */ -static inline int exec_long_cmd(int cmd, struct cdrom_msf *params) -{ - int ack = exec_read_cmd(cmd, params); - if (ack < 0) - return ack; - return get_exec_status(0); -} - -/* Address conversion routines */ - - -/* Binary to BCD (2 digits) */ -static inline void single_bin2bcd(u_char *p) -{ - DEBUG((DEBUG_CONV, "bin2bcd %02d", *p)); - *p = (*p % 10) | ((*p / 10) << 4); -} - - -/* Convert entire msf struct */ -static void bin2bcd(struct cdrom_msf *msf) -{ - single_bin2bcd(&msf->cdmsf_min0); - single_bin2bcd(&msf->cdmsf_sec0); - single_bin2bcd(&msf->cdmsf_frame0); - single_bin2bcd(&msf->cdmsf_min1); - single_bin2bcd(&msf->cdmsf_sec1); - single_bin2bcd(&msf->cdmsf_frame1); -} - - -/* Linear block address to minute, second, frame form */ -#define CD_FPM (CD_SECS * CD_FRAMES) /* frames per minute */ - -static void lba2msf(int lba, struct cdrom_msf *msf) -{ - DEBUG((DEBUG_CONV, "lba2msf %d", lba)); - lba += CD_MSF_OFFSET; - msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM; - msf->cdmsf_sec0 = lba / CD_FRAMES; - msf->cdmsf_frame0 = lba % CD_FRAMES; - msf->cdmsf_min1 = 0; - msf->cdmsf_sec1 = 0; - msf->cdmsf_frame1 = 0; - bin2bcd(msf); -} - - -/* Two BCD digits to binary */ -static inline u_char bcd2bin(u_char bcd) -{ - DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd)); - return (bcd >> 4) * 10 + (bcd & 0x0f); -} - - -static void msf2lba(union cdrom_addr *addr) -{ - addr->lba = addr->msf.minute * CD_FPM - + addr->msf.second * CD_FRAMES - + addr->msf.frame - CD_MSF_OFFSET; -} - - -/* Minute, second, frame address BCD to binary or to linear address, - depending on MODE */ -static void msf_bcd2bin(union cdrom_addr *addr) -{ - addr->msf.minute = bcd2bin(addr->msf.minute); - addr->msf.second = bcd2bin(addr->msf.second); - addr->msf.frame = bcd2bin(addr->msf.frame); -} - -/* High level drive commands */ - - -static int audio_status = CDROM_AUDIO_NO_STATUS; -static char toc_uptodate = 0; -static char disk_changed = 1; - -/* Get drive status, flagging completion of audio play and disk changes. */ -static int drive_status(void) -{ - int status; - - status = exec_cmd(COMIOCTLISTAT); - DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status)); - if (status < 0) - return status; - if (status == 0xff) /* No status available */ - return -ERR_IF_NOSTAT; - - if (((status & ST_MODE_BITS) != ST_M_AUDIO) && - (audio_status == CDROM_AUDIO_PLAY)) { - audio_status = CDROM_AUDIO_COMPLETED; - } - - if (status & ST_DSK_CHG) { - toc_uptodate = 0; - disk_changed = 1; - audio_status = CDROM_AUDIO_NO_STATUS; - } - - return status; -} - - -/* Read the current Q-channel info. Also used for reading the - table of contents. qp->cdsc_format must be set on entry to - indicate the desired address format */ -static int get_q_channel(struct cdrom_subchnl *qp) -{ - int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10; - - status = drive_status(); - if (status < 0) - return status; - qp->cdsc_audiostatus = audio_status; - - status = exec_cmd(COMSUBQ); - if (status < 0) - return status; - - d1 = get_data(0); - if (d1 < 0) - return d1; - qp->cdsc_adr = d1; - qp->cdsc_ctrl = d1 >> 4; - - d2 = get_data(0); - if (d2 < 0) - return d2; - qp->cdsc_trk = bcd2bin(d2); - - d3 = get_data(0); - if (d3 < 0) - return d3; - qp->cdsc_ind = bcd2bin(d3); - - d4 = get_data(0); - if (d4 < 0) - return d4; - qp->cdsc_reladdr.msf.minute = d4; - - d5 = get_data(0); - if (d5 < 0) - return d5; - qp->cdsc_reladdr.msf.second = d5; - - d6 = get_data(0); - if (d6 < 0) - return d6; - qp->cdsc_reladdr.msf.frame = d6; - - d7 = get_data(0); - if (d7 < 0) - return d7; - /* byte not used */ - - d8 = get_data(0); - if (d8 < 0) - return d8; - qp->cdsc_absaddr.msf.minute = d8; - - d9 = get_data(0); - if (d9 < 0) - return d9; - qp->cdsc_absaddr.msf.second = d9; - - d10 = get_data(0); - if (d10 < 0) - return d10; - qp->cdsc_absaddr.msf.frame = d10; - - DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - d1, d2, d3, d4, d5, d6, d7, d8, d9, d10)); - - msf_bcd2bin(&qp->cdsc_absaddr); - msf_bcd2bin(&qp->cdsc_reladdr); - if (qp->cdsc_format == CDROM_LBA) { - msf2lba(&qp->cdsc_absaddr); - msf2lba(&qp->cdsc_reladdr); - } - - return 0; -} - -/* Table of contents handling */ - - -/* Errors in table of contents */ -#define ERR_TOC_MISSINGINFO 0x120 -#define ERR_TOC_MISSINGENTRY 0x121 - - -struct cdrom_disk_info { - unsigned char first; - unsigned char last; - struct cdrom_msf0 disk_length; - struct cdrom_msf0 first_track; - /* Multisession info: */ - unsigned char next; - struct cdrom_msf0 next_session; - struct cdrom_msf0 last_session; - unsigned char multi; - unsigned char xa; - unsigned char audio; -}; -static struct cdrom_disk_info disk_info; - -#define MAX_TRACKS 111 -static struct cdrom_subchnl toc[MAX_TRACKS]; - -#define QINFO_FIRSTTRACK 100 /* bcd2bin(0xa0) */ -#define QINFO_LASTTRACK 101 /* bcd2bin(0xa1) */ -#define QINFO_DISKLENGTH 102 /* bcd2bin(0xa2) */ -#define QINFO_NEXTSESSION 110 /* bcd2bin(0xb0) */ - -#define I_FIRSTTRACK 0x01 -#define I_LASTTRACK 0x02 -#define I_DISKLENGTH 0x04 -#define I_NEXTSESSION 0x08 -#define I_ALL (I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH) - - -#if DEBUG_TOC -static void toc_debug_info(int i) -{ - printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d" - " %2d:%02d.%02d %2d:%02d.%02d\n", - i, toc[i].cdsc_ctrl, toc[i].cdsc_adr, - toc[i].cdsc_trk, toc[i].cdsc_ind, - toc[i].cdsc_reladdr.msf.minute, - toc[i].cdsc_reladdr.msf.second, - toc[i].cdsc_reladdr.msf.frame, - toc[i].cdsc_absaddr.msf.minute, - toc[i].cdsc_absaddr.msf.second, - toc[i].cdsc_absaddr.msf.frame); -} -#endif - - -static int read_toc(void) -{ - int status, limit, count; - unsigned char got_info = 0; - struct cdrom_subchnl q_info; -#if DEBUG_TOC - int i; -#endif - - DEBUG((DEBUG_TOC, "starting read_toc")); - - count = 0; - for (limit = 60; limit > 0; limit--) { - int index; - - q_info.cdsc_format = CDROM_MSF; - status = get_q_channel(&q_info); - if (status < 0) - return status; - - index = q_info.cdsc_ind; - if (index > 0 && index < MAX_TRACKS - && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) { - toc[index] = q_info; - DEBUG((DEBUG_TOC, "got %d", index)); - if (index < 100) - count++; - - switch (q_info.cdsc_ind) { - case QINFO_FIRSTTRACK: - got_info |= I_FIRSTTRACK; - break; - case QINFO_LASTTRACK: - got_info |= I_LASTTRACK; - break; - case QINFO_DISKLENGTH: - got_info |= I_DISKLENGTH; - break; - case QINFO_NEXTSESSION: - got_info |= I_NEXTSESSION; - break; - } - } - - if ((got_info & I_ALL) == I_ALL - && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count - >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1) - break; - } - - /* Construct disk_info from TOC */ - if (disk_info.first == 0) { - disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute; - disk_info.first_track.minute = - toc[disk_info.first].cdsc_absaddr.msf.minute; - disk_info.first_track.second = - toc[disk_info.first].cdsc_absaddr.msf.second; - disk_info.first_track.frame = - toc[disk_info.first].cdsc_absaddr.msf.frame; - } - disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute; - disk_info.disk_length.minute = - toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute; - disk_info.disk_length.second = - toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2; - disk_info.disk_length.frame = - toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame; - disk_info.next_session.minute = - toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute; - disk_info.next_session.second = - toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second; - disk_info.next_session.frame = - toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame; - disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute; - disk_info.last_session.minute = - toc[disk_info.next].cdsc_absaddr.msf.minute; - disk_info.last_session.second = - toc[disk_info.next].cdsc_absaddr.msf.second; - disk_info.last_session.frame = - toc[disk_info.next].cdsc_absaddr.msf.frame; - toc[disk_info.last + 1].cdsc_absaddr.msf.minute = - disk_info.disk_length.minute; - toc[disk_info.last + 1].cdsc_absaddr.msf.second = - disk_info.disk_length.second; - toc[disk_info.last + 1].cdsc_absaddr.msf.frame = - disk_info.disk_length.frame; -#if DEBUG_TOC - for (i = 1; i <= disk_info.last + 1; i++) - toc_debug_info(i); - toc_debug_info(QINFO_FIRSTTRACK); - toc_debug_info(QINFO_LASTTRACK); - toc_debug_info(QINFO_DISKLENGTH); - toc_debug_info(QINFO_NEXTSESSION); -#endif - - DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d", - got_info, count)); - if ((got_info & I_ALL) != I_ALL - || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count - < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1) - return -ERR_TOC_MISSINGINFO; - return 0; -} - - -#ifdef MULTISESSION -static int get_multi_disk_info(void) -{ - int sessions, status; - struct cdrom_msf multi_index; - - - for (sessions = 2; sessions < 10 /* %%for now */; sessions++) { - int count; - - for (count = 100; count < MAX_TRACKS; count++) - toc[count].cdsc_ind = 0; - - multi_index.cdmsf_min0 = disk_info.next_session.minute; - multi_index.cdmsf_sec0 = disk_info.next_session.second; - multi_index.cdmsf_frame0 = disk_info.next_session.frame; - if (multi_index.cdmsf_sec0 >= 20) - multi_index.cdmsf_sec0 -= 20; - else { - multi_index.cdmsf_sec0 += 40; - multi_index.cdmsf_min0--; - } - DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions, - multi_index.cdmsf_min0, - multi_index.cdmsf_sec0, - multi_index.cdmsf_frame0)); - bin2bcd(&multi_index); - multi_index.cdmsf_min1 = 0; - multi_index.cdmsf_sec1 = 0; - multi_index.cdmsf_frame1 = 1; - - status = exec_read_cmd(COMREAD, &multi_index); - if (status < 0) { - DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x", - -status)); - break; - } - status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ? - 0 : -ERR_TOC_MISSINGINFO; - flush_data(); - if (status < 0) { - DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status)); - break; - } - - status = read_toc(); - if (status < 0) { - DEBUG((DEBUG_TOC, "read_toc: %02x", -status)); - break; - } - - disk_info.multi = 1; - } - - exec_cmd(COMSTOP); - - if (status < 0) - return -EIO; - return 0; -} -#endif /* MULTISESSION */ - - -static int update_toc(void) -{ - int status, count; - - if (toc_uptodate) - return 0; - - DEBUG((DEBUG_TOC, "starting update_toc")); - - disk_info.first = 0; - for (count = 0; count < MAX_TRACKS; count++) - toc[count].cdsc_ind = 0; - - status = exec_cmd(COMLEADIN); - if (status < 0) - return -EIO; - - status = read_toc(); - if (status < 0) { - DEBUG((DEBUG_TOC, "read_toc: %02x", -status)); - return -EIO; - } - - /* Audio disk detection. Look at first track. */ - disk_info.audio = - (toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1; - - /* XA detection */ - disk_info.xa = drive_status() & ST_MODE2TRACK; - - /* Multisession detection: if we want this, define MULTISESSION */ - disk_info.multi = 0; -#ifdef MULTISESSION - if (disk_info.xa) - get_multi_disk_info(); /* Here disk_info.multi is set */ -#endif /* MULTISESSION */ - if (disk_info.multi) - printk(KERN_WARNING "optcd: Multisession support experimental, " - "see Documentation/cdrom/optcd\n"); - - DEBUG((DEBUG_TOC, "exiting update_toc")); - - toc_uptodate = 1; - return 0; -} - -/* Request handling */ - -static int current_valid(void) -{ - return CURRENT && - rq_data_dir(CURRENT) == READ && - CURRENT->sector != -1; -} - -/* Buffers for block size conversion. */ -#define NOBUF -1 - -static char buf[CD_FRAMESIZE * N_BUFS]; -static volatile int buf_bn[N_BUFS], next_bn; -static volatile int buf_in = 0, buf_out = NOBUF; - -static inline void opt_invalidate_buffers(void) -{ - int i; - - DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers")); - - for (i = 0; i < N_BUFS; i++) - buf_bn[i] = NOBUF; - buf_out = NOBUF; -} - - -/* Take care of the different block sizes between cdrom and Linux. - When Linux gets variable block sizes this will probably go away. */ -static void transfer(void) -{ -#if DEBUG_BUFFERS | DEBUG_REQUEST - printk(KERN_DEBUG "optcd: executing transfer\n"); -#endif - - if (!current_valid()) - return; - while (CURRENT -> nr_sectors) { - int bn = CURRENT -> sector / 4; - int i, offs, nr_sectors; - for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i); - - DEBUG((DEBUG_REQUEST, "found %d", i)); - - if (i >= N_BUFS) { - buf_out = NOBUF; - break; - } - - offs = (i * 4 + (CURRENT -> sector & 3)) * 512; - nr_sectors = 4 - (CURRENT -> sector & 3); - - if (buf_out != i) { - buf_out = i; - if (buf_bn[i] != bn) { - buf_out = NOBUF; - continue; - } - } - - if (nr_sectors > CURRENT -> nr_sectors) - nr_sectors = CURRENT -> nr_sectors; - memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512); - CURRENT -> nr_sectors -= nr_sectors; - CURRENT -> sector += nr_sectors; - CURRENT -> buffer += nr_sectors * 512; - } -} - - -/* State machine for reading disk blocks */ - -enum state_e { - S_IDLE, /* 0 */ - S_START, /* 1 */ - S_READ, /* 2 */ - S_DATA, /* 3 */ - S_STOP, /* 4 */ - S_STOPPING /* 5 */ -}; - -static volatile enum state_e state = S_IDLE; -#if DEBUG_STATE -static volatile enum state_e state_old = S_STOP; -static volatile int flags_old = 0; -static volatile long state_n = 0; -#endif - - -/* Used as mutex to keep do_optcd_request (and other processes calling - ioctl) out while some process is inside a VFS call. - Reverse is accomplished by checking if state = S_IDLE upon entry - of opt_ioctl and opt_media_change. */ -static int in_vfs = 0; - - -static volatile int transfer_is_active = 0; -static volatile int error = 0; /* %% do something with this?? */ -static int tries; /* ibid?? */ -static int timeout = 0; - -static void poll(unsigned long data); -static struct timer_list req_timer = {.function = poll}; - - -static void poll(unsigned long data) -{ - static volatile int read_count = 1; - int flags; - int loop_again = 1; - int status = 0; - int skip = 0; - - if (error) { - printk(KERN_ERR "optcd: I/O error 0x%02x\n", error); - opt_invalidate_buffers(); - if (!tries--) { - printk(KERN_ERR "optcd: read block %d failed;" - " Giving up\n", next_bn); - if (transfer_is_active) - loop_again = 0; - if (current_valid()) - end_request(CURRENT, 0); - tries = 5; - } - error = 0; - state = S_STOP; - } - - while (loop_again) - { - loop_again = 0; /* each case must flip this back to 1 if we want - to come back up here */ - -#if DEBUG_STATE - if (state == state_old) - state_n++; - else { - state_old = state; - if (++state_n > 1) - printk(KERN_DEBUG "optcd: %ld times " - "in previous state\n", state_n); - printk(KERN_DEBUG "optcd: state %d\n", state); - state_n = 0; - } -#endif - - switch (state) { - case S_IDLE: - return; - case S_START: - if (in_vfs) - break; - if (send_cmd(COMDRVST)) { - state = S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - state = S_READ; - timeout = READ_TIMEOUT; - break; - case S_READ: { - struct cdrom_msf msf; - if (!skip) { - status = fetch_status(); - if (status < 0) - break; - if (status & ST_DSK_CHG) { - toc_uptodate = 0; - opt_invalidate_buffers(); - } - } - skip = 0; - if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) { - toc_uptodate = 0; - opt_invalidate_buffers(); - printk(KERN_WARNING "optcd: %s\n", - (status & ST_DOOR_OPEN) - ? "door open" - : "disk removed"); - state = S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - if (!current_valid()) { - state = S_STOP; - loop_again = 1; - break; - } - next_bn = CURRENT -> sector / 4; - lba2msf(next_bn, &msf); - read_count = N_BUFS; - msf.cdmsf_frame1 = read_count; /* Not BCD! */ - - DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x", - msf.cdmsf_min0, - msf.cdmsf_sec0, - msf.cdmsf_frame0, - msf.cdmsf_min1, - msf.cdmsf_sec1, - msf.cdmsf_frame1)); - DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d" - " buf_out:%d buf_bn:%d", - next_bn, - buf_in, - buf_out, - buf_bn[buf_in])); - - exec_read_cmd(COMREAD, &msf); - state = S_DATA; - timeout = READ_TIMEOUT; - break; - } - case S_DATA: - flags = stdt_flags() & (FL_STEN|FL_DTEN); - -#if DEBUG_STATE - if (flags != flags_old) { - flags_old = flags; - printk(KERN_DEBUG "optcd: flags:%x\n", flags); - } - if (flags == FL_STEN) - printk(KERN_DEBUG "timeout cnt: %d\n", timeout); -#endif - - switch (flags) { - case FL_DTEN: /* only STEN low */ - if (!tries--) { - printk(KERN_ERR - "optcd: read block %d failed; " - "Giving up\n", next_bn); - if (transfer_is_active) { - tries = 0; - break; - } - if (current_valid()) - end_request(CURRENT, 0); - tries = 5; - } - state = S_START; - timeout = READ_TIMEOUT; - loop_again = 1; - case (FL_STEN|FL_DTEN): /* both high */ - break; - default: /* DTEN low */ - tries = 5; - if (!current_valid() && buf_in == buf_out) { - state = S_STOP; - loop_again = 1; - break; - } - if (read_count<=0) - printk(KERN_WARNING - "optcd: warning - try to read" - " 0 frames\n"); - while (read_count) { - buf_bn[buf_in] = NOBUF; - if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) { - /* should be no waiting here!?? */ - printk(KERN_ERR - "read_count:%d " - "CURRENT->nr_sectors:%ld " - "buf_in:%d\n", - read_count, - CURRENT->nr_sectors, - buf_in); - printk(KERN_ERR - "transfer active: %x\n", - transfer_is_active); - read_count = 0; - state = S_STOP; - loop_again = 1; - end_request(CURRENT, 0); - break; - } - fetch_data(buf+ - CD_FRAMESIZE*buf_in, - CD_FRAMESIZE); - read_count--; - - DEBUG((DEBUG_REQUEST, - "S_DATA; ---I've read data- " - "read_count: %d", - read_count)); - DEBUG((DEBUG_REQUEST, - "next_bn:%d buf_in:%d " - "buf_out:%d buf_bn:%d", - next_bn, - buf_in, - buf_out, - buf_bn[buf_in])); - - buf_bn[buf_in] = next_bn++; - if (buf_out == NOBUF) - buf_out = buf_in; - buf_in = buf_in + 1 == - N_BUFS ? 0 : buf_in + 1; - } - if (!transfer_is_active) { - while (current_valid()) { - transfer(); - if (CURRENT -> nr_sectors == 0) - end_request(CURRENT, 1); - else - break; - } - } - - if (current_valid() - && (CURRENT -> sector / 4 < next_bn || - CURRENT -> sector / 4 > - next_bn + N_BUFS)) { - state = S_STOP; - loop_again = 1; - break; - } - timeout = READ_TIMEOUT; - if (read_count == 0) { - state = S_STOP; - loop_again = 1; - break; - } - } - break; - case S_STOP: - if (read_count != 0) - printk(KERN_ERR - "optcd: discard data=%x frames\n", - read_count); - flush_data(); - if (send_cmd(COMDRVST)) { - state = S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - state = S_STOPPING; - timeout = STOP_TIMEOUT; - break; - case S_STOPPING: - status = fetch_status(); - if (status < 0 && timeout) - break; - if ((status >= 0) && (status & ST_DSK_CHG)) { - toc_uptodate = 0; - opt_invalidate_buffers(); - } - if (current_valid()) { - if (status >= 0) { - state = S_READ; - loop_again = 1; - skip = 1; - break; - } else { - state = S_START; - timeout = 1; - } - } else { - state = S_IDLE; - return; - } - break; - default: - printk(KERN_ERR "optcd: invalid state %d\n", state); - return; - } /* case */ - } /* while */ - - if (!timeout--) { - printk(KERN_ERR "optcd: timeout in state %d\n", state); - state = S_STOP; - if (exec_cmd(COMSTOP) < 0) { - state = S_IDLE; - while (current_valid()) - end_request(CURRENT, 0); - return; - } - } - - mod_timer(&req_timer, jiffies + HZ/100); -} - - -static void do_optcd_request(request_queue_t * q) -{ - DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)", - CURRENT -> sector, CURRENT -> nr_sectors)); - - if (disk_info.audio) { - printk(KERN_WARNING "optcd: tried to mount an Audio CD\n"); - end_request(CURRENT, 0); - return; - } - - transfer_is_active = 1; - while (current_valid()) { - transfer(); /* First try to transfer block from buffers */ - if (CURRENT -> nr_sectors == 0) { - end_request(CURRENT, 1); - } else { /* Want to read a block not in buffer */ - buf_out = NOBUF; - if (state == S_IDLE) { - /* %% Should this block the request queue?? */ - if (update_toc() < 0) { - while (current_valid()) - end_request(CURRENT, 0); - break; - } - /* Start state machine */ - state = S_START; - timeout = READ_TIMEOUT; - tries = 5; - /* %% why not start right away?? */ - mod_timer(&req_timer, jiffies + HZ/100); - } - break; - } - } - transfer_is_active = 0; - - DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d buf_out:%d buf_bn:%d", - next_bn, buf_in, buf_out, buf_bn[buf_in])); - DEBUG((DEBUG_REQUEST, "do_optcd_request ends")); -} - -/* IOCTLs */ - - -static char auto_eject = 0; - -static int cdrompause(void) -{ - int status; - - if (audio_status != CDROM_AUDIO_PLAY) - return -EINVAL; - - status = exec_cmd(COMPAUSEON); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status)); - return -EIO; - } - audio_status = CDROM_AUDIO_PAUSED; - return 0; -} - - -static int cdromresume(void) -{ - int status; - - if (audio_status != CDROM_AUDIO_PAUSED) - return -EINVAL; - - status = exec_cmd(COMPAUSEOFF); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status)); - audio_status = CDROM_AUDIO_ERROR; - return -EIO; - } - audio_status = CDROM_AUDIO_PLAY; - return 0; -} - - -static int cdromplaymsf(void __user *arg) -{ - int status; - struct cdrom_msf msf; - - if (copy_from_user(&msf, arg, sizeof msf)) - return -EFAULT; - - bin2bcd(&msf); - status = exec_long_cmd(COMPLAY, &msf); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status)); - audio_status = CDROM_AUDIO_ERROR; - return -EIO; - } - - audio_status = CDROM_AUDIO_PLAY; - return 0; -} - - -static int cdromplaytrkind(void __user *arg) -{ - int status; - struct cdrom_ti ti; - struct cdrom_msf msf; - - if (copy_from_user(&ti, arg, sizeof ti)) - return -EFAULT; - - if (ti.cdti_trk0 < disk_info.first - || ti.cdti_trk0 > disk_info.last - || ti.cdti_trk1 < ti.cdti_trk0) - return -EINVAL; - if (ti.cdti_trk1 > disk_info.last) - ti.cdti_trk1 = disk_info.last; - - msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute; - msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second; - msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame; - msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute; - msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second; - msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame; - - DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d", - msf.cdmsf_min0, - msf.cdmsf_sec0, - msf.cdmsf_frame0, - msf.cdmsf_min1, - msf.cdmsf_sec1, - msf.cdmsf_frame1)); - - bin2bcd(&msf); - status = exec_long_cmd(COMPLAY, &msf); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status)); - audio_status = CDROM_AUDIO_ERROR; - return -EIO; - } - - audio_status = CDROM_AUDIO_PLAY; - return 0; -} - - -static int cdromreadtochdr(void __user *arg) -{ - struct cdrom_tochdr tochdr; - - tochdr.cdth_trk0 = disk_info.first; - tochdr.cdth_trk1 = disk_info.last; - - return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0; -} - - -static int cdromreadtocentry(void __user *arg) -{ - struct cdrom_tocentry entry; - struct cdrom_subchnl *tocptr; - - if (copy_from_user(&entry, arg, sizeof entry)) - return -EFAULT; - - if (entry.cdte_track == CDROM_LEADOUT) - tocptr = &toc[disk_info.last + 1]; - else if (entry.cdte_track > disk_info.last - || entry.cdte_track < disk_info.first) - return -EINVAL; - else - tocptr = &toc[entry.cdte_track]; - - entry.cdte_adr = tocptr->cdsc_adr; - entry.cdte_ctrl = tocptr->cdsc_ctrl; - entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute; - entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second; - entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame; - /* %% What should go into entry.cdte_datamode? */ - - if (entry.cdte_format == CDROM_LBA) - msf2lba(&entry.cdte_addr); - else if (entry.cdte_format != CDROM_MSF) - return -EINVAL; - - return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0; -} - - -static int cdromvolctrl(void __user *arg) -{ - int status; - struct cdrom_volctrl volctrl; - struct cdrom_msf msf; - - if (copy_from_user(&volctrl, arg, sizeof volctrl)) - return -EFAULT; - - msf.cdmsf_min0 = 0x10; - msf.cdmsf_sec0 = 0x32; - msf.cdmsf_frame0 = volctrl.channel0; - msf.cdmsf_min1 = volctrl.channel1; - msf.cdmsf_sec1 = volctrl.channel2; - msf.cdmsf_frame1 = volctrl.channel3; - - status = exec_long_cmd(COMCHCTRL, &msf); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status)); - return -EIO; - } - return 0; -} - - -static int cdromsubchnl(void __user *arg) -{ - int status; - struct cdrom_subchnl subchnl; - - if (copy_from_user(&subchnl, arg, sizeof subchnl)) - return -EFAULT; - - if (subchnl.cdsc_format != CDROM_LBA - && subchnl.cdsc_format != CDROM_MSF) - return -EINVAL; - - status = get_q_channel(&subchnl); - if (status < 0) { - DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status)); - return -EIO; - } - - if (copy_to_user(arg, &subchnl, sizeof subchnl)) - return -EFAULT; - return 0; -} - - -static struct gendisk *optcd_disk; - - -static int cdromread(void __user *arg, int blocksize, int cmd) -{ - int status; - struct cdrom_msf msf; - - if (copy_from_user(&msf, arg, sizeof msf)) - return -EFAULT; - - bin2bcd(&msf); - msf.cdmsf_min1 = 0; - msf.cdmsf_sec1 = 0; - msf.cdmsf_frame1 = 1; /* read only one frame */ - status = exec_read_cmd(cmd, &msf); - - DEBUG((DEBUG_VFS, "read cmd status 0x%x", status)); - - if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT)) - return -EIO; - - fetch_data(optcd_disk->private_data, blocksize); - - if (copy_to_user(arg, optcd_disk->private_data, blocksize)) - return -EFAULT; - - return 0; -} - - -static int cdromseek(void __user *arg) -{ - int status; - struct cdrom_msf msf; - - if (copy_from_user(&msf, arg, sizeof msf)) - return -EFAULT; - - bin2bcd(&msf); - status = exec_seek_cmd(COMSEEK, &msf); - - DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status)); - - if (status < 0) - return -EIO; - return 0; -} - - -#ifdef MULTISESSION -static int cdrommultisession(void __user *arg) -{ - struct cdrom_multisession ms; - - if (copy_from_user(&ms, arg, sizeof ms)) - return -EFAULT; - - ms.addr.msf.minute = disk_info.last_session.minute; - ms.addr.msf.second = disk_info.last_session.second; - ms.addr.msf.frame = disk_info.last_session.frame; - - if (ms.addr_format != CDROM_LBA - && ms.addr_format != CDROM_MSF) - return -EINVAL; - if (ms.addr_format == CDROM_LBA) - msf2lba(&ms.addr); - - ms.xa_flag = disk_info.xa; - - if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession))) - return -EFAULT; - -#if DEBUG_MULTIS - if (ms.addr_format == CDROM_MSF) - printk(KERN_DEBUG - "optcd: multisession xa:%d, msf:%02d:%02d.%02d\n", - ms.xa_flag, - ms.addr.msf.minute, - ms.addr.msf.second, - ms.addr.msf.frame); - else - printk(KERN_DEBUG - "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n", - ms.xa_flag, - ms.addr.lba, - disk_info.last_session.minute, - disk_info.last_session.second, - disk_info.last_session.frame); -#endif /* DEBUG_MULTIS */ - - return 0; -} -#endif /* MULTISESSION */ - - -static int cdromreset(void) -{ - if (state != S_IDLE) { - error = 1; - tries = 0; - } - - toc_uptodate = 0; - disk_changed = 1; - opt_invalidate_buffers(); - audio_status = CDROM_AUDIO_NO_STATUS; - - if (!reset_drive()) - return -EIO; - return 0; -} - -/* VFS calls */ - - -static int opt_ioctl(struct inode *ip, struct file *fp, - unsigned int cmd, unsigned long arg) -{ - int status, err, retval = 0; - void __user *argp = (void __user *)arg; - - DEBUG((DEBUG_VFS, "starting opt_ioctl")); - - if (!ip) - return -EINVAL; - - if (cmd == CDROMRESET) - return cdromreset(); - - /* is do_optcd_request or another ioctl busy? */ - if (state != S_IDLE || in_vfs) - return -EBUSY; - - in_vfs = 1; - - status = drive_status(); - if (status < 0) { - DEBUG((DEBUG_VFS, "drive_status: %02x", -status)); - in_vfs = 0; - return -EIO; - } - - if (status & ST_DOOR_OPEN) - switch (cmd) { /* Actions that can be taken with door open */ - case CDROMCLOSETRAY: - /* We do this before trying to read the toc. */ - err = exec_cmd(COMCLOSE); - if (err < 0) { - DEBUG((DEBUG_VFS, - "exec_cmd COMCLOSE: %02x", -err)); - in_vfs = 0; - return -EIO; - } - break; - default: in_vfs = 0; - return -EBUSY; - } - - err = update_toc(); - if (err < 0) { - DEBUG((DEBUG_VFS, "update_toc: %02x", -err)); - in_vfs = 0; - return -EIO; - } - - DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd)); - - switch (cmd) { - case CDROMPAUSE: retval = cdrompause(); break; - case CDROMRESUME: retval = cdromresume(); break; - case CDROMPLAYMSF: retval = cdromplaymsf(argp); break; - case CDROMPLAYTRKIND: retval = cdromplaytrkind(argp); break; - case CDROMREADTOCHDR: retval = cdromreadtochdr(argp); break; - case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break; - - case CDROMSTOP: err = exec_cmd(COMSTOP); - if (err < 0) { - DEBUG((DEBUG_VFS, - "exec_cmd COMSTOP: %02x", - -err)); - retval = -EIO; - } else - audio_status = CDROM_AUDIO_NO_STATUS; - break; - case CDROMSTART: break; /* This is a no-op */ - case CDROMEJECT: err = exec_cmd(COMUNLOCK); - if (err < 0) { - DEBUG((DEBUG_VFS, - "exec_cmd COMUNLOCK: %02x", - -err)); - retval = -EIO; - break; - } - err = exec_cmd(COMOPEN); - if (err < 0) { - DEBUG((DEBUG_VFS, - "exec_cmd COMOPEN: %02x", - -err)); - retval = -EIO; - } - break; - - case CDROMVOLCTRL: retval = cdromvolctrl(argp); break; - case CDROMSUBCHNL: retval = cdromsubchnl(argp); break; - - /* The drive detects the mode and automatically delivers the - correct 2048 bytes, so we don't need these IOCTLs */ - case CDROMREADMODE2: retval = -EINVAL; break; - case CDROMREADMODE1: retval = -EINVAL; break; - - /* Drive doesn't support reading audio */ - case CDROMREADAUDIO: retval = -EINVAL; break; - - case CDROMEJECT_SW: auto_eject = (char) arg; - break; - -#ifdef MULTISESSION - case CDROMMULTISESSION: retval = cdrommultisession(argp); break; -#endif - - case CDROM_GET_MCN: retval = -EINVAL; break; /* not implemented */ - case CDROMVOLREAD: retval = -EINVAL; break; /* not implemented */ - - case CDROMREADRAW: - /* this drive delivers 2340 bytes in raw mode */ - retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW); - break; - case CDROMREADCOOKED: - retval = cdromread(argp, CD_FRAMESIZE, COMREAD); - break; - case CDROMREADALL: - retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL); - break; - - case CDROMSEEK: retval = cdromseek(argp); break; - case CDROMPLAYBLK: retval = -EINVAL; break; /* not implemented */ - case CDROMCLOSETRAY: break; /* The action was taken earlier */ - default: retval = -EINVAL; - } - in_vfs = 0; - return retval; -} - - -static int open_count = 0; - -/* Open device special file; check that a disk is in. */ -static int opt_open(struct inode *ip, struct file *fp) -{ - DEBUG((DEBUG_VFS, "starting opt_open")); - - if (!open_count && state == S_IDLE) { - int status; - char *buf; - - buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL); - if (!buf) { - printk(KERN_INFO "optcd: cannot allocate read buffer\n"); - return -ENOMEM; - } - optcd_disk->private_data = buf; /* save read buffer */ - - toc_uptodate = 0; - opt_invalidate_buffers(); - - status = exec_cmd(COMCLOSE); /* close door */ - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status)); - } - - status = drive_status(); - if (status < 0) { - DEBUG((DEBUG_VFS, "drive_status: %02x", -status)); - goto err_out; - } - DEBUG((DEBUG_VFS, "status: %02x", status)); - if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) { - printk(KERN_INFO "optcd: no disk or door open\n"); - goto err_out; - } - status = exec_cmd(COMLOCK); /* Lock door */ - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status)); - } - status = update_toc(); /* Read table of contents */ - if (status < 0) { - DEBUG((DEBUG_VFS, "update_toc: %02x", -status)); - status = exec_cmd(COMUNLOCK); /* Unlock door */ - if (status < 0) { - DEBUG((DEBUG_VFS, - "exec_cmd COMUNLOCK: %02x", -status)); - } - goto err_out; - } - open_count++; - } - - DEBUG((DEBUG_VFS, "exiting opt_open")); - - return 0; - -err_out: - return -EIO; -} - - -/* Release device special file; flush all blocks from the buffer cache */ -static int opt_release(struct inode *ip, struct file *fp) -{ - int status; - - DEBUG((DEBUG_VFS, "executing opt_release")); - DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n", - ip, ip->i_bdev->bd_disk->disk_name, fp)); - - if (!--open_count) { - toc_uptodate = 0; - opt_invalidate_buffers(); - status = exec_cmd(COMUNLOCK); /* Unlock door */ - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status)); - } - if (auto_eject) { - status = exec_cmd(COMOPEN); - DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status)); - } - kfree(optcd_disk->private_data); - del_timer(&delay_timer); - del_timer(&req_timer); - } - return 0; -} - - -/* Check if disk has been changed */ -static int opt_media_change(struct gendisk *disk) -{ - DEBUG((DEBUG_VFS, "executing opt_media_change")); - DEBUG((DEBUG_VFS, "dev: %s; disk_changed = %d\n", - disk->disk_name, disk_changed)); - - if (disk_changed) { - disk_changed = 0; - return 1; - } - return 0; -} - -/* Driver initialisation */ - - -/* Returns 1 if a drive is detected with a version string - starting with "DOLPHIN". Otherwise 0. */ -static int __init version_ok(void) -{ - char devname[100]; - int count, i, ch, status; - - status = exec_cmd(COMVERSION); - if (status < 0) { - DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status)); - return 0; - } - if ((count = get_data(1)) < 0) { - DEBUG((DEBUG_VFS, "get_data(1): %02x", -count)); - return 0; - } - for (i = 0, ch = -1; count > 0; count--) { - if ((ch = get_data(1)) < 0) { - DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch)); - break; - } - if (i < 99) - devname[i++] = ch; - } - devname[i] = '\0'; - if (ch < 0) - return 0; - - printk(KERN_INFO "optcd: Device %s detected\n", devname); - return ((devname[0] == 'D') - && (devname[1] == 'O') - && (devname[2] == 'L') - && (devname[3] == 'P') - && (devname[4] == 'H') - && (devname[5] == 'I') - && (devname[6] == 'N')); -} - - -static struct block_device_operations opt_fops = { - .owner = THIS_MODULE, - .open = opt_open, - .release = opt_release, - .ioctl = opt_ioctl, - .media_changed = opt_media_change, -}; - -#ifndef MODULE -/* Get kernel parameter when used as a kernel driver */ -static int optcd_setup(char *str) -{ - int ints[4]; - (void)get_options(str, ARRAY_SIZE(ints), ints); - - if (ints[0] > 0) - optcd_port = ints[1]; - - return 1; -} - -__setup("optcd=", optcd_setup); - -#endif /* MODULE */ - -/* Test for presence of drive and initialize it. Called at boot time - or during module initialisation. */ -static int __init optcd_init(void) -{ - int status; - - if (optcd_port <= 0) { - printk(KERN_INFO - "optcd: no Optics Storage CDROM Initialization\n"); - return -EIO; - } - optcd_disk = alloc_disk(1); - if (!optcd_disk) { - printk(KERN_ERR "optcd: can't allocate disk\n"); - return -ENOMEM; - } - optcd_disk->major = MAJOR_NR; - optcd_disk->first_minor = 0; - optcd_disk->fops = &opt_fops; - sprintf(optcd_disk->disk_name, "optcd"); - - if (!request_region(optcd_port, 4, "optcd")) { - printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n", - optcd_port); - put_disk(optcd_disk); - return -EIO; - } - - if (!reset_drive()) { - printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port); - release_region(optcd_port, 4); - put_disk(optcd_disk); - return -EIO; - } - if (!version_ok()) { - printk(KERN_ERR "optcd: unknown drive detected; aborting\n"); - release_region(optcd_port, 4); - put_disk(optcd_disk); - return -EIO; - } - status = exec_cmd(COMINITDOUBLE); - if (status < 0) { - printk(KERN_ERR "optcd: cannot init double speed mode\n"); - release_region(optcd_port, 4); - DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status)); - put_disk(optcd_disk); - return -EIO; - } - if (register_blkdev(MAJOR_NR, "optcd")) { - release_region(optcd_port, 4); - put_disk(optcd_disk); - return -EIO; - } - - - opt_queue = blk_init_queue(do_optcd_request, &optcd_lock); - if (!opt_queue) { - unregister_blkdev(MAJOR_NR, "optcd"); - release_region(optcd_port, 4); - put_disk(optcd_disk); - return -ENOMEM; - } - - blk_queue_hardsect_size(opt_queue, 2048); - optcd_disk->queue = opt_queue; - add_disk(optcd_disk); - - printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port); - return 0; -} - - -static void __exit optcd_exit(void) -{ - del_gendisk(optcd_disk); - put_disk(optcd_disk); - if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) { - printk(KERN_ERR "optcd: what's that: can't unregister\n"); - return; - } - blk_cleanup_queue(opt_queue); - release_region(optcd_port, 4); - printk(KERN_INFO "optcd: module released.\n"); -} - -module_init(optcd_init); -module_exit(optcd_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR); diff --git a/drivers/cdrom/optcd.h b/drivers/cdrom/optcd.h deleted file mode 100644 index 1911bb92ee28..000000000000 --- a/drivers/cdrom/optcd.h +++ /dev/null @@ -1,52 +0,0 @@ -/* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver - $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $ - - Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl) - - - Configuration file for linux/drivers/cdrom/optcd.c -*/ - -#ifndef _LINUX_OPTCD_H -#define _LINUX_OPTCD_H - - -/* I/O base of drive. Drive uses base to base+2. - This setting can be overridden with the kernel or insmod command - line option 'optcd='. Use address of 0 to disable driver. */ -#define OPTCD_PORTBASE 0x340 - - -/* enable / disable parts of driver by define / undef */ -#define MULTISESSION /* multisession support (ALPHA) */ - - -/* Change 0 to 1 to debug various parts of the driver */ -#define DEBUG_DRIVE_IF 0 /* Low level drive interface */ -#define DEBUG_CONV 0 /* Address conversions */ -#define DEBUG_BUFFERS 0 /* Buffering and block size conversion */ -#define DEBUG_REQUEST 0 /* Request mechanism */ -#define DEBUG_STATE 0 /* State machine */ -#define DEBUG_TOC 0 /* Q-channel and Table of Contents */ -#define DEBUG_MULTIS 0 /* Multisession code */ -#define DEBUG_VFS 0 /* VFS interface */ - - -/* Don't touch these unless you know what you're doing. */ - -/* Various timeout loop repetition counts. */ -#define BUSY_TIMEOUT 10000000 /* for busy wait */ -#define FAST_TIMEOUT 100000 /* ibid. for probing */ -#define SLEEP_TIMEOUT 6000 /* for timer wait */ -#define MULTI_SEEK_TIMEOUT 1000 /* for timer wait */ -#define READ_TIMEOUT 6000 /* for poll wait */ -#define STOP_TIMEOUT 2000 /* for poll wait */ -#define RESET_WAIT 5000 /* busy wait at drive reset */ - -/* # of buffers for block size conversion. 6 is optimal for my setup (P75), - giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal - setting */ -#define N_BUFS 6 - - -#endif /* _LINUX_OPTCD_H */ diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c deleted file mode 100644 index a1283b1ef989..000000000000 --- a/drivers/cdrom/sbpcd.c +++ /dev/null @@ -1,5966 +0,0 @@ -/* - * sbpcd.c CD-ROM device driver for the whole family of traditional, - * non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives. - * Works with SoundBlaster compatible cards and with "no-sound" - * interface cards like Lasermate, Panasonic CI-101P, Teac, ... - * Also for the Longshine LCS-7260 drive. - * Also for the IBM "External ISA CD-Rom" drive. - * Also for the CreativeLabs CD200 drive. - * Also for the TEAC CD-55A drive. - * Also for the ECS-AT "Vertos 100" drive. - * Not for Sanyo drives (but for the H94A, sjcd is there...). - * Not for any other Funai drives than the CD200 types (sometimes - * labelled E2550UA or MK4015 or 2800F). - */ - -#define VERSION "v4.63 Andrew J. Kroll Wed Jul 26 04:24:10 EDT 2000" - -/* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * You should have received a copy of the GNU General Public License - * (for example /usr/src/linux/COPYING); if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * If you change this software, you should mail a .diff file with some - * description lines to emoenke@gwdg.de. I want to know about it. - * - * If you are the editor of a Linux CD, you should enable sbpcd.c within - * your boot floppy kernel and send me one of your CDs for free. - * - * If you would like to port the driver to an other operating system (f.e. - * FreeBSD or NetBSD) or use it as an information source, you shall not be - * restricted by the GPL under the following conditions: - * a) the source code of your work is freely available - * b) my part of the work gets mentioned at all places where your - * authorship gets mentioned - * c) I receive a copy of your code together with a full installation - * package of your operating system for free. - * - * - * VERSION HISTORY - * - * 0.1 initial release, April/May 93, after mcd.c (Martin Harriss) - * - * 0.2 thek "repeat:"-loop in do_sbpcd_request did not check for - * end-of-request_queue (resulting in kernel panic). - * Flow control seems stable, but throughput is not better. - * - * 0.3 interrupt locking totally eliminated (maybe "inb" and "outb" - * are still locking) - 0.2 made keyboard-type-ahead losses. - * check_sbpcd_media_change added (to use by isofs/inode.c) - * - but it detects almost nothing. - * - * 0.4 use MAJOR 25 definitely. - * Almost total re-design to support double-speed drives and - * "naked" (no sound) interface cards ("LaserMate" interface type). - * Flow control should be exact now. - * Don't occupy the SbPro IRQ line (not needed either); will - * live together with Hannu Savolainen's sndkit now. - * Speeded up data transfer to 150 kB/sec, with help from Kai - * Makisara, the "provider" of the "mt" tape utility. - * Give "SpinUp" command if necessary. - * First steps to support up to 4 drives (but currently only one). - * Implemented audio capabilities - workman should work, xcdplayer - * gives some problems. - * This version is still consuming too much CPU time, and - * sleeping still has to be worked on. - * During "long" implied seeks, it seems possible that a - * ReadStatus command gets ignored. That gives the message - * "ResponseStatus timed out" (happens about 6 times here during - * a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is - * handled without data error, but it should get done better. - * - * 0.5 Free CPU during waits (again with help from Kai Makisara). - * Made it work together with the LILO/kernel setup standard. - * Included auto-probing code, as suggested by YGGDRASIL. - * Formal redesign to add DDI debugging. - * There are still flaws in IOCTL (workman with double speed drive). - * - * 1.0 Added support for all drive IDs (0...3, no longer only 0) - * and up to 4 drives on one controller. - * Added "#define MANY_SESSION" for "old" multi session CDs. - * - * 1.1 Do SpinUp for new drives, too. - * Revised for clean compile under "old" kernels (0.99pl9). - * - * 1.2 Found the "workman with double-speed drive" bug: use the driver's - * audio_state, not what the drive is reporting with ReadSubQ. - * - * 1.3 Minor cleanups. - * Refinements regarding Workman. - * - * 1.4 Read XA disks (PhotoCDs) with "old" drives, too (but only the first - * session - no chance to fully access a "multi-session" CD). - * This currently still is too slow (50 kB/sec) - but possibly - * the old drives won't do it faster. - * Implemented "door (un)lock" for new drives (still does not work - * as wanted - no lock possible after an unlock). - * Added some debugging printout for the UPC/EAN code - but my drives - * return only zeroes. Is there no UPC/EAN code written? - * - * 1.5 Laborate with UPC/EAN code (not better yet). - * Adapt to kernel 1.1.8 change (have to explicitly include - * now). - * - * 1.6 Trying to read audio frames as data. Impossible with the current - * drive firmware levels, as it seems. Awaiting any hint. ;-) - * Changed "door unlock": repeat it until success. - * Changed CDROMSTOP routine (stop somewhat "softer" so that Workman - * won't get confused). - * Added a third interface type: Sequoia S-1000, as used with the SPEA - * Media FX sound card. This interface (usable for Sony and Mitsumi - * drives, too) needs a special configuration setup and behaves like a - * LaserMate type after that. Still experimental - I do not have such - * an interface. - * Use the "variable BLOCK_SIZE" feature (2048). But it does only work - * if you give the mount option "block=2048". - * The media_check routine is currently disabled; now that it gets - * called as it should I fear it must get synchronized for not to - * disturb the normal driver's activity. - * - * 2.0 Version number bumped - two reasons: - * - reading audio tracks as data works now with CR-562 and CR-563. We - * currently do it by an IOCTL (yet has to get standardized), one frame - * at a time; that is pretty slow. But it works. - * - we are maintaining now up to 4 interfaces (each up to 4 drives): - * did it the easy way - a different MAJOR (25, 26, ...) and a different - * copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only - * distinguished by the value of SBPCD_ISSUE and the driver's name), - * and a common sbpcd.h file. - * Bettered the "ReadCapacity error" problem with old CR-52x drives (the - * drives sometimes need a manual "eject/insert" before work): just - * reset the drive and do again. Needs lots of resets here and sometimes - * that does not cure, so this can't be the solution. - * - * 2.1 Found bug with multisession CDs (accessing frame 16). - * "read audio" works now with address type CDROM_MSF, too. - * Bigger audio frame buffer: allows reading max. 4 frames at time; this - * gives a significant speedup, but reading more than one frame at once - * gives missing chunks at each single frame boundary. - * - * 2.2 Kernel interface cleanups: timers, init, setup, media check. - * - * 2.3 Let "door lock" and "eject" live together. - * Implemented "close tray" (done automatically during open). - * - * 2.4 Use different names for device registering. - * - * 2.5 Added "#if EJECT" code (default: enabled) to automatically eject - * the tray during last call to "sbpcd_release". - * Added "#if JUKEBOX" code (default: disabled) to automatically eject - * the tray during call to "sbpcd_open" if no disk is in. - * Turn on the CD volume of "compatible" sound cards, too; just define - * SOUND_BASE (in sbpcd.h) accordingly (default: disabled). - * - * 2.6 Nothing new. - * - * 2.7 Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly: - * 0 disables, 1 enables auto-ejecting. Useful to keep the tray in - * during shutdown. - * - * 2.8 Added first support (still BETA, I need feedback or a drive) for - * the Longshine LCS-7260 drives. They appear as double-speed drives - * using the "old" command scheme, extended by tray control and door - * lock functions. - * Found (and fixed preliminary) a flaw with some multisession CDs: we - * have to re-direct not only the accesses to frame 16 (the isofs - * routines drive it up to max. 100), but also those to the continuation - * (repetition) frames (as far as they exist - currently set fix as - * 16..20). - * Changed default of the "JUKEBOX" define. If you use this default, - * your tray will eject if you try to mount without a disk in. Next - * mount command will insert the tray - so, just fill in a disk. ;-) - * - * 2.9 Fulfilled the Longshine LCS-7260 support; with great help and - * experiments by Serge Robyns. - * First attempts to support the TEAC CD-55A drives; but still not - * usable yet. - * Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle - * multi session CDs more "transparent" (redirection handling has to be - * done within the isofs routines, and only for the special purpose of - * obtaining the "right" volume descriptor; accesses to the raw device - * should not get redirected). - * - * 3.0 Just a "normal" increment, with some provisions to do it better. ;-) - * Introduced "#define READ_AUDIO" to specify the maximum number of - * audio frames to grab with one request. This defines a buffer size - * within kernel space; a value of 0 will reserve no such space and - * disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading - * of a whole second with one command, but will use a buffer of more - * than 172 kB. - * Started CD200 support. Drive detection should work, but nothing - * more. - * - * 3.1 Working to support the CD200 and the Teac CD-55A drives. - * AT-BUS style device numbering no longer used: use SCSI style now. - * So, the first "found" device has MINOR 0, regardless of the - * jumpered drive ID. This implies modifications to the /dev/sbpcd* - * entries for some people, but will help the DAU (german TLA, english: - * "newbie", maybe ;-) to install his "first" system from a CD. - * - * 3.2 Still testing with CD200 and CD-55A drives. - * - * 3.3 Working with CD200 support. - * - * 3.4 Auto-probing stops if an address of 0 is seen (to be entered with - * the kernel command line). - * Made the driver "loadable". If used as a module, "audio copy" is - * disabled, and the internal read ahead data buffer has a reduced size - * of 4 kB; so, throughput may be reduced a little bit with slow CPUs. - * - * 3.5 Provisions to handle weird photoCDs which have an interrupted - * "formatting" immediately after the last frames of some files: simply - * never "read ahead" with MultiSession CDs. By this, CPU usage may be - * increased with those CDs, and there may be a loss in speed. - * Re-structured the messaging system. - * The "loadable" version no longer has a limited READ_AUDIO buffer - * size. - * Removed "MANY_SESSION" handling for "old" multi session CDs. - * Added "private" IOCTLs CDROMRESET and CDROMVOLREAD. - * Started again to support the TEAC CD-55A drives, now that I found - * the money for "my own" drive. ;-) - * The TEAC CD-55A support is fairly working now. - * I have measured that the drive "delivers" at 600 kB/sec (even with - * bigger requests than the drive's 64 kB buffer can satisfy), but - * the "real" rate does not exceed 520 kB/sec at the moment. - * Caused by the various changes to build in TEAC support, the timed - * loops are de-optimized at the moment (less throughput with CR-52x - * drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64). - * - * 3.6 Fixed TEAC data read problems with SbPro interfaces. - * Initial size of the READ_AUDIO buffer is 0. Can get set to any size - * during runtime. - * - * 3.7 Introduced MAX_DRIVES for some poor interface cards (seen with TEAC - * drives) which allow only one drive (ID 0); this avoids repetitive - * detection under IDs 1..3. - * Elongated cmd_out_T response waiting; necessary for photo CDs with - * a lot of sessions. - * Bettered the sbpcd_open() behavior with TEAC drives. - * - * 3.8 Elongated max_latency for CR-56x drives. - * - * 3.9 Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface - * configuration bug. - * Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy - * the config_spea() routine into their drivers. ;-) - * - * 4.0 No "big step" - normal version increment. - * Adapted the benefits from 1.3.33. - * Fiddled with CDROMREADAUDIO flaws. - * Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version - * seems not to support it). - * Fulfilled "read audio" for CD200 drives, with help of Pete Heist - * (heistp@rpi.edu). - * - * 4.1 Use loglevel KERN_INFO with printk(). - * Added support for "Vertos 100" drive ("ECS-AT") - it is very similar - * to the Longshine LCS-7260. Give feedback if you can - I never saw - * such a drive, and I have no specs. - * - * 4.2 Support for Teac 16-bit interface cards. Can't get auto-detected, - * so you have to jumper your card to 0x2C0. Still not 100% - come - * in contact if you can give qualified feedback. - * Use loglevel KERN_NOTICE with printk(). If you get annoyed by a - * flood of unwanted messages and the accompanied delay, try to read - * my documentation. Especially the Linux CDROM drivers have to do an - * important job for the newcomers, so the "distributed" version has - * to fit some special needs. Since generations, the flood of messages - * is user-configurable (even at runtime), but to get aware of this, one - * needs a special mental quality: the ability to read. - * - * 4.3 CD200F does not like to receive a command while the drive is - * reading the ToC; still trying to solve it. - * Removed some redundant verify_area calls (yes, Heiko Eissfeldt - * is visiting all the Linux CDROM drivers ;-). - * - * 4.4 Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down" - * experiments: "KLOGD_PAUSE". - * Inhibited "play audio" attempts with data CDs. Provisions for a - * "data-safe" handling of "mixed" (data plus audio) Cds. - * - * 4.5 Meanwhile Gonzalo Tornaria (GTL) built a - * special end_request routine: we seem to have to take care for not - * to have two processes working at the request list. My understanding - * was and is that ll_rw_blk should not call do_sbpcd_request as long - * as there is still one call active (the first call will care for all - * outstanding I/Os, and if a second call happens, that is a bug in - * ll_rw_blk.c). - * "Check media change" without touching any drive. - * - * 4.6 Use a semaphore to synchronize multi-activity; elaborated by Rob - * Riggs . At the moment, we simply block "read" - * against "ioctl" and vice versa. This could be refined further, but - * I guess with almost no performance increase. - * Experiments to speed up the CD-55A; again with help of Rob Riggs - * (to be true, he gave both, idea & code. ;-) - * - * 4.61 Ported to Uniform CD-ROM driver by - * Heiko Eissfeldt with additional - * changes by Erik Andersen - * - * 4.62 Fix a bug where playing audio left the drive in an unusable state. - * Heiko Eissfeldt - * - * November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - * - * 4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer. - * Annoying things fixed: - * TOC reread on automated disk changes - * TOC reread on manual cd changes - * Play IOCTL tries to play CD before it's actually ready... sometimes. - * CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play. - * Andrew J. Kroll Wed Jul 26 04:24:10 EDT 2000 - * - * 4.64 Fix module parameters - were being completely ignored. - * Can also specify max_drives=N as a setup int to get rid of - * "ghost" drives on crap hardware (aren't they all?) Paul Gortmaker - * - * TODO - * implement "read all subchannel data" (96 bytes per frame) - * remove alot of the virtual status bits and deal with hardware status - * move the change of cd for audio to a better place - * add debug levels to insmod parameters (trivial) - * - * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine - * elaborated speed-up experiments (and the fabulous results!), for - * the "push" towards load-free wait loops, and for the extensive mail - * thread which brought additional hints and bug fixes. - * - */ - -/* - * Trying to merge requests breaks this driver horribly (as in it goes - * boom and apparently has done so since 2.3.41). As it is a legacy - * driver for a horribly slow double speed CD on a hideous interface - * designed for polled operation, I won't lose any sleep in simply - * disallowing merging. Paul G. 02/2001 - * - * Thu May 30 14:14:47 CEST 2002: - * - * I have presumably found the reson for the above - there was a bogous - * end_request substitute, which was manipulating the request queues - * incorrectly. If someone has access to the actual hardware, and it's - * still operations - well please free to test it. - * - * Marcin Dalecki - */ - -/* - * Add bio/kdev_t changes for 2.5.x required to make it work again. - * Still room for improvement in the request handling here if anyone - * actually cares. Bring your own chainsaw. Paul G. 02/2002 - */ - - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "sbpcd.h" - -#define MAJOR_NR MATSUSHITA_CDROM_MAJOR -#include - -/*==========================================================================*/ -#if SBPCD_DIS_IRQ -# define SBPCD_CLI cli() -# define SBPCD_STI sti() -#else -# define SBPCD_CLI -# define SBPCD_STI -#endif - -/*==========================================================================*/ -/* - * auto-probing address list - * inspired by Adam J. Richter from Yggdrasil - * - * still not good enough - can cause a hang. - * example: a NE 2000 ethernet card at 300 will cause a hang probing 310. - * if that happens, reboot and use the LILO (kernel) command line. - * The possibly conflicting ethernet card addresses get NOT probed - * by default - to minimize the hang possibilities. - * - * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to - * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx. - * - * send mail to emoenke@gwdg.de if your interface card is not FULLY - * represented here. - */ -static int sbpcd[] = -{ - CDROM_PORT, SBPRO, /* probe with user's setup first */ -#if DISTRIBUTION - 0x230, 1, /* Soundblaster Pro and 16 (default) */ -#if 0 - 0x300, 0, /* CI-101P (default), WDH-7001C (default), - Galaxy (default), Reveal (one default) */ - 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */ - 0x2C0, 3, /* Teac 16-bit cards */ - 0x260, 1, /* OmniCD */ - 0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default), - Longshine LCS-6853 (default) */ - 0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */ - 0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */ - 0x360, 0, /* Lasermate, CI-101P */ - 0x270, 1, /* Soundblaster 16 */ - 0x670, 0, /* "sound card #9" */ - 0x690, 0, /* "sound card #9" */ - 0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */ - 0x328, 2, /* SPEA Media FX */ - 0x348, 2, /* SPEA Media FX */ - 0x634, 0, /* some newer sound cards */ - 0x638, 0, /* some newer sound cards */ - 0x230, 1, /* some newer sound cards */ - /* due to incomplete address decoding of the SbPro card, these must be last */ - 0x630, 0, /* "sound card #9" (default) */ - 0x650, 0, /* "sound card #9" */ -#ifdef MODULE - /* - * some "hazardous" locations (no harm with the loadable version) - * (will stop the bus if a NE2000 ethernet card resides at offset -0x10) - */ - 0x330, 0, /* Lasermate, CI-101P, WDH-7001C */ - 0x350, 0, /* Lasermate, CI-101P */ - 0x358, 2, /* SPEA Media FX */ - 0x370, 0, /* Lasermate, CI-101P */ - 0x290, 1, /* Soundblaster 16 */ - 0x310, 0, /* Lasermate, CI-101P, WDH-7001C */ -#endif /* MODULE */ -#endif -#endif /* DISTRIBUTION */ -}; - -/* - * Protects access to global structures etc. - */ -static __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock); -static struct request_queue *sbpcd_queue; - -/* You can only set the first pair, from old MODULE_PARM code. */ -static int sbpcd_set(const char *val, struct kernel_param *kp) -{ - get_options((char *)val, 2, (int *)sbpcd); - return 0; -} -module_param_call(sbpcd, sbpcd_set, NULL, NULL, 0); - -#define NUM_PROBE (sizeof(sbpcd) / sizeof(int)) - -/*==========================================================================*/ - -#define INLINE inline - -/*==========================================================================*/ -/* - * the forward references: - */ -static void sbp_sleep(u_int); -static void mark_timeout_delay(u_long); -static void mark_timeout_data(u_long); -#if 0 -static void mark_timeout_audio(u_long); -#endif -static void sbp_read_cmd(struct request *req); -static int sbp_data(struct request *req); -static int cmd_out(void); -static int DiskInfo(void); - -/*==========================================================================*/ - -/* - * pattern for printk selection: - * - * (1<99) msgnum=0; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - printk(MSG_LEVEL "%s-%d [%02d]: %s", major_name, current_drive - D_S, msgnum, buf); -#if KLOGD_PAUSE - sbp_sleep(KLOGD_PAUSE); /* else messages get lost */ -#endif /* KLOGD_PAUSE */ - return; -} -/*==========================================================================*/ -/* - * DDI interface: runtime trace bit pattern maintenance - */ -static int sbpcd_dbg_ioctl(unsigned long arg, int level) -{ - switch(arg) - { - case 0: /* OFF */ - sbpcd_debug = DBG_INF; - break; - - default: - if (arg>=128) sbpcd_debug &= ~(1<<(arg-128)); - else sbpcd_debug |= (1<>4)); -} -/*==========================================================================*/ -static INLINE u_char byt2bcd(u_char i) -{ - return (((i/10)<<4)+i%10); -} -/*==========================================================================*/ -static INLINE u_char bcd2bin(u_char bcd) -{ - return ((bcd>>4)*10+(bcd&0x0F)); -} -/*==========================================================================*/ -static INLINE int msf2blk(int msfx) -{ - MSF msf; - int i; - - msf.n=msfx; - i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET; - if (i<0) return (0); - return (i); -} -/*==========================================================================*/ -/* - * convert m-s-f_number (3 bytes only) to logical_block_address - */ -static INLINE int msf2lba(u_char *msf) -{ - int i; - - i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET; - if (i<0) return (0); - return (i); -} -/*==========================================================================*/ -/* evaluate cc_ReadError code */ -static int sta2err(int sta) -{ - if (famT_drive) - { - if (sta==0x00) return (0); - if (sta==0x01) return (-604); /* CRC error */ - if (sta==0x02) return (-602); /* drive not ready */ - if (sta==0x03) return (-607); /* unknown media */ - if (sta==0x04) return (-612); /* general failure */ - if (sta==0x05) return (0); - if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */ - if (sta==0x0b) return (-612); /* general failure */ - if (sta==0xff) return (-612); /* general failure */ - return (0); - } - else - { - if (sta<=2) return (sta); - if (sta==0x05) return (-604); /* CRC error */ - if (sta==0x06) return (-606); /* seek error */ - if (sta==0x0d) return (-606); /* seek error */ - if (sta==0x0e) return (-603); /* unknown command */ - if (sta==0x14) return (-603); /* unknown command */ - if (sta==0x0c) return (-611); /* read fault */ - if (sta==0x0f) return (-611); /* read fault */ - if (sta==0x10) return (-611); /* read fault */ - if (sta>=0x16) return (-612); /* general failure */ - if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */ - if (famL_drive) - if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */ - return (-602); /* drive not ready */ - } -} -/*==========================================================================*/ -static INLINE void clr_cmdbuf(void) -{ - int i; - - for (i=0;i<10;i++) drvcmd[i]=0; - cmd_type=0; -} -/*==========================================================================*/ -static void flush_status(void) -{ - int i; - - sbp_sleep(15*HZ/10); - for (i=maxtim_data;i!=0;i--) inb(CDi_status); -} -/*====================================================================*/ -/* - * CDi status loop for Teac CD-55A (Rob Riggs) - * - * This is needed because for some strange reason - * the CD-55A can take a real long time to give a - * status response. This seems to happen after we - * issue a READ command where a long seek is involved. - * - * I tried to ensure that we get max throughput with - * minimal busy waiting. We busy wait at first, then - * "switch gears" and start sleeping. We sleep for - * longer periods of time the longer we wait. - * - */ -static int CDi_stat_loop_T(void) -{ - int i, gear=1; - u_long timeout_1, timeout_2, timeout_3, timeout_4; - - timeout_1 = jiffies + HZ / 50; /* sbp_sleep(0) for a short period */ - timeout_2 = jiffies + HZ / 5; /* nap for no more than 200ms */ - timeout_3 = jiffies + 5 * HZ; /* sleep for up to 5s */ - timeout_4 = jiffies + 45 * HZ; /* long sleep for up to 45s. */ - do - { - i = inb(CDi_status); - if (!(i&s_not_data_ready)) return (i); - if (!(i&s_not_result_ready)) return (i); - switch(gear) - { - case 4: - sbp_sleep(HZ); - if (time_after(jiffies, timeout_4)) gear++; - msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n"); - break; - case 3: - sbp_sleep(HZ/10); - if (time_after(jiffies, timeout_3)) gear++; - break; - case 2: - sbp_sleep(HZ/100); - if (time_after(jiffies, timeout_2)) gear++; - break; - case 1: - sbp_sleep(0); - if (time_after(jiffies, timeout_1)) gear++; - } - } while (gear < 5); - return -1; -} -/*==========================================================================*/ -static int CDi_stat_loop(void) -{ - int i,j; - - for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); ) - { - for ( ;i!=0;i--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) return (j); - if (!(j&s_not_result_ready)) return (j); - if (fam0L_drive) if (j&s_attention) return (j); - } - sbp_sleep(1); - i = 1; - } - msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__); - return (-1); -} -/*==========================================================================*/ -#if 00000 -/*==========================================================================*/ -static int tst_DataReady(void) -{ - int i; - - i=inb(CDi_status); - if (i&s_not_data_ready) return (0); - return (1); -} -/*==========================================================================*/ -static int tst_ResultReady(void) -{ - int i; - - i=inb(CDi_status); - if (i&s_not_result_ready) return (0); - return (1); -} -/*==========================================================================*/ -static int tst_Attention(void) -{ - int i; - - i=inb(CDi_status); - if (i&s_attention) return (1); - return (0); -} -/*==========================================================================*/ -#endif -/*==========================================================================*/ -static int ResponseInfo(void) -{ - int i,j,st=0; - u_long timeout; - - for (i=0,timeout=jiffies+HZ;i0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j); -#endif /* 000 */ - for (j=0;j0) return (-j); - else return (i); -} -/*==========================================================================*/ -static void EvaluateStatus(int st) -{ - current_drive->status_bits=0; - if (fam1_drive) current_drive->status_bits=st|p_success; - else if (fam0_drive) - { - if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in; - if (st&p_spinning) current_drive->status_bits |= p_spinning; - if (st&p_check) current_drive->status_bits |= p_check; - if (st&p_success_old) current_drive->status_bits |= p_success; - if (st&p_busy_old) current_drive->status_bits |= p_busy_new; - if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok; - } - else if (famLV_drive) - { - current_drive->status_bits |= p_success; - if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in; - if (st&p_spinning) current_drive->status_bits |= p_spinning; - if (st&p_check) current_drive->status_bits |= p_check; - if (st&p_busy_old) current_drive->status_bits |= p_busy_new; - if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed; - if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked; - } - else if (fam2_drive) - { - current_drive->status_bits |= p_success; - if (st&p2_check) current_drive->status_bits |= p1_check; - if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed; - if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in; - if (st&p2_busy1) current_drive->status_bits |= p1_busy; - if (st&p2_busy2) current_drive->status_bits |= p1_busy; - if (st&p2_spinning) current_drive->status_bits |= p1_spinning; - if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked; - if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok; - } - else if (famT_drive) - { - return; /* still needs to get coded */ - current_drive->status_bits |= p_success; - if (st&p2_check) current_drive->status_bits |= p1_check; - if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed; - if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in; - if (st&p2_busy1) current_drive->status_bits |= p1_busy; - if (st&p2_busy2) current_drive->status_bits |= p1_busy; - if (st&p2_spinning) current_drive->status_bits |= p1_spinning; - if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked; - if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok; - } - return; -} -/*==========================================================================*/ -static int cmd_out_T(void); - -static int get_state_T(void) -{ - int i; - - clr_cmdbuf(); - current_drive->n_bytes=1; - drvcmd[0]=CMDT_STATUS; - i=cmd_out_T(); - if (i>=0) i=infobuf[0]; - else - { - msg(DBG_TEA,"get_state_T error %d\n", i); - return (i); - } - if (i>=0) - /* 2: closed, disk in */ - current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok; - else if (current_drive->error_state==6) - { - /* 3: closed, disk in, changed ("06 xx xx") */ - current_drive->status_bits=p1_door_closed|p1_disk_in; - current_drive->CD_changed=0xFF; - current_drive->diskstate_flags &= ~toc_bit; - } - else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00)) - { - /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */ - current_drive->status_bits=p1_door_closed; - current_drive->open_count=0; - } - else if (current_drive->b4==0x01) - { - /* 0: open ("02 3A 01") */ - current_drive->status_bits=0; - current_drive->open_count=0; - } - else - { - /* 1: closed, no disk ("02 3A xx") */ - current_drive->status_bits=p1_door_closed; - current_drive->open_count=0; - } - return (current_drive->status_bits); -} -/*==========================================================================*/ -static int ResponseStatus(void) -{ - int i,j; - u_long timeout; - - msg(DBG_STA,"doing ResponseStatus...\n"); - if (famT_drive) return (get_state_T()); - if (flags_cmd_out & f_respo3) timeout = jiffies; - else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ; - else timeout = jiffies + 4*HZ; - j=maxtim_8; - do - { - for ( ;j!=0;j--) - { - i=inb(CDi_status); - if (!(i&s_not_result_ready)) break; - } - if ((j!=0)||time_after(jiffies, timeout)) break; - sbp_sleep(1); - j = 1; - } - while (1); - if (j==0) - { - if ((flags_cmd_out & f_respo3) == 0) - msg(DBG_STA,"ResponseStatus: timeout.\n"); - current_drive->status_bits=0; - return (-401); - } - i=inb(CDi_info); - msg(DBG_STA,"ResponseStatus: response %02X.\n", i); - EvaluateStatus(i); - msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i); - return (current_drive->status_bits); -} -/*==========================================================================*/ -static void cc_ReadStatus(void) -{ - int i; - - msg(DBG_STA,"giving cc_ReadStatus command\n"); - if (famT_drive) return; - SBPCD_CLI; - if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS); - else if (fam1_drive) OUT(CDo_command,CMD1_STATUS); - else if (fam2_drive) OUT(CDo_command,CMD2_STATUS); - if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0); - SBPCD_STI; -} -/*==========================================================================*/ -static int cc_ReadError(void) -{ - int i; - - clr_cmdbuf(); - msg(DBG_ERR,"giving cc_ReadError command.\n"); - if (fam1_drive) - { - drvcmd[0]=CMD1_READ_ERR; - response_count=8; - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (fam0LV_drive) - { - drvcmd[0]=CMD0_READ_ERR; - response_count=6; - if (famLV_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_READ_ERR; - response_count=6; - flags_cmd_out=f_putcmd; - } - else if (famT_drive) - { - response_count=5; - drvcmd[0]=CMDT_READ_ERR; - } - i=cmd_out(); - current_drive->error_byte=0; - msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i); - if (i<0) return (i); - if (fam0V_drive) i=1; - else i=2; - current_drive->error_byte=infobuf[i]; - msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte); - i=sta2err(infobuf[i]); - if (i==-ERR_DISKCHANGE) - { - current_drive->CD_changed=0xFF; - current_drive->diskstate_flags &= ~toc_bit; - } - return (i); -} -/*==========================================================================*/ -static int cc_DriveReset(void); - -static int cmd_out_T(void) -{ -#undef CMDT_TRIES -#define CMDT_TRIES 1000 -#define TEST_FALSE_FF 1 - - int i, j, l=0, m, ntries; - unsigned long flags; - - current_drive->error_state=0; - current_drive->b3=0; - current_drive->b4=0; - current_drive->f_drv_error=0; - for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]); - msgbuf[i*3]=0; - msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf); - - OUT(CDo_sel_i_d,0); - OUT(CDo_enable,current_drive->drv_sel); - i=inb(CDi_status); - do_16bit=0; - if ((f_16bit)&&(!(i&0x80))) - { - do_16bit=1; - msg(DBG_TEA,"cmd_out_T: do_16bit set.\n"); - } - if (!(i&s_not_result_ready)) - do - { - j=inb(CDi_info); - i=inb(CDi_status); - sbp_sleep(0); - msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j); - } - while (!(i&s_not_result_ready)); - save_flags(flags); cli(); - for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]); - restore_flags(flags); - for (ntries=CMDT_TRIES;ntries>0;ntries--) - { - if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */ -#if 01 - OUT(CDo_sel_i_d,1); -#endif /* 01 */ - if (teac==2) - { - if ((i=CDi_stat_loop_T()) == -1) break; - } - else - { -#if 0 - OUT(CDo_sel_i_d,1); -#endif /* 0 */ - i=inb(CDi_status); - } - if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */ - { - OUT(CDo_sel_i_d,1); - if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */ - if (drvcmd[0]==CMDT_DISKINFO) - { - l=0; - do - { - if (do_16bit) - { - i=inw(CDi_data); - infobuf[l++]=i&0x0ff; - infobuf[l++]=i>>8; -#if TEST_FALSE_FF - if ((l==2)&&(infobuf[0]==0x0ff)) - { - infobuf[0]=infobuf[1]; - l=1; - msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n"); - } -#endif /* TEST_FALSE_FF */ - } - else infobuf[l++]=inb(CDi_data); - i=inb(CDi_status); - } - while (!(i&s_not_data_ready)); - for (j=0;j1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion); - clr_cmdbuf(); - drvcmd[0]=CMDT_READ_ERR; - j=cmd_out_T(); /* !!! recursive here !!! */ - --recursion; - sbp_sleep(1); - } - while (j<0); - current_drive->error_state=infobuf[2]; - current_drive->b3=infobuf[3]; - current_drive->b4=infobuf[4]; - if (current_drive->f_drv_error) - { - current_drive->f_drv_error=0; - cc_DriveReset(); - current_drive->error_state=2; - } - return (-current_drive->error_state-400); - } - if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */ - if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10); - else sbp_sleep(HZ/100); - if (ntries>(CMDT_TRIES-50)) continue; - msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1); - } - current_drive->f_drv_error=1; - cc_DriveReset(); - current_drive->error_state=2; - return (-99); -} -/*==========================================================================*/ -static int cmd_out(void) -{ - int i=0; - - if (famT_drive) return(cmd_out_T()); - - if (flags_cmd_out&f_putcmd) - { - unsigned long flags; - for (i=0;i<7;i++) - sprintf(&msgbuf[i*3], " %02X", drvcmd[i]); - msgbuf[i*3]=0; - msg(DBG_CMD,"cmd_out:%s\n", msgbuf); - save_flags(flags); cli(); - for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]); - restore_flags(flags); - } - if (response_count!=0) - { - if (cmd_type!=0) - { - if (sbpro_type==1) OUT(CDo_sel_i_d,1); - msg(DBG_INF,"misleaded to try ResponseData.\n"); - if (sbpro_type==1) OUT(CDo_sel_i_d,0); - return (-22); - } - else i=ResponseInfo(); - if (i<0) return (i); - } - if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n"); - if (flags_cmd_out&f_lopsta) - { - i=CDi_stat_loop(); - if ((i<0)||!(i&s_attention)) return (-8); - } - if (!(flags_cmd_out&f_getsta)) goto LOC_229; - - LOC_228: - if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n"); - cc_ReadStatus(); - - LOC_229: - if (flags_cmd_out&f_ResponseStatus) - { - if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n"); - i=ResponseStatus(); - /* builds status_bits, returns orig. status or p_busy_new */ - if (i<0) return (i); - if (flags_cmd_out&(f_bit1|f_wait_if_busy)) - { - if (!st_check) - { - if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232; - if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228; - } - } - } - LOC_232: - if (!(flags_cmd_out&f_obey_p_check)) return (0); - if (!st_check) return (0); - if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n"); - i=cc_ReadError(); - if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n"); - msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i); - return (i); -} -/*==========================================================================*/ -static int cc_Seek(u_int pos, char f_blk_msf) -{ - int i; - - clr_cmdbuf(); - if (f_blk_msf>1) return (-3); - if (fam0V_drive) - { - drvcmd[0]=CMD0_SEEK; - if (f_blk_msf==1) pos=msf2blk(pos); - drvcmd[2]=(pos>>16)&0x00FF; - drvcmd[3]=(pos>>8)&0x00FF; - drvcmd[4]=pos&0x00FF; - if (fam0_drive) - flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta | - f_ResponseStatus | f_obey_p_check | f_bit1; - else - flags_cmd_out = f_putcmd; - } - else if (fam1L_drive) - { - drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */ - if (f_blk_msf==0) pos=blk2msf(pos); - drvcmd[1]=(pos>>16)&0x00FF; - drvcmd[2]=(pos>>8)&0x00FF; - drvcmd[3]=pos&0x00FF; - if (famL_drive) - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - else - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_SEEK; - if (f_blk_msf==0) pos=blk2msf(pos); - drvcmd[2]=(pos>>24)&0x00FF; - drvcmd[3]=(pos>>16)&0x00FF; - drvcmd[4]=(pos>>8)&0x00FF; - drvcmd[5]=pos&0x00FF; - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_SEEK; - if (f_blk_msf==1) pos=msf2blk(pos); - drvcmd[2]=(pos>>24)&0x00FF; - drvcmd[3]=(pos>>16)&0x00FF; - drvcmd[4]=(pos>>8)&0x00FF; - drvcmd[5]=pos&0x00FF; - current_drive->n_bytes=1; - } - response_count=0; - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_SpinUp(void) -{ - int i; - - msg(DBG_SPI,"SpinUp.\n"); - current_drive->in_SpinUp = 1; - clr_cmdbuf(); - if (fam0LV_drive) - { - drvcmd[0]=CMD0_SPINUP; - if (fam0L_drive) - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta| - f_ResponseStatus|f_obey_p_check|f_bit1; - else - flags_cmd_out=f_putcmd; - } - else if (fam1_drive) - { - drvcmd[0]=CMD1_SPINUP; - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_TRAY_CTL; - drvcmd[4]=0x01; /* "spinup" */ - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_TRAY_CTL; - drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */ - } - response_count=0; - i=cmd_out(); - current_drive->in_SpinUp = 0; - return (i); -} -/*==========================================================================*/ -static int cc_SpinDown(void) -{ - int i; - - if (fam0_drive) return (0); - clr_cmdbuf(); - response_count=0; - if (fam1_drive) - { - drvcmd[0]=CMD1_SPINDOWN; - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_TRAY_CTL; - drvcmd[4]=0x02; /* "eject" */ - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (famL_drive) - { - drvcmd[0]=CMDL_SPINDOWN; - drvcmd[1]=1; - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - } - else if (famV_drive) - { - drvcmd[0]=CMDV_SPINDOWN; - flags_cmd_out=f_putcmd; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_TRAY_CTL; - drvcmd[4]=0x02; /* "eject" */ - } - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_get_mode_T(void) -{ - int i; - - clr_cmdbuf(); - response_count=10; - drvcmd[0]=CMDT_GETMODE; - drvcmd[4]=response_count; - i=cmd_out_T(); - return (i); -} -/*==========================================================================*/ -static int cc_set_mode_T(void) -{ - int i; - - clr_cmdbuf(); - response_count=1; - drvcmd[0]=CMDT_SETMODE; - drvcmd[1]=current_drive->speed_byte; - drvcmd[2]=current_drive->frmsiz>>8; - drvcmd[3]=current_drive->frmsiz&0x0FF; - drvcmd[4]=current_drive->f_XA; /* 1: XA */ - drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */ - drvcmd[6]=current_drive->mode_xb_6; - drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control; - drvcmd[8]=current_drive->mode_xb_8; - drvcmd[9]=current_drive->delay; - i=cmd_out_T(); - return (i); -} -/*==========================================================================*/ -static int cc_prep_mode_T(void) -{ - int i, j; - - i=cc_get_mode_T(); - if (i<0) return (i); - for (i=0;i<10;i++) - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf); - current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */ - current_drive->frmsiz=make16(infobuf[2],infobuf[3]); - current_drive->f_XA=infobuf[4]; - if (current_drive->f_XA==0) current_drive->type_byte=0; - else current_drive->type_byte=1; - current_drive->mode_xb_6=infobuf[6]; - current_drive->mode_yb_7=1; - current_drive->mode_xb_8=infobuf[8]; - current_drive->delay=0; /* 0, 1, 2, 3 */ - j=cc_set_mode_T(); - i=cc_get_mode_T(); - for (i=0;i<10;i++) - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf); - return (j); -} -/*==========================================================================*/ -static int cc_SetSpeed(u_char speed, u_char x1, u_char x2) -{ - int i; - - if (fam0LV_drive) return (0); - clr_cmdbuf(); - response_count=0; - if (fam1_drive) - { - drvcmd[0]=CMD1_SETMODE; - drvcmd[1]=0x03; - drvcmd[2]=speed; - drvcmd[3]=x1; - drvcmd[4]=x2; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_SETSPEED; - if (speed&speed_auto) - { - drvcmd[2]=0xFF; - drvcmd[3]=0xFF; - } - else - { - drvcmd[2]=0; - drvcmd[3]=150; - } - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - return (0); - } - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_SetVolume(void) -{ - int i; - u_char channel0,channel1,volume0,volume1; - u_char control0,value0,control1,value1; - - current_drive->diskstate_flags &= ~volume_bit; - clr_cmdbuf(); - channel0=current_drive->vol_chan0; - volume0=current_drive->vol_ctrl0; - channel1=control1=current_drive->vol_chan1; - volume1=value1=current_drive->vol_ctrl1; - control0=value0=0; - - if (famV_drive) return (0); - - if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211)) - { - if ((volume0!=0)&&(volume1==0)) - { - volume1=volume0; - channel1=channel0; - } - else if ((volume0==0)&&(volume1!=0)) - { - volume0=volume1; - channel0=channel1; - } - } - if (channel0>1) - { - channel0=0; - volume0=0; - } - if (channel1>1) - { - channel1=1; - volume1=0; - } - - if (fam1_drive) - { - control0=channel0+1; - control1=channel1+1; - value0=(volume0>volume1)?volume0:volume1; - value1=value0; - if (volume0==0) control0=0; - if (volume1==0) control1=0; - drvcmd[0]=CMD1_SETMODE; - drvcmd[1]=0x05; - drvcmd[3]=control0; - drvcmd[4]=value0; - drvcmd[5]=control1; - drvcmd[6]=value1; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - control0=channel0+1; - control1=channel1+1; - value0=(volume0>volume1)?volume0:volume1; - value1=value0; - if (volume0==0) control0=0; - if (volume1==0) control1=0; - drvcmd[0]=CMD2_SETMODE; - drvcmd[1]=0x0E; - drvcmd[3]=control0; - drvcmd[4]=value0; - drvcmd[5]=control1; - drvcmd[6]=value1; - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (famL_drive) - { - if ((volume0==0)||(channel0!=0)) control0 |= 0x80; - if ((volume1==0)||(channel1!=1)) control0 |= 0x40; - if (volume0|volume1) value0=0x80; - drvcmd[0]=CMDL_SETMODE; - drvcmd[1]=0x03; - drvcmd[4]=control0; - drvcmd[5]=value0; - flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - } - else if (fam0_drive) /* different firmware levels */ - { - if (current_drive->drv_type>=drv_300) - { - control0=volume0&0xFC; - value0=volume1&0xFC; - if ((volume0!=0)&&(volume0<4)) control0 |= 0x04; - if ((volume1!=0)&&(volume1<4)) value0 |= 0x04; - if (channel0!=0) control0 |= 0x01; - if (channel1==1) value0 |= 0x01; - } - else - { - value0=(volume0>volume1)?volume0:volume1; - if (current_drive->drv_typedrv_typedrv_type>=drv_201) - { - if (volume0==0) control0 |= 0x80; - if (volume1==0) control0 |= 0x40; - } - if (current_drive->drv_type>=drv_211) - { - if (channel0!=0) control0 |= 0x20; - if (channel1!=1) control0 |= 0x10; - } - } - drvcmd[0]=CMD0_SETMODE; - drvcmd[1]=0x83; - drvcmd[4]=control0; - drvcmd[5]=value0; - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - current_drive->volume_control=0; - if (!volume0) current_drive->volume_control|=0x10; - if (!volume1) current_drive->volume_control|=0x20; - i=cc_prep_mode_T(); - if (i<0) return (i); - } - if (!famT_drive) - { - response_count=0; - i=cmd_out(); - if (i<0) return (i); - } - current_drive->diskstate_flags |= volume_bit; - return (0); -} -/*==========================================================================*/ -static int GetStatus(void) -{ - int i; - - if (famT_drive) return (0); - flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check; - response_count=0; - cmd_type=0; - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_DriveReset(void) -{ - int i; - - msg(DBG_RES,"cc_DriveReset called.\n"); - clr_cmdbuf(); - response_count=0; - if (fam0LV_drive) OUT(CDo_reset,0x00); - else if (fam1_drive) - { - drvcmd[0]=CMD1_RESET; - flags_cmd_out=f_putcmd; - i=cmd_out(); - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_RESET; - flags_cmd_out=f_putcmd; - i=cmd_out(); - OUT(CDo_reset,0x00); - } - else if (famT_drive) - { - OUT(CDo_sel_i_d,0); - OUT(CDo_enable,current_drive->drv_sel); - OUT(CDo_command,CMDT_RESET); - for (i=1;i<10;i++) OUT(CDo_command,0); - } - if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */ - else sbp_sleep(1*HZ); /* wait a second */ -#if 1 - if (famT_drive) - { - msg(DBG_TEA, "================CMDT_RESET given=================.\n"); - sbp_sleep(3*HZ); - } -#endif /* 1 */ - flush_status(); - i=GetStatus(); - if (i<0) return i; - if (!famT_drive) - if (current_drive->error_byte!=aud_12) return -501; - return (0); -} - -/*==========================================================================*/ -static int SetSpeed(void) -{ - int i, speed; - - if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0); - speed=speed_auto; - if (!(current_drive->drv_options&speed_auto)) - { - speed |= speed_300; - if (!(current_drive->drv_options&speed_300)) speed=0; - } - i=cc_SetSpeed(speed,0,0); - return (i); -} - -static void switch_drive(struct sbpcd_drive *); - -static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed) -{ - struct sbpcd_drive *p = cdi->handle; - if (p != current_drive) - switch_drive(p); - - return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0); -} - -/*==========================================================================*/ -static int DriveReset(void) -{ - int i; - - i=cc_DriveReset(); - if (i<0) return (-22); - do - { - i=GetStatus(); - if ((i<0)&&(i!=-ERR_DISKCHANGE)) { - return (-2); /* from sta2err */ - } - if (!st_caddy_in) break; - sbp_sleep(1); - } - while (!st_diskok); -#if 000 - current_drive->CD_changed=1; -#endif - if ((st_door_closed) && (st_caddy_in)) - { - i=DiskInfo(); - if (i<0) return (-23); - } - return (0); -} - -static int sbpcd_reset(struct cdrom_device_info *cdi) -{ - struct sbpcd_drive *p = cdi->handle; - if (p != current_drive) - switch_drive(p); - return DriveReset(); -} - -/*==========================================================================*/ -static int cc_PlayAudio(int pos_audio_start,int pos_audio_end) -{ - int i, j, n; - - if (current_drive->audio_state==audio_playing) return (-EINVAL); - clr_cmdbuf(); - response_count=0; - if (famLV_drive) - { - drvcmd[0]=CMDL_PLAY; - i=msf2blk(pos_audio_start); - n=msf2blk(pos_audio_end)+1-i; - drvcmd[1]=(i>>16)&0x00FF; - drvcmd[2]=(i>>8)&0x00FF; - drvcmd[3]=i&0x00FF; - drvcmd[4]=(n>>16)&0x00FF; - drvcmd[5]=(n>>8)&0x00FF; - drvcmd[6]=n&0x00FF; - if (famL_drive) - flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta | - f_ResponseStatus | f_obey_p_check | f_wait_if_busy; - else - flags_cmd_out = f_putcmd; - } - else - { - j=1; - if (fam1_drive) - { - drvcmd[0]=CMD1_PLAY_MSF; - flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | - f_obey_p_check | f_wait_if_busy; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_PLAY_MSF; - flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_PLAY_MSF; - j=3; - response_count=1; - } - else if (fam0_drive) - { - drvcmd[0]=CMD0_PLAY_MSF; - flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta | - f_ResponseStatus | f_obey_p_check | f_wait_if_busy; - } - drvcmd[j]=(pos_audio_start>>16)&0x00FF; - drvcmd[j+1]=(pos_audio_start>>8)&0x00FF; - drvcmd[j+2]=pos_audio_start&0x00FF; - drvcmd[j+3]=(pos_audio_end>>16)&0x00FF; - drvcmd[j+4]=(pos_audio_end>>8)&0x00FF; - drvcmd[j+5]=pos_audio_end&0x00FF; - } - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_Pause_Resume(int pau_res) -{ - int i; - - clr_cmdbuf(); - response_count=0; - if (fam1_drive) - { - drvcmd[0]=CMD1_PAU_RES; - if (pau_res!=1) drvcmd[1]=0x80; - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_PAU_RES; - if (pau_res!=1) drvcmd[2]=0x01; - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (fam0LV_drive) - { - drvcmd[0]=CMD0_PAU_RES; - if (pau_res!=1) drvcmd[1]=0x80; - if (famL_drive) - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus| - f_obey_p_check|f_bit1; - else if (famV_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus| - f_obey_p_check; - } - else if (famT_drive) - { - if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end)); - else if (pau_res==1) drvcmd[0]=CMDT_PAUSE; - else return (-56); - } - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int cc_LockDoor(char lock) -{ - int i; - - if (fam0_drive) return (0); - msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S); - msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked); - clr_cmdbuf(); - response_count=0; - if (fam1_drive) - { - drvcmd[0]=CMD1_LOCK_CTL; - if (lock==1) drvcmd[1]=0x01; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_LOCK_CTL; - if (lock==1) drvcmd[4]=0x01; - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (famLV_drive) - { - drvcmd[0]=CMDL_LOCK_CTL; - if (lock==1) drvcmd[1]=0x01; - if (famL_drive) - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - else - flags_cmd_out=f_putcmd; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_LOCK_CTL; - if (lock==1) drvcmd[4]=0x01; - } - i=cmd_out(); - msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked); - return (i); -} -/*==========================================================================*/ -/*==========================================================================*/ -static int UnLockDoor(void) -{ - int i,j; - - j=20; - do - { - i=cc_LockDoor(0); - --j; - sbp_sleep(1); - } - while ((i<0)&&(j)); - if (i<0) - { - cc_DriveReset(); - return -84; - } - return (0); -} -/*==========================================================================*/ -static int LockDoor(void) -{ - int i,j; - - j=20; - do - { - i=cc_LockDoor(1); - --j; - sbp_sleep(1); - } - while ((i<0)&&(j)); - if (j==0) - { - cc_DriveReset(); - j=20; - do - { - i=cc_LockDoor(1); - --j; - sbp_sleep(1); - } - while ((i<0)&&(j)); - } - return (i); -} - -static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock) -{ - return lock ? LockDoor() : UnLockDoor(); -} - -/*==========================================================================*/ -static int cc_CloseTray(void) -{ - int i; - - if (fam0_drive) return (0); - msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S); - msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed); - - clr_cmdbuf(); - response_count=0; - if (fam1_drive) - { - drvcmd[0]=CMD1_TRAY_CTL; - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_TRAY_CTL; - drvcmd[1]=0x01; - drvcmd[4]=0x03; /* "insert" */ - flags_cmd_out=f_putcmd|f_ResponseStatus; - } - else if (famLV_drive) - { - drvcmd[0]=CMDL_TRAY_CTL; - if (famLV_drive) - flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta| - f_ResponseStatus|f_obey_p_check|f_bit1; - else - flags_cmd_out=f_putcmd; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_TRAY_CTL; - drvcmd[4]=0x03; /* "insert" */ - } - i=cmd_out(); - msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed); - - i=cc_ReadError(); - flags_cmd_out |= f_respo2; - cc_ReadStatus(); /* command: give 1-byte status */ - i=ResponseStatus(); - if (famT_drive&&(i<0)) - { - cc_DriveReset(); - i=ResponseStatus(); -#if 0 - sbp_sleep(HZ); -#endif /* 0 */ - i=ResponseStatus(); - } - if (i<0) - { - msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i); - } - if (!(famT_drive)) - { - if (!st_spinning) - { - cc_SpinUp(); - if (st_check) i=cc_ReadError(); - flags_cmd_out |= f_respo2; - cc_ReadStatus(); - i=ResponseStatus(); - } else { - } - } - i=DiskInfo(); - return (i); -} - -static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position) -{ - int retval=0; - switch_drive(cdi->handle); - /* DUH! --AJK */ - if(current_drive->CD_changed != 0xFF) { - current_drive->CD_changed=0xFF; - current_drive->diskstate_flags &= ~cd_size_bit; - } - if (position == 1) { - cc_SpinDown(); - } else { - retval=cc_CloseTray(); - } - return retval; -} - -/*==========================================================================*/ -static int cc_ReadSubQ(void) -{ - int i,j; - - current_drive->diskstate_flags &= ~subq_bit; - for (j=255;j>0;j--) - { - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_READSUBQ; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - response_count=11; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_READSUBQ; - drvcmd[1]=0x02; - drvcmd[3]=0x01; - flags_cmd_out=f_putcmd; - response_count=10; - } - else if (fam0LV_drive) - { - drvcmd[0]=CMD0_READSUBQ; - drvcmd[1]=0x02; - if (famLV_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - response_count=13; - } - else if (famT_drive) - { - response_count=12; - drvcmd[0]=CMDT_READSUBQ; - drvcmd[1]=0x02; - drvcmd[2]=0x40; - drvcmd[3]=0x01; - drvcmd[8]=response_count; - } - i=cmd_out(); - if (i<0) return (i); - for (i=0;iSubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0; - current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0; - return (0); - } - } - if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1]; - else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]); - current_drive->SubQ_trk=byt2bcd(infobuf[2]); - current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]); - if (fam0LV_drive) i=5; - else if (fam12_drive) i=4; - else if (famT_drive) i=8; - current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */ - i=7; - if (fam0LV_drive) i=9; - else if (fam12_drive) i=7; - else if (famT_drive) i=4; - current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */ - current_drive->SubQ_whatisthis=infobuf[i+3]; - current_drive->diskstate_flags |= subq_bit; - return (0); -} -/*==========================================================================*/ -static int cc_ModeSense(void) -{ - int i; - - if (fam2_drive) return (0); - if (famV_drive) return (0); - current_drive->diskstate_flags &= ~frame_size_bit; - clr_cmdbuf(); - if (fam1_drive) - { - response_count=5; - drvcmd[0]=CMD1_GETMODE; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam0L_drive) - { - response_count=2; - drvcmd[0]=CMD0_GETMODE; - if (famL_drive) flags_cmd_out=f_putcmd; - else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - response_count=10; - drvcmd[0]=CMDT_GETMODE; - drvcmd[4]=response_count; - } - i=cmd_out(); - if (i<0) return (i); - i=0; - current_drive->sense_byte=0; - if (fam1_drive) current_drive->sense_byte=infobuf[i++]; - else if (famT_drive) - { - if (infobuf[4]==0x01) current_drive->xa_byte=0x20; - else current_drive->xa_byte=0; - i=2; - } - current_drive->frame_size=make16(infobuf[i],infobuf[i+1]); - for (i=0;idiskstate_flags |= frame_size_bit; - return (0); -} -/*==========================================================================*/ -/*==========================================================================*/ -static int cc_ModeSelect(int framesize) -{ - int i; - - if (fam2_drive) return (0); - if (famV_drive) return (0); - current_drive->diskstate_flags &= ~frame_size_bit; - clr_cmdbuf(); - current_drive->frame_size=framesize; - if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82; - else current_drive->sense_byte=0x00; - - msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n", - current_drive->sense_byte, current_drive->frame_size); - - if (fam1_drive) - { - drvcmd[0]=CMD1_SETMODE; - drvcmd[1]=0x00; - drvcmd[2]=current_drive->sense_byte; - drvcmd[3]=(current_drive->frame_size>>8)&0xFF; - drvcmd[4]=current_drive->frame_size&0xFF; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam0L_drive) - { - drvcmd[0]=CMD0_SETMODE; - drvcmd[1]=0x00; - drvcmd[2]=(current_drive->frame_size>>8)&0xFF; - drvcmd[3]=current_drive->frame_size&0xFF; - drvcmd[4]=0x00; - if(famL_drive) - flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - return (-1); - } - response_count=0; - i=cmd_out(); - if (i<0) return (i); - current_drive->diskstate_flags |= frame_size_bit; - return (0); -} -/*==========================================================================*/ -static int cc_GetVolume(void) -{ - int i; - u_char switches; - u_char chan0=0; - u_char vol0=0; - u_char chan1=1; - u_char vol1=0; - - if (famV_drive) return (0); - current_drive->diskstate_flags &= ~volume_bit; - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_GETMODE; - drvcmd[1]=0x05; - response_count=5; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_GETMODE; - drvcmd[1]=0x0E; - response_count=5; - flags_cmd_out=f_putcmd; - } - else if (fam0L_drive) - { - drvcmd[0]=CMD0_GETMODE; - drvcmd[1]=0x03; - response_count=2; - if(famL_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - i=cc_get_mode_T(); - if (i<0) return (i); - } - if (!famT_drive) - { - i=cmd_out(); - if (i<0) return (i); - } - if (fam1_drive) - { - chan0=infobuf[1]&0x0F; - vol0=infobuf[2]; - chan1=infobuf[3]&0x0F; - vol1=infobuf[4]; - if (chan0==0) - { - chan0=1; - vol0=0; - } - if (chan1==0) - { - chan1=2; - vol1=0; - } - chan0 >>= 1; - chan1 >>= 1; - } - else if (fam2_drive) - { - chan0=infobuf[1]; - vol0=infobuf[2]; - chan1=infobuf[3]; - vol1=infobuf[4]; - } - else if (famL_drive) - { - chan0=0; - chan1=1; - vol0=vol1=infobuf[1]; - switches=infobuf[0]; - if ((switches&0x80)!=0) chan0=1; - if ((switches&0x40)!=0) chan1=0; - } - else if (fam0_drive) /* different firmware levels */ - { - chan0=0; - chan1=1; - vol0=vol1=infobuf[1]; - if (current_drive->drv_type>=drv_201) - { - if (current_drive->drv_typedrv_type>=drv_211) - { - if ((switches&0x20)!=0) chan0=1; - if ((switches&0x10)!=0) chan1=0; - } - } - else - { - vol0=infobuf[0]; - if ((vol0&0x01)!=0) chan0=1; - if ((vol1&0x01)==0) chan1=0; - vol0 &= 0xFC; - vol1 &= 0xFC; - if (vol0!=0) vol0 += 3; - if (vol1!=0) vol1 += 3; - } - } - } - else if (famT_drive) - { - current_drive->volume_control=infobuf[7]; - chan0=0; - chan1=1; - if (current_drive->volume_control&0x10) vol0=0; - else vol0=0xff; - if (current_drive->volume_control&0x20) vol1=0; - else vol1=0xff; - } - current_drive->vol_chan0=chan0; - current_drive->vol_ctrl0=vol0; - current_drive->vol_chan1=chan1; - current_drive->vol_ctrl1=vol1; -#if 000 - current_drive->vol_chan2=2; - current_drive->vol_ctrl2=0xFF; - current_drive->vol_chan3=3; - current_drive->vol_ctrl3=0xFF; -#endif /* 000 */ - current_drive->diskstate_flags |= volume_bit; - return (0); -} -/*==========================================================================*/ -static int cc_ReadCapacity(void) -{ - int i, j; - - if (fam2_drive) return (0); /* some firmware lacks this command */ - if (famLV_drive) return (0); /* some firmware lacks this command */ - if (famT_drive) return (0); /* done with cc_ReadTocDescr() */ - current_drive->diskstate_flags &= ~cd_size_bit; - for (j=3;j>0;j--) - { - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_CAPACITY; - response_count=5; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } -#if 00 - else if (fam2_drive) - { - drvcmd[0]=CMD2_CAPACITY; - response_count=8; - flags_cmd_out=f_putcmd; - } -#endif - else if (fam0_drive) - { - drvcmd[0]=CMD0_CAPACITY; - response_count=5; - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - i=cmd_out(); - if (i>=0) break; - msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i); - cc_ReadError(); - } - if (j==0) return (i); - if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET; - else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])); -#if 00 - else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3])); -#endif - current_drive->diskstate_flags |= cd_size_bit; - msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm); - return (0); -} -/*==========================================================================*/ -static int cc_ReadTocDescr(void) -{ - int i; - - current_drive->diskstate_flags &= ~toc_bit; - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_DISKINFO; - response_count=6; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam0LV_drive) - { - drvcmd[0]=CMD0_DISKINFO; - response_count=6; - if(famLV_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - /* possibly longer timeout periods necessary */ - current_drive->f_multisession=0; - drvcmd[0]=CMD2_DISKINFO; - drvcmd[1]=0x02; - drvcmd[2]=0xAB; - drvcmd[3]=0xFF; /* session */ - response_count=8; - flags_cmd_out=f_putcmd; - } - else if (famT_drive) - { - current_drive->f_multisession=0; - response_count=12; - drvcmd[0]=CMDT_DISKINFO; - drvcmd[1]=0x02; - drvcmd[6]=CDROM_LEADOUT; - drvcmd[8]=response_count; - drvcmd[9]=0x00; - } - i=cmd_out(); - if (i<0) return (i); - if ((famT_drive)&&(ixa_byte=infobuf[0]; - if (fam2_drive) - { - current_drive->first_session=infobuf[1]; - current_drive->last_session=infobuf[2]; - current_drive->n_first_track=infobuf[3]; - current_drive->n_last_track=infobuf[4]; - if (current_drive->first_session!=current_drive->last_session) - { - current_drive->f_multisession=1; - current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]))); - } -#if 0 - if (current_drive->first_session!=current_drive->last_session) - { - if (current_drive->last_session<=20) - zwanzig=current_drive->last_session+1; - else zwanzig=20; - for (count=current_drive->first_session;countmsf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])); - } - current_drive->diskstate_flags |= multisession_bit; - } -#endif - drvcmd[0]=CMD2_DISKINFO; - drvcmd[1]=0x02; - drvcmd[2]=0xAA; - drvcmd[3]=0xFF; - response_count=5; - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<0) return (i); - current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4])); - current_drive->size_blk=msf2blk(current_drive->size_msf); - current_drive->CDsize_frm=current_drive->size_blk+1; - } - else if (famT_drive) - { - current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11])); - current_drive->size_blk=msf2blk(current_drive->size_msf); - current_drive->CDsize_frm=current_drive->size_blk+1; - current_drive->n_first_track=infobuf[2]; - current_drive->n_last_track=infobuf[3]; - } - else - { - current_drive->n_first_track=infobuf[1]; - current_drive->n_last_track=infobuf[2]; - current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5])); - current_drive->size_blk=msf2blk(current_drive->size_msf); - if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1; - } - current_drive->diskstate_flags |= toc_bit; - msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n", - current_drive->xa_byte, - current_drive->n_first_track, - current_drive->n_last_track, - current_drive->size_msf, - current_drive->first_session, - current_drive->last_session); - return (0); -} -/*==========================================================================*/ -static int cc_ReadTocEntry(int num) -{ - int i; - - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_READTOC; - drvcmd[2]=num; - response_count=8; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam2_drive) - { - /* possibly longer timeout periods necessary */ - drvcmd[0]=CMD2_DISKINFO; - drvcmd[1]=0x02; - drvcmd[2]=num; - response_count=5; - flags_cmd_out=f_putcmd; - } - else if (fam0LV_drive) - { - drvcmd[0]=CMD0_READTOC; - drvcmd[1]=0x02; - drvcmd[2]=num; - response_count=8; - if (famLV_drive) - flags_cmd_out=f_putcmd; - else - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - } - else if (famT_drive) - { - response_count=12; - drvcmd[0]=CMDT_DISKINFO; - drvcmd[1]=0x02; - drvcmd[6]=num; - drvcmd[8]=response_count; - drvcmd[9]=0x00; - } - i=cmd_out(); - if (i<0) return (i); - if ((famT_drive)&&(iTocEnt_nixbyte=infobuf[0]; - i=1; - } - else if (fam2_drive) i=0; - else if (famT_drive) i=5; - current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]); - if ((fam1_drive)||(fam0L_drive)) - { - current_drive->TocEnt_number=infobuf[i++]; - current_drive->TocEnt_format=infobuf[i]; - } - else - { - current_drive->TocEnt_number=num; - current_drive->TocEnt_format=0; - } - if (fam1_drive) i=4; - else if (fam0LV_drive) i=5; - else if (fam2_drive) i=2; - else if (famT_drive) i=9; - current_drive->TocEnt_address=make32(make16(0,infobuf[i]), - make16(infobuf[i+1],infobuf[i+2])); - for (i=0;iTocEnt_nixbyte, current_drive->TocEnt_ctl_adr, - current_drive->TocEnt_number, current_drive->TocEnt_format, - current_drive->TocEnt_address); - return (0); -} -/*==========================================================================*/ -static int cc_ReadPacket(void) -{ - int i; - - clr_cmdbuf(); - drvcmd[0]=CMD0_PACKET; - drvcmd[1]=response_count; - if(famL_drive) flags_cmd_out=f_putcmd; - else if (fam01_drive) - flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check; - else if (fam2_drive) return (-1); /* not implemented yet */ - else if (famT_drive) - { - return (-1); - } - i=cmd_out(); - return (i); -} -/*==========================================================================*/ -static int convert_UPC(u_char *p) -{ - int i; - - p++; - if (fam0L_drive) p[13]=0; - for (i=0;i<7;i++) - { - if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++); - else if (fam0L_drive) - { - current_drive->UPC_buf[i]=((*p++)<<4)&0xFF; - current_drive->UPC_buf[i] |= *p++; - } - else if (famT_drive) - { - return (-1); - } - else /* CD200 */ - { - return (-1); - } - } - current_drive->UPC_buf[6] &= 0xF0; - return (0); -} -/*==========================================================================*/ -static int cc_ReadUPC(void) -{ - int i; -#if TEST_UPC - int block, checksum; -#endif /* TEST_UPC */ - - if (fam2_drive) return (0); /* not implemented yet */ - if (famT_drive) return (0); /* not implemented yet */ - if (famV_drive) return (0); /* not implemented yet */ -#if 1 - if (fam0_drive) return (0); /* but it should work */ -#endif - - current_drive->diskstate_flags &= ~upc_bit; -#if TEST_UPC - for (block=CD_MSF_OFFSET+1;block>16)&0xFF; - drvcmd[2]=(block>>8)&0xFF; - drvcmd[3]=block&0xFF; -#endif /* TEST_UPC */ - response_count=8; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam0L_drive) - { - drvcmd[0]=CMD0_READ_UPC; -#if TEST_UPC - drvcmd[2]=(block>>16)&0xFF; - drvcmd[3]=(block>>8)&0xFF; - drvcmd[4]=block&0xFF; -#endif /* TEST_UPC */ - response_count=0; - flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - } - else if (fam2_drive) - { - return (-1); - } - else if (famT_drive) - { - return (-1); - } - i=cmd_out(); - if (i<0) - { - msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i); - return (i); - } - if (fam0L_drive) - { - response_count=16; - if (famL_drive) flags_cmd_out=f_putcmd; - i=cc_ReadPacket(); - if (i<0) - { - msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i); - return (i); - } - } -#if TEST_UPC - checksum=0; -#endif /* TEST_UPC */ - for (i=0;i<(fam1_drive?8:16);i++) - { -#if TEST_UPC - checksum |= infobuf[i]; -#endif /* TEST_UPC */ - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - } - msgbuf[i*3]=0; - msg(DBG_UPC,"UPC info:%s\n", msgbuf); -#if TEST_UPC - if ((checksum&0x7F)!=0) break; - } -#endif /* TEST_UPC */ - current_drive->UPC_ctl_adr=0; - if (fam1_drive) i=0; - else i=2; - if ((infobuf[i]&0x80)!=0) - { - convert_UPC(&infobuf[i]); - current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02; - } - for (i=0;i<7;i++) - sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]); - sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr); - msgbuf[i*3+5]=0; - msg(DBG_UPC,"UPC code:%s\n", msgbuf); - current_drive->diskstate_flags |= upc_bit; - return (0); -} - -static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) -{ - int i; - unsigned char *mcnp = mcn->medium_catalog_number; - unsigned char *resp; - - current_drive->diskstate_flags &= ~upc_bit; - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_READ_UPC; - response_count=8; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - } - else if (fam0L_drive) - { - drvcmd[0]=CMD0_READ_UPC; - response_count=0; - flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; - } - else if (fam2_drive) - { - return (-1); - } - else if (famT_drive) - { - return (-1); - } - i=cmd_out(); - if (i<0) - { - msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i); - return (i); - } - if (fam0L_drive) - { - response_count=16; - if (famL_drive) flags_cmd_out=f_putcmd; - i=cc_ReadPacket(); - if (i<0) - { - msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i); - return (i); - } - } - current_drive->UPC_ctl_adr=0; - if (fam1_drive) i=0; - else i=2; - - resp = infobuf + i; - if (*resp++ == 0x80) { - /* packed bcd to single ASCII digits */ - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - *mcnp++ = (*resp++ & 0x0f) + '0'; - *mcnp++ = (*resp >> 4) + '0'; - } - *mcnp = '\0'; - - current_drive->diskstate_flags |= upc_bit; - return (0); -} - -/*==========================================================================*/ -static int cc_CheckMultiSession(void) -{ - int i; - - if (fam2_drive) return (0); - current_drive->f_multisession=0; - current_drive->lba_multi=0; - if (fam0_drive) return (0); - clr_cmdbuf(); - if (fam1_drive) - { - drvcmd[0]=CMD1_MULTISESS; - response_count=6; - flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - i=cmd_out(); - if (i<0) return (i); - if ((infobuf[0]&0x80)!=0) - { - current_drive->f_multisession=1; - current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]), - make16(infobuf[2],infobuf[3]))); - } - } - else if (famLV_drive) - { - drvcmd[0]=CMDL_MULTISESS; - drvcmd[1]=3; - drvcmd[2]=1; - response_count=8; - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<0) return (i); - current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]), - make16(infobuf[6],infobuf[7]))); - } - else if (famT_drive) - { - response_count=12; - drvcmd[0]=CMDT_DISKINFO; - drvcmd[1]=0x02; - drvcmd[6]=0; - drvcmd[8]=response_count; - drvcmd[9]=0x40; - i=cmd_out(); - if (i<0) return (i); - if (ifirst_session=infobuf[2]; - current_drive->last_session=infobuf[3]; - current_drive->track_of_last_session=infobuf[6]; - if (current_drive->first_session!=current_drive->last_session) - { - current_drive->f_multisession=1; - current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11]))); - } - } - for (i=0;ilba_multi); - if (current_drive->lba_multi>200) - { - current_drive->f_multisession=1; - msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi); - } - return (0); -} -/*==========================================================================*/ -#ifdef FUTURE -static int cc_SubChanInfo(int frame, int count, u_char *buffer) - /* "frame" is a RED BOOK (msf-bin) address */ -{ - int i; - - if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */ - if (famT_drive) - { - return (-1); - } -#if 0 - if (current_drive->audio_state!=audio_playing) return (-ENODATA); -#endif - clr_cmdbuf(); - drvcmd[0]=CMD1_SUBCHANINF; - drvcmd[1]=(frame>>16)&0xFF; - drvcmd[2]=(frame>>8)&0xFF; - drvcmd[3]=frame&0xFF; - drvcmd[5]=(count>>8)&0xFF; - drvcmd[6]=count&0xFF; - flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; - cmd_type=READ_SC; - current_drive->frame_size=CD_FRAMESIZE_SUB; - i=cmd_out(); /* which buffer to use? */ - return (i); -} -#endif /* FUTURE */ -/*==========================================================================*/ -static void __init check_datarate(void) -{ - int i=0; - - msg(DBG_IOX,"check_datarate entered.\n"); - datarate=0; -#if TEST_STI - for (i=0;i<=1000;i++) printk("."); -#endif - /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */ -#if 1 - del_timer(&delay_timer); -#endif - delay_timer.expires=jiffies+11*HZ/10; - timed_out_delay=0; - add_timer(&delay_timer); -#if 0 - msg(DBG_TIM,"delay timer started (11*HZ/10).\n"); -#endif - do - { - i=inb(CDi_status); - datarate++; -#if 1 - if (datarate>0x6FFFFFFF) break; -#endif - } - while (!timed_out_delay); - del_timer(&delay_timer); -#if 0 - msg(DBG_TIM,"datarate: %04X\n", datarate); -#endif - if (datarate<65536) datarate=65536; - maxtim16=datarate*16; - maxtim04=datarate*4; - maxtim02=datarate*2; - maxtim_8=datarate/32; -#if LONG_TIMING - maxtim_data=datarate/100; -#else - maxtim_data=datarate/300; -#endif /* LONG_TIMING */ -#if 0 - msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data); -#endif -} -/*==========================================================================*/ -#if 0 -static int c2_ReadError(int fam) -{ - int i; - - clr_cmdbuf(); - response_count=9; - clr_respo_buf(9); - if (fam==1) - { - drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */ - i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus); - } - else if (fam==2) - { - drvcmd[0]=CMD2_READ_ERR; - i=do_cmd(f_putcmd); - } - else return (-1); - return (i); -} -#endif -/*==========================================================================*/ -static void __init ask_mail(void) -{ - int i; - - msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n"); - msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n"); - msg(DBG_INF, "%s\n", VERSION); - msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n", - CDo_command, type, current_drive->drive_model, current_drive->drv_id); - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_INF,"infobuf =%s\n", msgbuf); - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %c ", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_INF,"infobuf =%s\n", msgbuf); -} -/*==========================================================================*/ -static int __init check_version(void) -{ - int i, j, l; - int teac_possible=0; - - msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S); - current_drive->drv_type=0; - - /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */ - /* clear any pending error state */ - clr_cmdbuf(); - drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */ - response_count=9; - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i); - /* read drive version */ - clr_cmdbuf(); - for (i=0;i<12;i++) infobuf[i]=0; - drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */ - response_count=12; /* fam1: only 11 */ - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i); - if (i==-11) teac_possible++; - j=0; - for (i=0;i<12;i++) j+=infobuf[i]; - if (j) - { - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_ECS,"infobuf =%s\n", msgbuf); - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %c ", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_ECS,"infobuf =%s\n", msgbuf); - } - for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break; - if (i==4) - { - current_drive->drive_model[0]='C'; - current_drive->drive_model[1]='R'; - current_drive->drive_model[2]='-'; - current_drive->drive_model[3]='5'; - current_drive->drive_model[4]=infobuf[i++]; - current_drive->drive_model[5]=infobuf[i++]; - current_drive->drive_model[6]=0; - current_drive->drv_type=drv_fam1; - } - if (!current_drive->drv_type) - { - for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break; - if (i==8) - { - current_drive->drive_model[0]='C'; - current_drive->drive_model[1]='R'; - current_drive->drive_model[2]='-'; - current_drive->drive_model[3]='5'; - current_drive->drive_model[4]='2'; - current_drive->drive_model[5]='x'; - current_drive->drive_model[6]=0; - current_drive->drv_type=drv_fam0; - } - } - if (!current_drive->drv_type) - { - for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break; - if (i==8) - { - for (j=0;j<8;j++) - current_drive->drive_model[j]=infobuf[j]; - current_drive->drive_model[8]=0; - current_drive->drv_type=drv_famL; - } - } - if (!current_drive->drv_type) - { - for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break; - if (i==6) - { - for (j=0;j<6;j++) - current_drive->drive_model[j]=infobuf[j]; - current_drive->drive_model[6]=0; - current_drive->drv_type=drv_famV; - i+=2; /* 2 blanks before version */ - } - } - if (!current_drive->drv_type) - { - /* check for CD200 */ - clr_cmdbuf(); - drvcmd[0]=CMD2_READ_ERR; - response_count=9; - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i); - if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i); - /* read drive version */ - clr_cmdbuf(); - for (i=0;i<12;i++) infobuf[i]=0; - if (sbpro_type==1) OUT(CDo_sel_i_d,0); -#if 0 - OUT(CDo_reset,0); - sbp_sleep(6*HZ); - OUT(CDo_enable,current_drive->drv_sel); -#endif - drvcmd[0]=CMD2_READ_VER; - response_count=12; - flags_cmd_out=f_putcmd; - i=cmd_out(); - if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i); - if (i==-7) teac_possible++; - j=0; - for (i=0;i<12;i++) j+=infobuf[i]; - if (j) - { - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %02X", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_IDX,"infobuf =%s\n", msgbuf); - for (i=0;i<12;i++) - sprintf(&msgbuf[i*3], " %c ", infobuf[i]); - msgbuf[i*3]=0; - msg(DBG_IDX,"infobuf =%s\n", msgbuf); - } - if (i>=0) - { - for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break; - if (i==5) - { - current_drive->drive_model[0]='C'; - current_drive->drive_model[1]='D'; - current_drive->drive_model[2]='2'; - current_drive->drive_model[3]='0'; - current_drive->drive_model[4]='0'; - current_drive->drive_model[5]=infobuf[i++]; - current_drive->drive_model[6]=infobuf[i++]; - current_drive->drive_model[7]=0; - current_drive->drv_type=drv_fam2; - } - } - } - if (!current_drive->drv_type) - { - /* check for TEAC CD-55A */ - msg(DBG_TEA,"teac_possible: %d\n",teac_possible); - for (j=1;j<=((current_drive->drv_id==0)?3:1);j++) - { - for (l=1;l<=((current_drive->drv_id==0)?10:1);l++) - { - msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l); - if (sbpro_type==1) OUT(CDo_reset,0); - else - { - OUT(CDo_enable,current_drive->drv_sel); - OUT(CDo_sel_i_d,0); - OUT(CDo_command,CMDT_RESET); - for (i=0;i<9;i++) OUT(CDo_command,0); - } - sbp_sleep(5*HZ/10); - OUT(CDo_enable,current_drive->drv_sel); - OUT(CDo_sel_i_d,0); - i=inb(CDi_status); - msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i); -#if 0 - if (i&s_not_result_ready) continue; /* drive not present or ready */ -#endif - i=inb(CDi_info); - msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i); - if (i==0x55) break; /* drive found */ - } - if (i==0x55) break; /* drive found */ - } - if (i==0x55) /* drive found */ - { - msg(DBG_TEA,"TEAC drive found.\n"); - clr_cmdbuf(); - flags_cmd_out=f_putcmd; - response_count=12; - drvcmd[0]=CMDT_READ_VER; - drvcmd[4]=response_count; - for (i=0;i<12;i++) infobuf[i]=0; - i=cmd_out_T(); - if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i); - for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break; - if (i==6) - { - current_drive->drive_model[0]='C'; - current_drive->drive_model[1]='D'; - current_drive->drive_model[2]='-'; - current_drive->drive_model[3]='5'; - current_drive->drive_model[4]='5'; - current_drive->drive_model[5]=0; - current_drive->drv_type=drv_famT; - } - } - } - if (!current_drive->drv_type) - { - msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id); - return (-522); - } - for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j]; - if (famL_drive) - { - u_char lcs_firm_e1[]="A E1"; - u_char lcs_firm_f4[]="A4F4"; - - for (j=0;j<4;j++) - if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break; - if (j==4) current_drive->drv_type=drv_e1; - - for (j=0;j<4;j++) - if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break; - if (j==4) current_drive->drv_type=drv_f4; - - if (current_drive->drv_type==drv_famL) ask_mail(); - } - else if (famT_drive) - { - j=infobuf[4]; /* one-byte version??? - here: 0x15 */ - if (j=='5') - { - current_drive->firmware_version[0]=infobuf[7]; - current_drive->firmware_version[1]=infobuf[8]; - current_drive->firmware_version[2]=infobuf[10]; - current_drive->firmware_version[3]=infobuf[11]; - } - else - { - if (j!=0x15) ask_mail(); - current_drive->firmware_version[0]='0'; - current_drive->firmware_version[1]='.'; - current_drive->firmware_version[2]='0'+(j>>4); - current_drive->firmware_version[3]='0'+(j&0x0f); - } - } - else /* CR-52x, CR-56x, CD200, ECS-AT */ - { - j = (current_drive->firmware_version[0] & 0x0F) * 100 + - (current_drive->firmware_version[2] & 0x0F) *10 + - (current_drive->firmware_version[3] & 0x0F); - if (fam0_drive) - { - if (j<200) current_drive->drv_type=drv_199; - else if (j<201) current_drive->drv_type=drv_200; - else if (j<210) current_drive->drv_type=drv_201; - else if (j<211) current_drive->drv_type=drv_210; - else if (j<300) current_drive->drv_type=drv_211; - else if (j>=300) current_drive->drv_type=drv_300; - } - else if (fam1_drive) - { - if (j<100) current_drive->drv_type=drv_099; - else - { - current_drive->drv_type=drv_100; - if ((j!=500)&&(j!=102)) ask_mail(); - } - } - else if (fam2_drive) - { - if (current_drive->drive_model[5]=='F') - { - if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210)) - ask_mail(); /* unknown version at time */ - } - else - { - msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n"); - if ((j!=101)&&(j!=35)) - ask_mail(); /* unknown version at time */ - } - } - else if (famV_drive) - { - if ((j==100)||(j==150)) current_drive->drv_type=drv_at; - ask_mail(); /* hopefully we get some feedback by this */ - } - } - msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type); - msg(DBG_INI,"check_version done.\n"); - return (0); -} -/*==========================================================================*/ -static void switch_drive(struct sbpcd_drive *p) -{ - current_drive = p; - OUT(CDo_enable,current_drive->drv_sel); - msg(DBG_DID,"drive %d (ID=%d) activated.\n", - current_drive - D_S, current_drive->drv_id); - return; -} -/*==========================================================================*/ -#ifdef PATH_CHECK -/* - * probe for the presence of an interface card - */ -static int __init check_card(int port) -{ -#undef N_RESPO -#define N_RESPO 20 - int i, j, k; - u_char response[N_RESPO]; - u_char save_port0; - u_char save_port3; - - msg(DBG_INI,"check_card entered.\n"); - save_port0=inb(port+0); - save_port3=inb(port+3); - - for (j=0;j0;i--) OUT(port+0,0); - for (k=0;k0;i--) - { - if (inb(port+1)&s_not_result_ready) continue; - response[k]=inb(port+0); - break; - } - } - for (i=0;i0;i--) OUT(port+0,0); - for (k=0;k0;i--) - { - if (inb(port+1)&s_not_result_ready) continue; - response[k]=inb(port+0); - break; - } - } - for (i=0;i0;i--) OUT(port+0,0); - for (k=0;k0;i--) - { - if (inb(port+1)&s_not_result_ready) continue; - response[k]=inb(port+0); - break; - } - } - for (i=0;i0;i--) OUT(port+0,0); - for (k=0;k0;i--) - { - if (inb(port+1)&s_not_result_ready) continue; - response[k]=inb(port+0); - break; - } - } - for (i=0;idrv_id=j; - if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1; - else p->drv_sel=j; - switch_drive(p); - msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j); - msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j); - i=check_version(); - if (i<0) msg(DBG_INI,"check_version returns %d.\n",i); - else - { - current_drive->drv_options=drv_pattern[j]; - if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150); - msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n", - current_drive - D_S, - current_drive->drv_id, - current_drive->drive_model, - current_drive->firmware_version, - CDo_command, - sbpro_type); - ndrives++; - } - } - for (j=ndrives;jpos_audio_end)-1; - if (i<0) return (-1); - i=cc_Seek(i,0); - return (i); -} -#endif /* FUTURE */ -/*==========================================================================*/ -static int ReadToC(void) -{ - int i, j; - current_drive->diskstate_flags &= ~toc_bit; - current_drive->ored_ctl_adr=0; - /* special handling of CD-I HE */ - if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) || - current_drive->xa_byte == 0x10) - { - current_drive->TocBuffer[1].nixbyte=0; - current_drive->TocBuffer[1].ctl_adr=0x40; - current_drive->TocBuffer[1].number=1; - current_drive->TocBuffer[1].format=0; - current_drive->TocBuffer[1].address=blk2msf(0); - current_drive->ored_ctl_adr |= 0x40; - current_drive->n_first_track = 1; - current_drive->n_last_track = 1; - current_drive->xa_byte = 0x10; - j = 2; - } else - for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++) - { - i=cc_ReadTocEntry(j); - if (i<0) - { - msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i); - return (i); - } - current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte; - current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr; - current_drive->TocBuffer[j].number=current_drive->TocEnt_number; - current_drive->TocBuffer[j].format=current_drive->TocEnt_format; - current_drive->TocBuffer[j].address=current_drive->TocEnt_address; - current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr; - } - /* fake entry for LeadOut Track */ - current_drive->TocBuffer[j].nixbyte=0; - current_drive->TocBuffer[j].ctl_adr=0; - current_drive->TocBuffer[j].number=CDROM_LEADOUT; - current_drive->TocBuffer[j].format=0; - current_drive->TocBuffer[j].address=current_drive->size_msf; - - current_drive->diskstate_flags |= toc_bit; - return (0); -} -/*==========================================================================*/ -static int DiskInfo(void) -{ - int i, j; - - current_drive->mode=READ_M1; - -#undef LOOP_COUNT -#define LOOP_COUNT 10 /* needed for some "old" drives */ - - msg(DBG_000,"DiskInfo entered.\n"); - for (j=1;j=0) break; - msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i); -#if 0 - i=cc_DriveReset(); -#endif - if (!fam0_drive && j == 2) break; - } - if (j==LOOP_COUNT) return (-33); /* give up */ - - i=cc_ReadTocDescr(); - if (i<0) - { - msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i); - return (i); - } - i=ReadToC(); - if (i<0) - { - msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i); - return (i); - } - i=cc_CheckMultiSession(); - if (i<0) - { - msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i); - return (i); - } - if (current_drive->f_multisession) current_drive->sbp_bufsiz=1; /* possibly a weird PhotoCD */ - else current_drive->sbp_bufsiz=buffers; - i=cc_ReadTocEntry(current_drive->n_first_track); - if (i<0) - { - msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i); - return (i); - } - i=cc_ReadUPC(); - if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i); - if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10)) - { - /* XA disk with old drive */ - cc_ModeSelect(CD_FRAMESIZE_RAW1); - cc_ModeSense(); - } - if (famT_drive) cc_prep_mode_T(); - msg(DBG_000,"DiskInfo done.\n"); - return (0); -} - -static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr) -{ - struct sbpcd_drive *p = cdi->handle; - int st; - - if (CDSL_CURRENT != slot_nr) { - /* we have no changer support */ - return -EINVAL; - } - - cc_ReadStatus(); - st=ResponseStatus(); - if (st<0) - { - msg(DBG_INF,"sbpcd_drive_status: timeout.\n"); - return (0); - } - msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked); - msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed); - msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in); - msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok); - msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning); - msg(DBG_000,"Drive Status: busy =%d.\n", st_busy); - -#if 0 - if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN; - if (p->status_bits & p_disk_ok) return CDS_DISC_OK; - if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY; - - return CDS_NO_DISC; -#else - if (p->status_bits & p_spinning) return CDS_DISC_OK; -/* return CDS_TRAY_OPEN; */ - return CDS_NO_DISC; - -#endif - -} - - -/*==========================================================================*/ -#ifdef FUTURE -/* - * called always if driver gets entered - * returns 0 or ERROR2 or ERROR15 - */ -static int prepare(u_char func, u_char subfunc) -{ - int i; - - if (fam0L_drive) - { - i=inb(CDi_status); - if (i&s_attention) GetStatus(); - } - else if (fam1_drive) GetStatus(); - else if (fam2_drive) GetStatus(); - else if (famT_drive) GetStatus(); - if (current_drive->CD_changed==0xFF) - { - current_drive->diskstate_flags=0; - current_drive->audio_state=0; - if (!st_diskok) - { - i=check_allowed1(func,subfunc); - if (i<0) return (-2); - } - else - { - i=check_allowed3(func,subfunc); - if (i<0) - { - current_drive->CD_changed=1; - return (-15); - } - } - } - else - { - if (!st_diskok) - { - current_drive->diskstate_flags=0; - current_drive->audio_state=0; - i=check_allowed1(func,subfunc); - if (i<0) return (-2); - } - else - { - if (st_busy) - { - if (current_drive->audio_state!=audio_pausing) - { - i=check_allowed2(func,subfunc); - if (i<0) return (-2); - } - } - else - { - if (current_drive->audio_state==audio_playing) seek_pos_audio_end(); - current_drive->audio_state=0; - } - if (!frame_size_valid) - { - i=DiskInfo(); - if (i<0) - { - current_drive->diskstate_flags=0; - current_drive->audio_state=0; - i=check_allowed1(func,subfunc); - if (i<0) return (-2); - } - } - } - } - return (0); -} -#endif /* FUTURE */ -/*==========================================================================*/ -/*==========================================================================*/ -/* - * Check the results of the "get status" command. - */ -static int sbp_status(void) -{ - int st; - - st=ResponseStatus(); - if (st<0) - { - msg(DBG_INF,"sbp_status: timeout.\n"); - return (0); - } - - if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n"); - - if (st_check) - { - msg(DBG_INF,"st_check detected - retrying.\n"); - return (0); - } - if (!st_door_closed) - { - msg(DBG_INF,"door is open - retrying.\n"); - return (0); - } - if (!st_caddy_in) - { - msg(DBG_INF,"disk removed - retrying.\n"); - return (0); - } - if (!st_diskok) - { - msg(DBG_INF,"!st_diskok detected - retrying.\n"); - return (0); - } - if (st_busy) - { - msg(DBG_INF,"st_busy detected - retrying.\n"); - return (0); - } - return (1); -} -/*==========================================================================*/ - -static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp) -{ - struct sbpcd_drive *p = cdi->handle; - ms_infp->addr_format = CDROM_LBA; - ms_infp->addr.lba = p->lba_multi; - if (p->f_multisession) - ms_infp->xa_flag=1; /* valid redirection address */ - else - ms_infp->xa_flag=0; /* invalid redirection address */ - - return 0; -} - -static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, - void * arg) -{ - struct sbpcd_drive *p = cdi->handle; - int i, st, j; - - msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg); - if (p->drv_id==-1) { - msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name); - return (-ENXIO); /* no such drive */ - } - down(&ioctl_read_sem); - if (p != current_drive) - switch_drive(p); - - msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd); - switch (cmd) /* Sun-compatible */ - { - - case CDROMPAUSE: /* Pause the drive */ - msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n"); - /* pause the drive unit when it is currently in PLAY mode, */ - /* or reset the starting and ending locations when in PAUSED mode. */ - /* If applicable, at the next stopping point it reaches */ - /* the drive will discontinue playing. */ - switch (current_drive->audio_state) - { - case audio_playing: - if (famL_drive) i=cc_ReadSubQ(); - else i=cc_Pause_Resume(1); - if (i<0) RETURN_UP(-EIO); - if (famL_drive) i=cc_Pause_Resume(1); - else i=cc_ReadSubQ(); - if (i<0) RETURN_UP(-EIO); - current_drive->pos_audio_start=current_drive->SubQ_run_tot; - current_drive->audio_state=audio_pausing; - RETURN_UP(0); - case audio_pausing: - i=cc_Seek(current_drive->pos_audio_start,1); - if (i<0) RETURN_UP(-EIO); - RETURN_UP(0); - default: - RETURN_UP(-EINVAL); - } - - case CDROMRESUME: /* resume paused audio play */ - msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n"); - /* resume playing audio tracks when a previous PLAY AUDIO call has */ - /* been paused with a PAUSE command. */ - /* It will resume playing from the location saved in SubQ_run_tot. */ - if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL); - if (famL_drive) - i=cc_PlayAudio(current_drive->pos_audio_start, - current_drive->pos_audio_end); - else i=cc_Pause_Resume(3); - if (i<0) RETURN_UP(-EIO); - current_drive->audio_state=audio_playing; - RETURN_UP(0); - - case CDROMPLAYMSF: - msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n"); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - if (current_drive->audio_state==audio_playing) - { - i=cc_Pause_Resume(1); - if (i<0) RETURN_UP(-EIO); - i=cc_ReadSubQ(); - if (i<0) RETURN_UP(-EIO); - current_drive->pos_audio_start=current_drive->SubQ_run_tot; - i=cc_Seek(current_drive->pos_audio_start,1); - } - memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf)); - /* values come as msf-bin */ - current_drive->pos_audio_start = (msf.cdmsf_min0<<16) | - (msf.cdmsf_sec0<<8) | - msf.cdmsf_frame0; - current_drive->pos_audio_end = (msf.cdmsf_min1<<16) | - (msf.cdmsf_sec1<<8) | - msf.cdmsf_frame1; - msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n", - current_drive->pos_audio_start,current_drive->pos_audio_end); - i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end); - if (i<0) - { - msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i); - DriveReset(); - current_drive->audio_state=0; - RETURN_UP(-EIO); - } - current_drive->audio_state=audio_playing; - RETURN_UP(0); - - case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ - msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n"); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - if (current_drive->audio_state==audio_playing) - { - msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n"); -#if 1 - RETURN_UP(0); /* just let us play on */ -#else - RETURN_UP(-EINVAL); /* play on, but say "error" */ -#endif - } - memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti)); - msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n", - ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1); - if (ti.cdti_trk0n_first_track) RETURN_UP(-EINVAL); - if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL); - if (ti.cdti_trk1current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track; - current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address; - current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address; - i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end); - if (i<0) - { - msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i); - DriveReset(); - current_drive->audio_state=0; - RETURN_UP(-EIO); - } - current_drive->audio_state=audio_playing; - RETURN_UP(0); - - case CDROMREADTOCHDR: /* Read the table of contents header */ - msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n"); - tochdr.cdth_trk0=current_drive->n_first_track; - tochdr.cdth_trk1=current_drive->n_last_track; - memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr)); - RETURN_UP(0); - - case CDROMREADTOCENTRY: /* Read an entry in the table of contents */ - msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n"); - memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry)); - i=tocentry.cdte_track; - if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1; - else if (in_first_track||i>current_drive->n_last_track) - RETURN_UP(-EINVAL); - tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F; - tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F; - tocentry.cdte_datamode=current_drive->TocBuffer[i].format; - if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */ - { - tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF; - tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF; - tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF; - } - else if (tocentry.cdte_format==CDROM_LBA) /* blk required */ - tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address); - else RETURN_UP(-EINVAL); - memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry)); - RETURN_UP(0); - - case CDROMSTOP: /* Spin down the drive */ - msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n"); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - i=cc_Pause_Resume(1); - current_drive->audio_state=0; -#if 0 - cc_DriveReset(); -#endif - RETURN_UP(i); - - case CDROMSTART: /* Spin up the drive */ - msg(DBG_IOC,"ioctl: CDROMSTART entered.\n"); - cc_SpinUp(); - current_drive->audio_state=0; - RETURN_UP(0); - - case CDROMVOLCTRL: /* Volume control */ - msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n"); - memcpy(&volctrl,(char *) arg,sizeof(volctrl)); - current_drive->vol_chan0=0; - current_drive->vol_ctrl0=volctrl.channel0; - current_drive->vol_chan1=1; - current_drive->vol_ctrl1=volctrl.channel1; - i=cc_SetVolume(); - RETURN_UP(0); - - case CDROMVOLREAD: /* read Volume settings from drive */ - msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n"); - st=cc_GetVolume(); - if (st<0) RETURN_UP(st); - volctrl.channel0=current_drive->vol_ctrl0; - volctrl.channel1=current_drive->vol_ctrl1; - volctrl.channel2=0; - volctrl.channel2=0; - memcpy((void *)arg,&volctrl,sizeof(volctrl)); - RETURN_UP(0); - - case CDROMSUBCHNL: /* Get subchannel info */ - msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n"); - /* Bogus, I can do better than this! --AJK - if ((st_spinning)||(!subq_valid)) { - i=cc_ReadSubQ(); - if (i<0) RETURN_UP(-EIO); - } - */ - i=cc_ReadSubQ(); - if (i<0) { - j=cc_ReadError(); /* clear out error status from drive */ - current_drive->audio_state=CDROM_AUDIO_NO_STATUS; - /* get and set the disk state here, - probably not the right place, but who cares! - It makes it work properly! --AJK */ - if (current_drive->CD_changed==0xFF) { - msg(DBG_000,"Disk changed detect\n"); - current_drive->diskstate_flags &= ~cd_size_bit; - } - RETURN_UP(-EIO); - } - if (current_drive->CD_changed==0xFF) { - /* reread the TOC because the disk has changed! --AJK */ - msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n"); - i=DiskInfo(); - if(i==0) { - current_drive->CD_changed=0x00; /* cd has changed, procede, */ - RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */ - } else { - RETURN_UP(-EIO); /* we weren't ready yet! --AJK */ - } - } - memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl)); - /* - This virtual crap is very bogus! - It doesn't detect when the cd is done playing audio! - Lets do this right with proper hardware register reading! - */ - cc_ReadStatus(); - i=ResponseStatus(); - msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked); - msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed); - msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in); - msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok); - msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning); - msg(DBG_000,"Drive Status: busy =%d.\n", st_busy); - /* st_busy indicates if it's _ACTUALLY_ playing audio */ - switch (current_drive->audio_state) - { - case audio_playing: - if(st_busy==0) { - /* CD has stopped playing audio --AJK */ - current_drive->audio_state=audio_completed; - SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED; - } else { - SC.cdsc_audiostatus=CDROM_AUDIO_PLAY; - } - break; - case audio_pausing: - SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED; - break; - case audio_completed: - SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED; - break; - default: - SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS; - break; - } - SC.cdsc_adr=current_drive->SubQ_ctl_adr; - SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4; - SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk); - SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx); - if (SC.cdsc_format==CDROM_LBA) - { - SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot); - SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk); - } - else /* not only if (SC.cdsc_format==CDROM_MSF) */ - { - SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF; - SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF; - SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF; - SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF; - SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF; - SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF; - } - memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl)); - msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n", - SC.cdsc_format,SC.cdsc_audiostatus, - SC.cdsc_adr,SC.cdsc_ctrl, - SC.cdsc_trk,SC.cdsc_ind, - SC.cdsc_absaddr,SC.cdsc_reladdr); - RETURN_UP(0); - - default: - msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); - RETURN_UP(-EINVAL); - } /* end switch(cmd) */ -} -/*==========================================================================*/ -/* - * Take care of the different block sizes between cdrom and Linux. - */ -static void sbp_transfer(struct request *req) -{ - long offs; - - while ( (req->nr_sectors > 0) && - (req->sector/4 >= current_drive->sbp_first_frame) && - (req->sector/4 <= current_drive->sbp_last_frame) ) - { - offs = (req->sector - current_drive->sbp_first_frame * 4) * 512; - memcpy(req->buffer, current_drive->sbp_buf + offs, 512); - req->nr_sectors--; - req->sector++; - req->buffer += 512; - } -} -/*==========================================================================*/ -/* - * special end_request for sbpcd to solve CURRENT==NULL bug. (GTL) - * GTL = Gonzalo Tornaria - * - * This is a kludge so we don't need to modify end_request. - * We put the req we take out after INIT_REQUEST in the requests list, - * so that end_request will discard it. - * - * The bug could be present in other block devices, perhaps we - * should modify INIT_REQUEST and end_request instead, and - * change every block device.. - * - * Could be a race here?? Could e.g. a timer interrupt schedule() us? - * If so, we should copy end_request here, and do it right.. (or - * modify end_request and the block devices). - * - * In any case, the race here would be much small than it was, and - * I couldn't reproduce.. - * - * The race could be: suppose CURRENT==NULL. We put our req in the list, - * and we are scheduled. Other process takes over, and gets into - * do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so - * proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in - * end_request, but now CURRENT==NULL... oops! - * - */ -#undef DEBUG_GTL - -/*==========================================================================*/ -/* - * I/O request routine, called from Linux kernel. - */ -static void do_sbpcd_request(request_queue_t * q) -{ - u_int block; - u_int nsect; - int status_tries, data_tries; - struct request *req; - struct sbpcd_drive *p; -#ifdef DEBUG_GTL - static int xx_nr=0; - int xnr; -#endif - - request_loop: -#ifdef DEBUG_GTL - xnr=++xx_nr; - - req = elv_next_request(q); - - if (!req) - { - printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n", - xnr, current->pid, jiffies); - printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n", - xnr, jiffies); - return; - } - - printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n", - xnr, req, req->sector, req->nr_sectors, current->pid, jiffies); -#endif - - req = elv_next_request(q); /* take out our request so no other */ - if (!req) - return; - - if (req -> sector == -1) - end_request(req, 0); - spin_unlock_irq(q->queue_lock); - - down(&ioctl_read_sem); - if (rq_data_dir(elv_next_request(q)) != READ) - { - msg(DBG_INF, "bad cmd %d\n", req->cmd[0]); - goto err_done; - } - p = req->rq_disk->private_data; -#if OLD_BUSY - while (busy_audio) sbp_sleep(HZ); /* wait a bit */ - busy_data=1; -#endif /* OLD_BUSY */ - - if (p->audio_state==audio_playing) goto err_done; - if (p != current_drive) - switch_drive(p); - - block = req->sector; /* always numbered as 512-byte-pieces */ - nsect = req->nr_sectors; /* always counted as 512-byte-pieces */ - - msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect); -#if 0 - msg(DBG_MUL,"read LBA %d\n", block/4); -#endif - - sbp_transfer(req); - /* if we satisfied the request from the buffer, we're done. */ - if (req->nr_sectors == 0) - { -#ifdef DEBUG_GTL - printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n", - xnr, req, req->sector, req->nr_sectors, jiffies); -#endif - up(&ioctl_read_sem); - spin_lock_irq(q->queue_lock); - end_request(req, 1); - goto request_loop; - } - -#ifdef FUTURE - i=prepare(0,0); /* at moment not really a hassle check, but ... */ - if (i!=0) - msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i); -#endif /* FUTURE */ - - if (!st_spinning) cc_SpinUp(); - - for (data_tries=n_retries; data_tries > 0; data_tries--) - { - for (status_tries=3; status_tries > 0; status_tries--) - { - flags_cmd_out |= f_respo3; - cc_ReadStatus(); - if (sbp_status() != 0) break; - if (st_check) cc_ReadError(); - sbp_sleep(1); /* wait a bit, try again */ - } - if (status_tries == 0) - { - msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__); - break; - } - - sbp_read_cmd(req); - sbp_sleep(0); - if (sbp_data(req) != 0) - { -#ifdef SAFE_MIXED - current_drive->has_data=2; /* is really a data disk */ -#endif /* SAFE_MIXED */ -#ifdef DEBUG_GTL - printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n", - xnr, req, req->sector, req->nr_sectors, jiffies); -#endif - up(&ioctl_read_sem); - spin_lock_irq(q->queue_lock); - end_request(req, 1); - goto request_loop; - } - } - - err_done: -#if OLD_BUSY - busy_data=0; -#endif /* OLD_BUSY */ -#ifdef DEBUG_GTL - printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n", - xnr, req, req->sector, req->nr_sectors, jiffies); -#endif - up(&ioctl_read_sem); - sbp_sleep(0); /* wait a bit, try again */ - spin_lock_irq(q->queue_lock); - end_request(req, 0); - goto request_loop; -} -/*==========================================================================*/ -/* - * build and send the READ command. - */ -static void sbp_read_cmd(struct request *req) -{ -#undef OLD - - int i; - int block; - - current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */ - current_drive->sbp_current = 0; - block=req->sector/4; - if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm) - current_drive->sbp_read_frames = current_drive->sbp_bufsiz; - else - { - current_drive->sbp_read_frames=current_drive->CDsize_frm-block; - /* avoid reading past end of data */ - if (current_drive->sbp_read_frames < 1) - { - msg(DBG_INF,"requested frame %d, CD size %d ???\n", - block, current_drive->CDsize_frm); - current_drive->sbp_read_frames=1; - } - } - - flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; - clr_cmdbuf(); - if (famV_drive) - { - drvcmd[0]=CMDV_READ; - lba2msf(block,&drvcmd[1]); /* msf-bcd format required */ - bin2bcdx(&drvcmd[1]); - bin2bcdx(&drvcmd[2]); - bin2bcdx(&drvcmd[3]); - drvcmd[4]=current_drive->sbp_read_frames>>8; - drvcmd[5]=current_drive->sbp_read_frames&0xff; - drvcmd[6]=0x02; /* flag "msf-bcd" */ - } - else if (fam0L_drive) - { - flags_cmd_out |= f_lopsta | f_getsta | f_bit1; - if (current_drive->xa_byte==0x20) - { - cmd_type=READ_M2; - drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */ - drvcmd[1]=(block>>16)&0x0ff; - drvcmd[2]=(block>>8)&0x0ff; - drvcmd[3]=block&0x0ff; - drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff; - drvcmd[5]=current_drive->sbp_read_frames&0x0ff; - } - else - { - drvcmd[0]=CMD0_READ; /* "read frames", old drives */ - if (current_drive->drv_type>=drv_201) - { - lba2msf(block,&drvcmd[1]); /* msf-bcd format required */ - bin2bcdx(&drvcmd[1]); - bin2bcdx(&drvcmd[2]); - bin2bcdx(&drvcmd[3]); - } - else - { - drvcmd[1]=(block>>16)&0x0ff; - drvcmd[2]=(block>>8)&0x0ff; - drvcmd[3]=block&0x0ff; - } - drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff; - drvcmd[5]=current_drive->sbp_read_frames&0x0ff; - drvcmd[6]=(current_drive->drv_typesbp_read_frames>>8)&0x0ff; - drvcmd[6]=current_drive->sbp_read_frames&0x0ff; - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_READ; - lba2msf(block,&drvcmd[1]); /* msf-bin format required */ - drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff; - drvcmd[5]=current_drive->sbp_read_frames&0x0ff; - drvcmd[6]=0x02; - } - else if (famT_drive) - { - drvcmd[0]=CMDT_READ; - drvcmd[2]=(block>>24)&0x0ff; - drvcmd[3]=(block>>16)&0x0ff; - drvcmd[4]=(block>>8)&0x0ff; - drvcmd[5]=block&0x0ff; - drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff; - drvcmd[8]=current_drive->sbp_read_frames&0x0ff; - } - flags_cmd_out=f_putcmd; - response_count=0; - i=cmd_out(); - if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i); - return; -} -/*==========================================================================*/ -/* - * Check the completion of the read-data command. On success, read - * the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer. - */ -static int sbp_data(struct request *req) -{ - int i=0, j=0, l, frame; - u_int try=0; - u_long timeout; - u_char *p; - u_int data_tries = 0; - u_int data_waits = 0; - u_int data_retrying = 0; - int error_flag; - int xa_count; - int max_latency; - int success; - int wait; - int duration; - - error_flag=0; - success=0; -#if LONG_TIMING - max_latency=9*HZ; -#else - if (current_drive->f_multisession) max_latency=15*HZ; - else max_latency=5*HZ; -#endif - duration=jiffies; - for (frame=0;framesbp_read_frames&&!error_flag; frame++) - { - SBPCD_CLI; - - del_timer(&data_timer); - data_timer.expires=jiffies+max_latency; - timed_out_data=0; - add_timer(&data_timer); - while (!timed_out_data) - { - if (current_drive->f_multisession) try=maxtim_data*4; - else try=maxtim_data; - msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try); - for ( ; try!=0;try--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (fam0LV_drive) if (j&s_attention) break; - } - if (!(j&s_not_data_ready)) goto data_ready; - if (try==0) - { - if (data_retrying == 0) data_waits++; - data_retrying = 1; - msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n"); - sbp_sleep(1); - try = 1; - } - } - msg(DBG_INF,"sbp_data: CDi_status loop expired.\n"); - data_ready: - del_timer(&data_timer); - - if (timed_out_data) - { - msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j); - error_flag++; - } - if (try==0) - { - msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j); - error_flag++; - } - if (!(j&s_not_result_ready)) - { - msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j); - response_count=20; - j=ResponseInfo(); - j=inb(CDi_status); - } - if (j&s_not_data_ready) - { - if ((current_drive->ored_ctl_adr&0x40)==0) - msg(DBG_INF, "CD contains no data tracks.\n"); - else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j); - error_flag++; - } - SBPCD_STI; - if (error_flag) break; - - msg(DBG_000, "sbp_data: beginning to read.\n"); - p = current_drive->sbp_buf + frame * CD_FRAMESIZE; - if (sbpro_type==1) OUT(CDo_sel_i_d,1); - if (cmd_type==READ_M2) { - if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1); - else insb(CDi_data, xa_head_buf, CD_XA_HEAD); - } - if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1); - else insb(CDi_data, p, CD_FRAMESIZE); - if (cmd_type==READ_M2) { - if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1); - else insb(CDi_data, xa_tail_buf, CD_XA_TAIL); - } - current_drive->sbp_current++; - if (sbpro_type==1) OUT(CDo_sel_i_d,0); - if (cmd_type==READ_M2) - { - for (xa_count=0;xa_count= 1000) - { - msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries); - data_waits = data_tries = 0; - } - } - duration=jiffies-duration; - msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration); - if (famT_drive) - { - wait=8; - do - { - if (teac==2) - { - if ((i=CDi_stat_loop_T()) == -1) break; - } - else - { - sbp_sleep(1); - OUT(CDo_sel_i_d,0); - i=inb(CDi_status); - } - if (!(i&s_not_data_ready)) - { - OUT(CDo_sel_i_d,1); - j=0; - do - { - if (do_16bit) i=inw(CDi_data); - else i=inb(CDi_data); - j++; - i=inb(CDi_status); - } - while (!(i&s_not_data_ready)); - msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j); - } - if (!(i&s_not_result_ready)) - { - OUT(CDo_sel_i_d,0); - l=0; - do - { - infobuf[l++]=inb(CDi_info); - i=inb(CDi_status); - } - while (!(i&s_not_result_ready)); - if (infobuf[0]==0x00) success=1; -#if 1 - for (j=0;j1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion); - else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n"); - clr_cmdbuf(); - drvcmd[0]=CMDT_READ_ERR; - j=cmd_out_T(); /* !!! recursive here !!! */ - --recursion; - sbp_sleep(1); - } - while (j<0); - current_drive->error_state=infobuf[2]; - current_drive->b3=infobuf[3]; - current_drive->b4=infobuf[4]; - } - break; - } - else - { -#if 0 - msg(DBG_TEA, "============= waiting for result=================.\n"); - sbp_sleep(1); -#endif - } - } - while (wait--); - } - - if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ - { - msg(DBG_TEA, "================error flag: %d=================.\n", error_flag); - msg(DBG_INF,"sbp_data: read aborted by drive.\n"); -#if 1 - i=cc_DriveReset(); /* ugly fix to prevent a hang */ -#else - i=cc_ReadError(); -#endif - return (0); - } - - if (fam0LV_drive) - { - SBPCD_CLI; - i=maxtim_data; - for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--) - { - for ( ;i!=0;i--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (j&s_attention) break; - } - if (i != 0 || time_after_eq(jiffies, timeout)) break; - sbp_sleep(0); - i = 1; - } - if (i==0) msg(DBG_INF,"status timeout after READ.\n"); - if (!(j&s_attention)) - { - msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n"); - i=cc_DriveReset(); /* ugly fix to prevent a hang */ - SBPCD_STI; - return (0); - } - SBPCD_STI; - } - -#if 0 - if (!success) -#endif - do - { - if (fam0LV_drive) cc_ReadStatus(); -#if 1 - if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i); -#endif - i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */ -#if 1 - if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i); -#endif - if (i<0) - { - msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits); - return (0); - } - } - while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success))); - if (st_check) - { - i=cc_ReadError(); - msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i); - return (0); - } - if (fatal_err) - { - fatal_err=0; - current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */ - current_drive->sbp_current = 0; - msg(DBG_INF,"sbp_data: fatal_err - retrying.\n"); - return (0); - } - - current_drive->sbp_first_frame = req -> sector / 4; - current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1; - sbp_transfer(req); - return (1); -} -/*==========================================================================*/ - -static int sbpcd_block_open(struct inode *inode, struct file *file) -{ - struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; - return cdrom_open(p->sbpcd_infop, inode, file); -} - -static int sbpcd_block_release(struct inode *inode, struct file *file) -{ - struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; - return cdrom_release(p->sbpcd_infop, file); -} - -static int sbpcd_block_ioctl(struct inode *inode, struct file *file, - unsigned cmd, unsigned long arg) -{ - struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; - struct cdrom_device_info *cdi = p->sbpcd_infop; - int ret, i; - - ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg); - if (ret != -ENOSYS) - return ret; - - msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg); - if (p->drv_id==-1) { - msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name); - return (-ENXIO); /* no such drive */ - } - down(&ioctl_read_sem); - if (p != current_drive) - switch_drive(p); - - msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd); - switch (cmd) /* Sun-compatible */ - { - case DDIOCSDBG: /* DDI Debug */ - if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM); - i=sbpcd_dbg_ioctl(arg,1); - RETURN_UP(i); - case CDROMRESET: /* hard reset the drive */ - msg(DBG_IOC,"ioctl: CDROMRESET entered.\n"); - i=DriveReset(); - current_drive->audio_state=0; - RETURN_UP(i); - - case CDROMREADMODE1: - msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n"); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - cc_ModeSelect(CD_FRAMESIZE); - cc_ModeSense(); - current_drive->mode=READ_M1; - RETURN_UP(0); - - case CDROMREADMODE2: /* not usable at the moment */ - msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n"); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - cc_ModeSelect(CD_FRAMESIZE_RAW1); - cc_ModeSense(); - current_drive->mode=READ_M2; - RETURN_UP(0); - - case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */ - msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n"); - if (current_drive->sbp_audsiz>0) - vfree(current_drive->aud_buf); - current_drive->aud_buf=NULL; - current_drive->sbp_audsiz=arg; - - if (current_drive->sbp_audsiz>16) - { - current_drive->sbp_audsiz = 0; - RETURN_UP(current_drive->sbp_audsiz); - } - - if (current_drive->sbp_audsiz>0) - { - current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW); - if (current_drive->aud_buf==NULL) - { - msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz); - current_drive->sbp_audsiz=0; - } - else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz); - } - RETURN_UP(current_drive->sbp_audsiz); - - case CDROMREADAUDIO: - { /* start of CDROMREADAUDIO */ - int i=0, j=0, frame, block=0; - u_int try=0; - u_long timeout; - u_char *p; - u_int data_tries = 0; - u_int data_waits = 0; - u_int data_retrying = 0; - int status_tries; - int error_flag; - - msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n"); - if (fam0_drive) RETURN_UP(-EINVAL); - if (famL_drive) RETURN_UP(-EINVAL); - if (famV_drive) RETURN_UP(-EINVAL); - if (famT_drive) RETURN_UP(-EINVAL); -#ifdef SAFE_MIXED - if (current_drive->has_data>1) RETURN_UP(-EBUSY); -#endif /* SAFE_MIXED */ - if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL); - if (copy_from_user(&read_audio, (void __user *)arg, - sizeof(struct cdrom_read_audio))) - RETURN_UP(-EFAULT); - if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL); - if (!access_ok(VERIFY_WRITE, read_audio.buf, - read_audio.nframes*CD_FRAMESIZE_RAW)) - RETURN_UP(-EFAULT); - - if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */ - block=msf2lba(&read_audio.addr.msf.minute); - else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */ - block=read_audio.addr.lba; - else RETURN_UP(-EINVAL); -#if 000 - i=cc_SetSpeed(speed_150,0,0); - if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i); -#endif - msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n", - block, blk2msf(block)); - msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n"); -#if OLD_BUSY - while (busy_data) sbp_sleep(HZ/10); /* wait a bit */ - busy_audio=1; -#endif /* OLD_BUSY */ - error_flag=0; - for (data_tries=5; data_tries>0; data_tries--) - { - msg(DBG_AUD,"data_tries=%d ...\n", data_tries); - current_drive->mode=READ_AU; - cc_ModeSelect(CD_FRAMESIZE_RAW); - cc_ModeSense(); - for (status_tries=3; status_tries > 0; status_tries--) - { - flags_cmd_out |= f_respo3; - cc_ReadStatus(); - if (sbp_status() != 0) break; - if (st_check) cc_ReadError(); - sbp_sleep(1); /* wait a bit, try again */ - } - if (status_tries == 0) - { - msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__); - continue; - } - msg(DBG_AUD,"read_audio: sbp_status: ok.\n"); - - flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; - if (fam0L_drive) - { - flags_cmd_out |= f_lopsta | f_getsta | f_bit1; - cmd_type=READ_M2; - drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */ - drvcmd[1]=(block>>16)&0x000000ff; - drvcmd[2]=(block>>8)&0x000000ff; - drvcmd[3]=block&0x000000ff; - drvcmd[4]=0; - drvcmd[5]=read_audio.nframes; /* # of frames */ - drvcmd[6]=0; - } - else if (fam1_drive) - { - drvcmd[0]=CMD1_READ; /* "read frames", new drives */ - lba2msf(block,&drvcmd[1]); /* msf-bin format required */ - drvcmd[4]=0; - drvcmd[5]=0; - drvcmd[6]=read_audio.nframes; /* # of frames */ - } - else if (fam2_drive) - { - drvcmd[0]=CMD2_READ_XA2; - lba2msf(block,&drvcmd[1]); /* msf-bin format required */ - drvcmd[4]=0; - drvcmd[5]=read_audio.nframes; /* # of frames */ - drvcmd[6]=0x11; /* raw mode */ - } - else if (famT_drive) /* CD-55A: not tested yet */ - { - } - msg(DBG_AUD,"read_audio: before giving \"read\" command.\n"); - flags_cmd_out=f_putcmd; - response_count=0; - i=cmd_out(); - if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i); - sbp_sleep(0); - msg(DBG_AUD,"read_audio: after giving \"read\" command.\n"); - for (frame=1;frame<2 && !error_flag; frame++) - { - try=maxtim_data; - for (timeout=jiffies+9*HZ; ; ) - { - for ( ; try!=0;try--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (fam0L_drive) if (j&s_attention) break; - } - if (try != 0 || time_after_eq(jiffies, timeout)) break; - if (data_retrying == 0) data_waits++; - data_retrying = 1; - sbp_sleep(1); - try = 1; - } - if (try==0) - { - msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n"); - error_flag++; - break; - } - msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n"); - if (j&s_not_data_ready) - { - msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n"); - error_flag++; - break; - } - msg(DBG_AUD,"read_audio: before reading data.\n"); - error_flag=0; - p = current_drive->aud_buf; - if (sbpro_type==1) OUT(CDo_sel_i_d,1); - if (do_16bit) - { - u_short *p2 = (u_short *) p; - - for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) - { - if ((inb_p(CDi_status)&s_not_data_ready)) continue; - - /* get one sample */ - *p2++ = inw_p(CDi_data); - *p2++ = inw_p(CDi_data); - } - } else { - for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) - { - if ((inb_p(CDi_status)&s_not_data_ready)) continue; - - /* get one sample */ - *p++ = inb_p(CDi_data); - *p++ = inb_p(CDi_data); - *p++ = inb_p(CDi_data); - *p++ = inb_p(CDi_data); - } - } - if (sbpro_type==1) OUT(CDo_sel_i_d,0); - data_retrying = 0; - } - msg(DBG_AUD,"read_audio: after reading data.\n"); - if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ - { - msg(DBG_AUD,"read_audio: read aborted by drive\n"); -#if 0000 - i=cc_DriveReset(); /* ugly fix to prevent a hang */ -#else - i=cc_ReadError(); -#endif - continue; - } - if (fam0L_drive) - { - i=maxtim_data; - for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--) - { - for ( ;i!=0;i--) - { - j=inb(CDi_status); - if (!(j&s_not_data_ready)) break; - if (!(j&s_not_result_ready)) break; - if (j&s_attention) break; - } - if (i != 0 || time_after_eq(jiffies, timeout)) break; - sbp_sleep(0); - i = 1; - } - if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ"); - if (!(j&s_attention)) - { - msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"); - i=cc_DriveReset(); /* ugly fix to prevent a hang */ - continue; - } - } - do - { - if (fam0L_drive) cc_ReadStatus(); - i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */ - if (i<0) { msg(DBG_AUD, - "read_audio: cc_ReadStatus error after read: %02X\n", - current_drive->status_bits); - continue; /* FIXME */ - } - } - while ((fam0L_drive)&&(!st_check)&&(!(i&p_success))); - if (st_check) - { - i=cc_ReadError(); - msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i); - continue; - } - if (copy_to_user(read_audio.buf, - current_drive->aud_buf, - read_audio.nframes * CD_FRAMESIZE_RAW)) - RETURN_UP(-EFAULT); - msg(DBG_AUD,"read_audio: copy_to_user done.\n"); - break; - } - cc_ModeSelect(CD_FRAMESIZE); - cc_ModeSense(); - current_drive->mode=READ_M1; -#if OLD_BUSY - busy_audio=0; -#endif /* OLD_BUSY */ - if (data_tries == 0) - { - msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__); - RETURN_UP(-EIO); - } - msg(DBG_AUD,"read_audio: successful return.\n"); - RETURN_UP(0); - } /* end of CDROMREADAUDIO */ - - default: - msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); - RETURN_UP(-EINVAL); - } /* end switch(cmd) */ -} - -static int sbpcd_block_media_changed(struct gendisk *disk) -{ - struct sbpcd_drive *p = disk->private_data; - return cdrom_media_changed(p->sbpcd_infop); -} - -static struct block_device_operations sbpcd_bdops = -{ - .owner = THIS_MODULE, - .open = sbpcd_block_open, - .release = sbpcd_block_release, - .ioctl = sbpcd_block_ioctl, - .media_changed = sbpcd_block_media_changed, -}; -/*==========================================================================*/ -/* - * Open the device special file. Check that a disk is in. Read TOC. - */ -static int sbpcd_open(struct cdrom_device_info *cdi, int purpose) -{ - struct sbpcd_drive *p = cdi->handle; - - down(&ioctl_read_sem); - switch_drive(p); - - /* - * try to keep an "open" counter here and lock the door if 0->1. - */ - msg(DBG_LCK,"open_count: %d -> %d\n", - current_drive->open_count,current_drive->open_count+1); - if (++current_drive->open_count<=1) - { - int i; - i=LockDoor(); - current_drive->open_count=1; - if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n"); - i=DiskInfo(); - if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n"); - if ((current_drive->ored_ctl_adr&0x40)==0) - { - msg(DBG_INF,"CD contains no data tracks.\n"); -#ifdef SAFE_MIXED - current_drive->has_data=0; -#endif /* SAFE_MIXED */ - } -#ifdef SAFE_MIXED - else if (current_drive->has_data<1) current_drive->has_data=1; -#endif /* SAFE_MIXED */ - } - if (!st_spinning) cc_SpinUp(); - RETURN_UP(0); -} -/*==========================================================================*/ -/* - * On close, we flush all sbp blocks from the buffer cache. - */ -static void sbpcd_release(struct cdrom_device_info * cdi) -{ - struct sbpcd_drive *p = cdi->handle; - - if (p->drv_id==-1) { - msg(DBG_INF, "release: bad device: %s\n", cdi->name); - return; - } - down(&ioctl_read_sem); - switch_drive(p); - /* - * try to keep an "open" counter here and unlock the door if 1->0. - */ - msg(DBG_LCK,"open_count: %d -> %d\n", - p->open_count,p->open_count-1); - if (p->open_count>-2) /* CDROMEJECT may have been done */ - { - if (--p->open_count<=0) - { - p->sbp_first_frame=p->sbp_last_frame=-1; - if (p->audio_state!=audio_playing) - if (p->f_eject) cc_SpinDown(); - p->diskstate_flags &= ~cd_size_bit; - p->open_count=0; -#ifdef SAFE_MIXED - p->has_data=0; -#endif /* SAFE_MIXED */ - } - } - up(&ioctl_read_sem); - return ; -} -/*==========================================================================*/ -/* - * - */ -static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr); -static struct cdrom_device_ops sbpcd_dops = { - .open = sbpcd_open, - .release = sbpcd_release, - .drive_status = sbpcd_drive_status, - .media_changed = sbpcd_media_changed, - .tray_move = sbpcd_tray_move, - .lock_door = sbpcd_lock_door, - .select_speed = sbpcd_select_speed, - .get_last_session = sbpcd_get_last_session, - .get_mcn = sbpcd_get_mcn, - .reset = sbpcd_reset, - .audio_ioctl = sbpcd_audio_ioctl, - .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | - CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | - CDC_MCN | CDC_PLAY_AUDIO, - .n_minors = 1, -}; - -/*==========================================================================*/ -/* - * accept "kernel command line" parameters - * (suggested by Peter MacDonald with SLS 1.03) - * - * This is only implemented for the first controller. Should be enough to - * allow installing with a "strange" distribution kernel. - * - * use: tell LILO: - * sbpcd=0x230,SoundBlaster - * or - * sbpcd=0x300,LaserMate - * or - * sbpcd=0x338,SoundScape - * or - * sbpcd=0x2C0,Teac16bit - * - * (upper/lower case sensitive here - but all-lowercase is ok!!!). - * - * the address value has to be the CDROM PORT ADDRESS - - * not the soundcard base address. - * For the SPEA/SoundScape setup, DO NOT specify the "configuration port" - * address, but the address which is really used for the CDROM (usually 8 - * bytes above). - * - */ - -int sbpcd_setup(char *s) -{ -#ifndef MODULE - int p[4]; - (void)get_options(s, ARRAY_SIZE(p), p); - setup_done++; - msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s); - sbpro_type=0; /* default: "LaserMate" */ - if (p[0]>1) sbpro_type=p[2]; - else if (!strcmp(s,str_sb)) sbpro_type=1; - else if (!strcmp(s,str_sb_l)) sbpro_type=1; - else if (!strcmp(s,str_sp)) sbpro_type=2; - else if (!strcmp(s,str_sp_l)) sbpro_type=2; - else if (!strcmp(s,str_ss)) sbpro_type=2; - else if (!strcmp(s,str_ss_l)) sbpro_type=2; - else if (!strcmp(s,str_t16)) sbpro_type=3; - else if (!strcmp(s,str_t16_l)) sbpro_type=3; - if (p[0]>0) sbpcd_ioaddr=p[1]; - if (p[0]>2) max_drives=p[3]; -#else - sbpcd_ioaddr = sbpcd[0]; - sbpro_type = sbpcd[1]; -#endif - - CDo_command=sbpcd_ioaddr; - CDi_info=sbpcd_ioaddr; - CDi_status=sbpcd_ioaddr+1; - CDo_sel_i_d=sbpcd_ioaddr+1; - CDo_reset=sbpcd_ioaddr+2; - CDo_enable=sbpcd_ioaddr+3; - f_16bit=0; - if ((sbpro_type==1)||(sbpro_type==3)) - { - CDi_data=sbpcd_ioaddr; - if (sbpro_type==3) - { - f_16bit=1; - sbpro_type=1; - } - } - else CDi_data=sbpcd_ioaddr+2; - - return 1; -} - -__setup("sbpcd=", sbpcd_setup); - - -/*==========================================================================*/ -/* - * Sequoia S-1000 CD-ROM Interface Configuration - * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards - * The soundcard has to get jumpered for the interface type "Panasonic" - * (not Sony or Mitsumi) and to get soft-configured for - * -> configuration port address - * -> CDROM port offset (num_ports): has to be 8 here. Possibly this - * offset value determines the interface type (none, Panasonic, - * Mitsumi, Sony). - * The interface uses a configuration port (0x320, 0x330, 0x340, 0x350) - * some bytes below the real CDROM address. - * - * For the Panasonic style (LaserMate) interface and the configuration - * port 0x330, we have to use an offset of 8; so, the real CDROM port - * address is 0x338. - */ -static int __init config_spea(void) -{ - /* - * base address offset between configuration port and CDROM port, - * this probably defines the interface type - * 2 (type=??): 0x00 - * 8 (type=LaserMate):0x10 - * 16 (type=??):0x20 - * 32 (type=??):0x30 - */ - int n_ports=0x10; - - int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */ - int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */ - int dack_polarity=0; /* L:0x00, H:0x80 */ - int drq_polarity=0x40; /* L:0x00, H:0x40 */ - int i; - -#define SPEA_REG_1 sbpcd_ioaddr-0x08+4 -#define SPEA_REG_2 sbpcd_ioaddr-0x08+5 - - OUT(SPEA_REG_1,0xFF); - i=inb(SPEA_REG_1); - if (i!=0x0F) - { - msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr); - return (-1); /* no interface found */ - } - OUT(SPEA_REG_1,0x04); - OUT(SPEA_REG_2,0xC0); - - OUT(SPEA_REG_1,0x05); - OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity); - -#if 1 -#define SPEA_PATTERN 0x80 -#else -#define SPEA_PATTERN 0x00 -#endif - OUT(SPEA_REG_1,0x06); - OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN); - OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN); - - OUT(SPEA_REG_1,0x09); - i=(inb(SPEA_REG_2)&0xCF)|n_ports; - OUT(SPEA_REG_2,i); - - sbpro_type = 0; /* acts like a LaserMate interface now */ - msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr); - return (0); -} - -/*==========================================================================*/ -/* - * Test for presence of drive and initialize it. - * Called once at boot or load time. - */ - -/* FIXME: cleanups after failed allocations are too ugly for words */ -#ifdef MODULE -int __init __sbpcd_init(void) -#else -int __init sbpcd_init(void) -#endif -{ - int i=0, j=0; - int addr[2]={1, CDROM_PORT}; - int port_index; - - sti(); - - msg(DBG_INF,"sbpcd.c %s\n", VERSION); -#ifndef MODULE -#if DISTRIBUTION - if (!setup_done) - { - msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n"); - msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n"); - msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n"); - msg(DBG_INF,"If that happens, you have to reboot and use the\n"); - msg(DBG_INF,"LILO (kernel) command line feature like:\n"); - msg(DBG_INF," LILO boot: ... sbpcd=0x230,SoundBlaster\n"); - msg(DBG_INF,"or like:\n"); - msg(DBG_INF," LILO boot: ... sbpcd=0x300,LaserMate\n"); - msg(DBG_INF,"or like:\n"); - msg(DBG_INF," LILO boot: ... sbpcd=0x338,SoundScape\n"); - msg(DBG_INF,"with your REAL address.\n"); - msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n"); - } -#endif /* DISTRIBUTION */ - sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */ - sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */ -#endif /* MODULE */ - - for (port_index=0;port_index=0) break; /* drive found */ - } /* end of cycling through the set of possible I/O port addresses */ - - if (ndrives==0) - { - msg(DBG_INF, "No drive found.\n"); -#ifdef MODULE - return -EIO; -#else - goto init_done; -#endif /* MODULE */ - } - - if (port_index>0) - { - msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n"); - msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n"); - } - check_datarate(); - msg(DBG_INI,"check_datarate done.\n"); - - for (j=0;jdrv_id==-1) - continue; - switch_drive(p); -#if 1 - if (!famL_drive) cc_DriveReset(); -#endif - if (!st_spinning) cc_SpinUp(); - p->sbp_first_frame = -1; /* First frame in buffer */ - p->sbp_last_frame = -1; /* Last frame in buffer */ - p->sbp_read_frames = 0; /* Number of frames being read to buffer */ - p->sbp_current = 0; /* Frame being currently read */ - p->CD_changed=1; - p->frame_size=CD_FRAMESIZE; - p->f_eject=0; -#if EJECT - if (!fam0_drive) p->f_eject=1; -#endif /* EJECT */ - cc_ReadStatus(); - i=ResponseStatus(); /* returns orig. status or p_busy_new */ - if (famT_drive) i=ResponseStatus(); /* returns orig. status or p_busy_new */ - if (i<0) - { - if (i!=-402) - msg(DBG_INF,"init: ResponseStatus returns %d.\n",i); - } - else - { - if (st_check) - { - i=cc_ReadError(); - msg(DBG_INI,"init: cc_ReadError returns %d\n",i); - } - } - msg(DBG_INI,"init: first GetStatus: %d\n",i); - msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n", - p->error_byte); - if (p->error_byte==aud_12) - { - timeout=jiffies+2*HZ; - do - { - i=GetStatus(); - msg(DBG_INI,"init: second GetStatus: %02X\n",i); - msg(DBG_LCS, - "init: second GetStatus: error_byte=%d\n", - p->error_byte); - if (i<0) break; - if (!st_caddy_in) break; - } - while ((!st_diskok)||time_after(jiffies, timeout)); - } - i=SetSpeed(); - if (i>=0) p->CD_changed=1; - } - - if (!request_region(CDo_command,4,major_name)) - { - printk(KERN_WARNING "sbpcd: Unable to request region 0x%x\n", CDo_command); - return -EIO; - } - - /* - * Turn on the CD audio channels. - * The addresses are obtained from SOUND_BASE (see sbpcd.h). - */ -#if SOUND_BASE - OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */ - OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */ -#endif /* SOUND_BASE */ - - if (register_blkdev(MAJOR_NR, major_name)) { -#ifdef MODULE - return -EIO; -#else - goto init_done; -#endif /* MODULE */ - } - - /* - * init error handling is broken beyond belief in this driver... - */ - sbpcd_queue = blk_init_queue(do_sbpcd_request, &sbpcd_lock); - if (!sbpcd_queue) { - release_region(CDo_command,4); - unregister_blkdev(MAJOR_NR, major_name); - return -ENOMEM; - } - - for (j=0;jdrv_id==-1) continue; - switch_drive(p); -#ifdef SAFE_MIXED - p->has_data=0; -#endif /* SAFE_MIXED */ - /* - * allocate memory for the frame buffers - */ - p->aud_buf=NULL; - p->sbp_audsiz=0; - p->sbp_bufsiz=buffers; - if (p->drv_type&drv_fam1) - if (READ_AUDIO>0) - p->sbp_audsiz = READ_AUDIO; - p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE); - if (!p->sbp_buf) { - msg(DBG_INF,"data buffer (%d frames) not available.\n", - buffers); - if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL)) - { - printk("Can't unregister %s\n", major_name); - } - release_region(CDo_command,4); - blk_cleanup_queue(sbpcd_queue); - return -EIO; - } -#ifdef MODULE - msg(DBG_INF,"data buffer size: %d frames.\n",buffers); -#endif /* MODULE */ - if (p->sbp_audsiz>0) - { - p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW); - if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz); - else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz); - } - sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info)); - if (sbpcd_infop == NULL) - { - release_region(CDo_command,4); - blk_cleanup_queue(sbpcd_queue); - return -ENOMEM; - } - memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info)); - sbpcd_infop->ops = &sbpcd_dops; - sbpcd_infop->speed = 2; - sbpcd_infop->capacity = 1; - sprintf(sbpcd_infop->name, "sbpcd%d", j); - sbpcd_infop->handle = p; - p->sbpcd_infop = sbpcd_infop; - disk = alloc_disk(1); - disk->major = MAJOR_NR; - disk->first_minor = j; - disk->fops = &sbpcd_bdops; - strcpy(disk->disk_name, sbpcd_infop->name); - disk->flags = GENHD_FL_CD; - p->disk = disk; - if (register_cdrom(sbpcd_infop)) - { - printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n"); - } - disk->private_data = p; - disk->queue = sbpcd_queue; - add_disk(disk); - } - blk_queue_hardsect_size(sbpcd_queue, CD_FRAMESIZE); - -#ifndef MODULE - init_done: -#endif - return 0; -} -/*==========================================================================*/ -#ifdef MODULE -static void sbpcd_exit(void) -{ - int j; - - if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL)) - { - msg(DBG_INF, "What's that: can't unregister %s.\n", major_name); - return; - } - release_region(CDo_command,4); - blk_cleanup_queue(sbpcd_queue); - for (j=0;j0) - vfree(D_S[j].aud_buf); - if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL)) - { - msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name); - return; - } - vfree(D_S[j].sbpcd_infop); - } - msg(DBG_INF, "%s module released.\n", major_name); -} - - -module_init(__sbpcd_init) /*HACK!*/; -module_exit(sbpcd_exit); - - -#endif /* MODULE */ -static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr) -{ - struct sbpcd_drive *p = cdi->handle; - msg(DBG_CHK,"media_check (%s) called\n", cdi->name); - - if (p->CD_changed==0xFF) - { - p->CD_changed=0; - msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name); - current_drive->diskstate_flags &= ~toc_bit; - /* we *don't* need invalidate here, it's done by caller */ - current_drive->diskstate_flags &= ~cd_size_bit; -#ifdef SAFE_MIXED - current_drive->has_data=0; -#endif /* SAFE_MIXED */ - - return (1); - } - else - return (0); -} - -MODULE_LICENSE("GPL"); -/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but - AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */ -MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR); - -/*==========================================================================*/ -/* - * 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-indent-level: 8 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -8 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * End: - */ - diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h deleted file mode 100644 index 2f2225f13c6f..000000000000 --- a/drivers/cdrom/sbpcd.h +++ /dev/null @@ -1,839 +0,0 @@ -/* - * sbpcd.h Specify interface address and interface type here. - */ - -/* - * Attention! This file contains user-serviceable parts! - * I recommend to make use of it... - * If you feel helpless, look into Documentation/cdrom/sbpcd - * (good idea anyway, at least before mailing me). - * - * The definitions for the first controller can get overridden by - * the kernel command line ("lilo boot option"). - * Examples: - * sbpcd=0x300,LaserMate - * or - * sbpcd=0x230,SoundBlaster - * or - * sbpcd=0x338,SoundScape - * or - * sbpcd=0x2C0,Teac16bit - * - * If sbpcd gets used as a module, you can load it with - * insmod sbpcd.o sbpcd=0x300,0 - * or - * insmod sbpcd.o sbpcd=0x230,1 - * or - * insmod sbpcd.o sbpcd=0x338,2 - * or - * insmod sbpcd.o sbpcd=0x2C0,3 - * respective to override the configured address and type. - */ - -/* - * define your CDROM port base address as CDROM_PORT - * and specify the type of your interface card as SBPRO. - * - * address: - * ======== - * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ... - * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ... - * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to - * specify the REAL address here, not the configuration port address. Look - * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let - * sbpcd auto-probe, if you are not firm with the address. - * There are some soundcards on the market with 0x0630, 0x0650, ...; their - * type is not obvious (both types are possible). - * - * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1. - * if your soundcard has its CDROM port above 0x300, specify - * that address and try SBPRO 0 first. - * if your SoundScape configuration port is at 0x330, specify - * 0x338 and SBPRO 2. - * - * interface type: - * =============== - * set SBPRO to 1 for "true" SoundBlaster card - * set SBPRO to 0 for "compatible" soundcards and - * for "poor" (no sound) interface cards. - * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards - * set SBPRO to 3 for Teac 16bit interface cards - * - * Almost all "compatible" sound boards need to set SBPRO to 0. - * If SBPRO is set wrong, the drives will get found - but any - * data access will give errors (audio access will work). - * The "OmniCD" no-sound interface card from CreativeLabs and most Teac - * interface cards need SBPRO 1. - * - * sound base: - * =========== - * The SOUND_BASE definition tells if we should try to turn the CD sound - * channels on. It will only be of use regarding soundcards with a SbPro - * compatible mixer. - * - * Example: #define SOUND_BASE 0x220 enables the sound card's CD channels - * #define SOUND_BASE 0 leaves the soundcard untouched - */ -#define CDROM_PORT 0x340 /* <-----------<< port address */ -#define SBPRO 0 /* <-----------<< interface type */ -#define MAX_DRIVES 4 /* set to 1 if the card does not use "drive select" */ -#define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0 */ - -/* - * some more or less user dependent definitions - service them! - */ - -/* Set this to 0 once you have configured your interface definitions right. */ -#define DISTRIBUTION 1 - -/* - * Time to wait after giving a message. - * This gets important if you enable non-standard DBG_xxx flags. - * You will see what happens if you omit the pause or make it - * too short. Be warned! - */ -#define KLOGD_PAUSE 1 - -/* tray control: eject tray if no disk is in */ -#if DISTRIBUTION -#define JUKEBOX 0 -#else -#define JUKEBOX 1 -#endif /* DISTRIBUTION */ - -/* tray control: eject tray after last use */ -#if DISTRIBUTION -#define EJECT 0 -#else -#define EJECT 1 -#endif /* DISTRIBUTION */ - -/* max. number of audio frames to read with one */ -/* request (allocates n* 2352 bytes kernel memory!) */ -/* may be freely adjusted, f.e. 75 (= 1 sec.), at */ -/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */ -#define READ_AUDIO 0 - -/* Optimizations for the Teac CD-55A drive read performance. - * SBP_TEAC_SPEED can be changed here, or one can set the - * variable "teac" when loading as a module. - * Valid settings are: - * 0 - very slow - the recommended "DISTRIBUTION 1" setup. - * 1 - 2x performance with little overhead. No busy waiting. - * 2 - 4x performance with 5ms overhead per read. Busy wait. - * - * Setting SBP_TEAC_SPEED or the variable 'teac' to anything - * other than 0 may cause problems. If you run into them, first - * change SBP_TEAC_SPEED back to 0 and see if your drive responds - * normally. If yes, you are "allowed" to report your case - to help - * me with the driver, not to solve your hassle. Don´t mail if you - * simply are stuck into your own "tuning" experiments, you know? - */ -#define SBP_TEAC_SPEED 1 - -/*==========================================================================*/ -/*==========================================================================*/ -/* - * nothing to change below here if you are not fully aware what you're doing - */ -#ifndef _LINUX_SBPCD_H - -#define _LINUX_SBPCD_H -/*==========================================================================*/ -/*==========================================================================*/ -/* - * driver's own read_ahead, data mode - */ -#define SBP_BUFFER_FRAMES 8 - -#define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */ -#undef FUTURE -#undef SAFE_MIXED - -#define TEST_UPC 0 -#define SPEA_TEST 0 -#define TEST_STI 0 -#define OLD_BUSY 0 -#undef PATH_CHECK -#ifndef SOUND_BASE -#define SOUND_BASE 0 -#endif -#if DISTRIBUTION -#undef SBP_TEAC_SPEED -#define SBP_TEAC_SPEED 0 -#endif -/*==========================================================================*/ -/* - * DDI interface definitions - * "invented" by Fred N. van Kempen.. - */ -#define DDIOCSDBG 0x9000 - -/*==========================================================================*/ -/* - * "private" IOCTL functions - */ -#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */ - -/*==========================================================================*/ -/* - * Debug output levels - */ -#define DBG_INF 1 /* necessary information */ -#define DBG_BSZ 2 /* BLOCK_SIZE trace */ -#define DBG_REA 3 /* READ status trace */ -#define DBG_CHK 4 /* MEDIA CHECK trace */ -#define DBG_TIM 5 /* datarate timer test */ -#define DBG_INI 6 /* initialization trace */ -#define DBG_TOC 7 /* tell TocEntry values */ -#define DBG_IOC 8 /* ioctl trace */ -#define DBG_STA 9 /* ResponseStatus() trace */ -#define DBG_ERR 10 /* cc_ReadError() trace */ -#define DBG_CMD 11 /* cmd_out() trace */ -#define DBG_WRN 12 /* give explanation before auto-probing */ -#define DBG_MUL 13 /* multi session code test */ -#define DBG_IDX 14 /* test code for drive_id !=0 */ -#define DBG_IOX 15 /* some special information */ -#define DBG_DID 16 /* drive ID test */ -#define DBG_RES 17 /* drive reset info */ -#define DBG_SPI 18 /* SpinUp test */ -#define DBG_IOS 19 /* ioctl trace: subchannel functions */ -#define DBG_IO2 20 /* ioctl trace: general */ -#define DBG_UPC 21 /* show UPC information */ -#define DBG_XA1 22 /* XA mode debugging */ -#define DBG_LCK 23 /* door (un)lock info */ -#define DBG_SQ1 24 /* dump SubQ frame */ -#define DBG_AUD 25 /* READ AUDIO debugging */ -#define DBG_SEQ 26 /* Sequoia interface configuration trace */ -#define DBG_LCS 27 /* Longshine LCS-7260 debugging trace */ -#define DBG_CD2 28 /* MKE/Funai CD200 debugging trace */ -#define DBG_TEA 29 /* TEAC CD-55A debugging trace */ -#define DBG_ECS 30 /* ECS-AT (Vertos 100) debugging trace */ -#define DBG_000 31 /* unnecessary information */ - -/*==========================================================================*/ -/*==========================================================================*/ - -/* - * bits of flags_cmd_out: - */ -#define f_respo3 0x100 -#define f_putcmd 0x80 -#define f_respo2 0x40 -#define f_lopsta 0x20 -#define f_getsta 0x10 -#define f_ResponseStatus 0x08 -#define f_obey_p_check 0x04 -#define f_bit1 0x02 -#define f_wait_if_busy 0x01 - -/* - * diskstate_flags: - */ -#define x80_bit 0x80 -#define upc_bit 0x40 -#define volume_bit 0x20 -#define toc_bit 0x10 -#define multisession_bit 0x08 -#define cd_size_bit 0x04 -#define subq_bit 0x02 -#define frame_size_bit 0x01 - -/* - * disk states (bits of diskstate_flags): - */ -#define upc_valid (current_drive->diskstate_flags&upc_bit) -#define volume_valid (current_drive->diskstate_flags&volume_bit) -#define toc_valid (current_drive->diskstate_flags&toc_bit) -#define cd_size_valid (current_drive->diskstate_flags&cd_size_bit) -#define subq_valid (current_drive->diskstate_flags&subq_bit) -#define frame_size_valid (current_drive->diskstate_flags&frame_size_bit) - -/* - * the status_bits variable - */ -#define p_success 0x100 -#define p_door_closed 0x80 -#define p_caddy_in 0x40 -#define p_spinning 0x20 -#define p_check 0x10 -#define p_busy_new 0x08 -#define p_door_locked 0x04 -#define p_disk_ok 0x01 - -/* - * LCS-7260 special status result bits: - */ -#define p_lcs_door_locked 0x02 -#define p_lcs_door_closed 0x01 /* probably disk_in */ - -/* - * CR-52x special status result bits: - */ -#define p_caddin_old 0x40 -#define p_success_old 0x08 -#define p_busy_old 0x04 -#define p_bit_1 0x02 /* hopefully unused now */ - -/* - * "generation specific" defs of the status result bits: - */ -#define p0_door_closed 0x80 -#define p0_caddy_in 0x40 -#define p0_spinning 0x20 -#define p0_check 0x10 -#define p0_success 0x08 /* unused */ -#define p0_busy 0x04 -#define p0_bit_1 0x02 /* unused */ -#define p0_disk_ok 0x01 - -#define pL_disk_in 0x40 -#define pL_spinning 0x20 -#define pL_check 0x10 -#define pL_success 0x08 /* unused ?? */ -#define pL_busy 0x04 -#define pL_door_locked 0x02 -#define pL_door_closed 0x01 - -#define pV_door_closed 0x40 -#define pV_spinning 0x20 -#define pV_check 0x10 -#define pV_success 0x08 -#define pV_busy 0x04 -#define pV_door_locked 0x02 -#define pV_disk_ok 0x01 - -#define p1_door_closed 0x80 -#define p1_disk_in 0x40 -#define p1_spinning 0x20 -#define p1_check 0x10 -#define p1_busy 0x08 -#define p1_door_locked 0x04 -#define p1_bit_1 0x02 /* unused */ -#define p1_disk_ok 0x01 - -#define p2_disk_ok 0x80 -#define p2_door_locked 0x40 -#define p2_spinning 0x20 -#define p2_busy2 0x10 -#define p2_busy1 0x08 -#define p2_door_closed 0x04 -#define p2_disk_in 0x02 -#define p2_check 0x01 - -/* - * used drive states: - */ -#define st_door_closed (current_drive->status_bits&p_door_closed) -#define st_caddy_in (current_drive->status_bits&p_caddy_in) -#define st_spinning (current_drive->status_bits&p_spinning) -#define st_check (current_drive->status_bits&p_check) -#define st_busy (current_drive->status_bits&p_busy_new) -#define st_door_locked (current_drive->status_bits&p_door_locked) -#define st_diskok (current_drive->status_bits&p_disk_ok) - -/* - * bits of the CDi_status register: - */ -#define s_not_result_ready 0x04 /* 0: "result ready" */ -#define s_not_data_ready 0x02 /* 0: "data ready" */ -#define s_attention 0x01 /* 1: "attention required" */ -/* - * usable as: - */ -#define DRV_ATTN ((inb(CDi_status)&s_attention)!=0) -#define DATA_READY ((inb(CDi_status)&s_not_data_ready)==0) -#define RESULT_READY ((inb(CDi_status)&s_not_result_ready)==0) - -/* - * drive families and types (firmware versions): - */ -#define drv_fam0 0x0100 /* CR-52x family */ -#define drv_199 (drv_fam0+0x01) /* <200 */ -#define drv_200 (drv_fam0+0x02) /* <201 */ -#define drv_201 (drv_fam0+0x03) /* <210 */ -#define drv_210 (drv_fam0+0x04) /* <211 */ -#define drv_211 (drv_fam0+0x05) /* <300 */ -#define drv_300 (drv_fam0+0x06) /* >=300 */ - -#define drv_fam1 0x0200 /* CR-56x family */ -#define drv_099 (drv_fam1+0x01) /* <100 */ -#define drv_100 (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */ - -#define drv_fam2 0x0400 /* CD200 family */ - -#define drv_famT 0x0800 /* TEAC CD-55A */ - -#define drv_famL 0x1000 /* Longshine family */ -#define drv_260 (drv_famL+0x01) /* LCS-7260 */ -#define drv_e1 (drv_famL+0x01) /* LCS-7260, firmware "A E1" */ -#define drv_f4 (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */ - -#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */ -#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */ - -#define fam0_drive (current_drive->drv_type&drv_fam0) -#define famL_drive (current_drive->drv_type&drv_famL) -#define famV_drive (current_drive->drv_type&drv_famV) -#define fam1_drive (current_drive->drv_type&drv_fam1) -#define fam2_drive (current_drive->drv_type&drv_fam2) -#define famT_drive (current_drive->drv_type&drv_famT) -#define fam0L_drive (current_drive->drv_type&(drv_fam0|drv_famL)) -#define fam0V_drive (current_drive->drv_type&(drv_fam0|drv_famV)) -#define famLV_drive (current_drive->drv_type&(drv_famL|drv_famV)) -#define fam0LV_drive (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV)) -#define fam1L_drive (current_drive->drv_type&(drv_fam1|drv_famL)) -#define fam1V_drive (current_drive->drv_type&(drv_fam1|drv_famV)) -#define fam1LV_drive (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV)) -#define fam01_drive (current_drive->drv_type&(drv_fam0|drv_fam1)) -#define fam12_drive (current_drive->drv_type&(drv_fam1|drv_fam2)) -#define fam2T_drive (current_drive->drv_type&(drv_fam2|drv_famT)) - -/* - * audio states: - */ -#define audio_completed 3 /* Forgot this one! --AJK */ -#define audio_playing 2 -#define audio_pausing 1 - -/* - * drv_pattern, drv_options: - */ -#define speed_auto 0x80 -#define speed_300 0x40 -#define speed_150 0x20 -#define audio_mono 0x04 - -/* - * values of cmd_type (0 else): - */ -#define READ_M1 0x01 /* "data mode 1": 2048 bytes per frame */ -#define READ_M2 0x02 /* "data mode 2": 12+2048+280 bytes per frame */ -#define READ_SC 0x04 /* "subchannel info": 96 bytes per frame */ -#define READ_AU 0x08 /* "audio frame": 2352 bytes per frame */ - -/* - * sense_byte: - * - * values: 00 - * 01 - * 81 - * 82 "raw audio" mode - * xx from infobuf[0] after 85 00 00 00 00 00 00 - */ - -/* audio status (bin) */ -#define aud_00 0x00 /* Audio status byte not supported or not valid */ -#define audx11 0x0b /* Audio play operation in progress */ -#define audx12 0x0c /* Audio play operation paused */ -#define audx13 0x0d /* Audio play operation successfully completed */ -#define audx14 0x0e /* Audio play operation stopped due to error */ -#define audx15 0x0f /* No current audio status to return */ -/* audio status (bcd) */ -#define aud_11 0x11 /* Audio play operation in progress */ -#define aud_12 0x12 /* Audio play operation paused */ -#define aud_13 0x13 /* Audio play operation successfully completed */ -#define aud_14 0x14 /* Audio play operation stopped due to error */ -#define aud_15 0x15 /* No current audio status to return */ - -/* - * highest allowed drive number (MINOR+1) - */ -#define NR_SBPCD 4 - -/* - * we try to never disable interrupts - seems to work - */ -#define SBPCD_DIS_IRQ 0 - -/* - * "write byte to port" - */ -#define OUT(x,y) outb(y,x) - -/*==========================================================================*/ - -#define MIXER_addr SOUND_BASE+4 /* sound card's address register */ -#define MIXER_data SOUND_BASE+5 /* sound card's data register */ -#define MIXER_CD_Volume 0x28 /* internal SB Pro register address */ - -/*==========================================================================*/ - -#define MAX_TRACKS 99 - -#define ERR_DISKCHANGE 615 - -/*==========================================================================*/ -/* - * To make conversions easier (machine dependent!) - */ -typedef union _msf -{ - u_int n; - u_char c[4]; -} MSF; - -typedef union _blk -{ - u_int n; - u_char c[4]; -} BLK; - -/*==========================================================================*/ - -/*============================================================================ -============================================================================== - -COMMAND SET of "old" drives like CR-521, CR-522 - (the CR-562 family is different): - -No. Command Code --------------------------------------------- - -Drive Commands: - 1 Seek 01 - 2 Read Data 02 - 3 Read XA-Data 03 - 4 Read Header 04 - 5 Spin Up 05 - 6 Spin Down 06 - 7 Diagnostic 07 - 8 Read UPC 08 - 9 Read ISRC 09 -10 Play Audio 0A -11 Play Audio MSF 0B -12 Play Audio Track/Index 0C - -Status Commands: -13 Read Status 81 -14 Read Error 82 -15 Read Drive Version 83 -16 Mode Select 84 -17 Mode Sense 85 -18 Set XA Parameter 86 -19 Read XA Parameter 87 -20 Read Capacity 88 -21 Read SUB_Q 89 -22 Read Disc Code 8A -23 Read Disc Information 8B -24 Read TOC 8C -25 Pause/Resume 8D -26 Read Packet 8E -27 Read Path Check 00 - - -all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first - -mnemo 7-byte command #bytes response (r0...rn) -________ ____________________ ____ - -Read Status: -status: 81. (1) one-byte command, gives the main - status byte -Read Error: -check1: 82 00 00 00 00 00 00. (6) r1: audio status - -Read Packet: -check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating - to commands 01 04 05 07 08 09 - -Play Audio: -play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba), - nn-nn-nn: #blocks -Play Audio MSF: - 0b mm-ss-ff mm-ss-ff (0) play audio from/to - -Play Audio Track/Index: - 0c ... - -Pause/Resume: -pause: 8d pr 00 00 00 00 00. (0) pause (pr=00) - resume (pr=80) audio playing - -Mode Select: - 84 00 nn-nn ??.?? 00 (0) nn-nn: 2048 or 2340 - possibly defines transfer size - -set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1) - le(vel): min=0, max=FF, else half - (firmware 2.11) - -Mode Sense: -get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting - -Read Disc Information: -tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format) - -Read TOC: -tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn - (fl=0:"lba"-, =2:"msf-bin"-format) - -Read Capacity: -capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity" - - -Read Path Check: -ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55 - ("ping" if the drive is connected) - -Read Drive Version: -ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn" - (n.nn = 2.01, 2.11., 3.00, ...) - -Seek: -seek: 01 00 ll-bb-aa 00 00. (0) -seek: 01 02 mm-ss-ff 00 00. (0) - -Read Data: -read: 02 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2048 bytes, - starting at block xx-xx-xx - fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx - -Read XA-Data: -read: 03 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2340 bytes, - starting at block xx-xx-xx - fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx - -Read SUB_Q: - 89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf, - fl=0: "lba", fl=2: "msf" - -Read Disc Code: - 8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info - -Read Header: - 04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2" - 04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2" - -Spin Up: - 05 00 ll-bb-aa 00 00. (0) possibly implies a "seek" - -Spin Down: - 06 ... - -Diagnostic: - 07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2" - 07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2" - -Read UPC: - 08 00 ll-bb-aa 00 00. (16) - 08 02 mm-ss-ff 00 00. (16) - -Read ISRC: - 09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2" - 09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2" - -Set XA Parameter: - 86 ... - -Read XA Parameter: - 87 ... - -============================================================================== -============================================================================*/ - -/* - * commands - * - * CR-52x: CMD0_ - * CR-56x: CMD1_ - * CD200: CMD2_ - * LCS-7260: CMDL_ - * TEAC CD-55A: CMDT_ - * ECS-AT: CMDV_ - */ -#define CMD1_RESET 0x0a -#define CMD2_RESET 0x01 -#define CMDT_RESET 0xc0 - -#define CMD1_LOCK_CTL 0x0c -#define CMD2_LOCK_CTL 0x1e -#define CMDT_LOCK_CTL CMD2_LOCK_CTL -#define CMDL_LOCK_CTL 0x0e -#define CMDV_LOCK_CTL CMDL_LOCK_CTL - -#define CMD1_TRAY_CTL 0x07 -#define CMD2_TRAY_CTL 0x1b -#define CMDT_TRAY_CTL CMD2_TRAY_CTL -#define CMDL_TRAY_CTL 0x0d -#define CMDV_TRAY_CTL CMDL_TRAY_CTL - -#define CMD1_MULTISESS 0x8d -#define CMDL_MULTISESS 0x8c -#define CMDV_MULTISESS CMDL_MULTISESS - -#define CMD1_SUBCHANINF 0x11 -#define CMD2_SUBCHANINF 0x?? - -#define CMD1_ABORT 0x08 -#define CMD2_ABORT 0x08 -#define CMDT_ABORT 0x08 - -#define CMD2_x02 0x02 - -#define CMD2_SETSPEED 0xda - -#define CMD0_PATH_CHECK 0x00 -#define CMD1_PATH_CHECK 0x??? -#define CMD2_PATH_CHECK 0x??? -#define CMDT_PATH_CHECK 0x??? -#define CMDL_PATH_CHECK CMD0_PATH_CHECK -#define CMDV_PATH_CHECK CMD0_PATH_CHECK - -#define CMD0_SEEK 0x01 -#define CMD1_SEEK CMD0_SEEK -#define CMD2_SEEK 0x2b -#define CMDT_SEEK CMD2_SEEK -#define CMDL_SEEK CMD0_SEEK -#define CMDV_SEEK CMD0_SEEK - -#define CMD0_READ 0x02 -#define CMD1_READ 0x10 -#define CMD2_READ 0x28 -#define CMDT_READ CMD2_READ -#define CMDL_READ CMD0_READ -#define CMDV_READ CMD0_READ - -#define CMD0_READ_XA 0x03 -#define CMD2_READ_XA 0xd4 -#define CMD2_READ_XA2 0xd5 -#define CMDL_READ_XA CMD0_READ_XA /* really ?? */ -#define CMDV_READ_XA CMD0_READ_XA - -#define CMD0_READ_HEAD 0x04 - -#define CMD0_SPINUP 0x05 -#define CMD1_SPINUP 0x02 -#define CMD2_SPINUP CMD2_TRAY_CTL -#define CMDL_SPINUP CMD0_SPINUP -#define CMDV_SPINUP CMD0_SPINUP - -#define CMD0_SPINDOWN 0x06 /* really??? */ -#define CMD1_SPINDOWN 0x06 -#define CMD2_SPINDOWN CMD2_TRAY_CTL -#define CMDL_SPINDOWN 0x0d -#define CMDV_SPINDOWN CMD0_SPINDOWN - -#define CMD0_DIAG 0x07 - -#define CMD0_READ_UPC 0x08 -#define CMD1_READ_UPC 0x88 -#define CMD2_READ_UPC 0x??? -#define CMDL_READ_UPC CMD0_READ_UPC -#define CMDV_READ_UPC 0x8f - -#define CMD0_READ_ISRC 0x09 - -#define CMD0_PLAY 0x0a -#define CMD1_PLAY 0x??? -#define CMD2_PLAY 0x??? -#define CMDL_PLAY CMD0_PLAY -#define CMDV_PLAY CMD0_PLAY - -#define CMD0_PLAY_MSF 0x0b -#define CMD1_PLAY_MSF 0x0e -#define CMD2_PLAY_MSF 0x47 -#define CMDT_PLAY_MSF CMD2_PLAY_MSF -#define CMDL_PLAY_MSF 0x??? - -#define CMD0_PLAY_TI 0x0c -#define CMD1_PLAY_TI 0x0f - -#define CMD0_STATUS 0x81 -#define CMD1_STATUS 0x05 -#define CMD2_STATUS 0x00 -#define CMDT_STATUS CMD2_STATUS -#define CMDL_STATUS CMD0_STATUS -#define CMDV_STATUS CMD0_STATUS -#define CMD2_SEEK_LEADIN 0x00 - -#define CMD0_READ_ERR 0x82 -#define CMD1_READ_ERR CMD0_READ_ERR -#define CMD2_READ_ERR 0x03 -#define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */ -#define CMDL_READ_ERR CMD0_READ_ERR -#define CMDV_READ_ERR CMD0_READ_ERR - -#define CMD0_READ_VER 0x83 -#define CMD1_READ_VER CMD0_READ_VER -#define CMD2_READ_VER 0x12 -#define CMDT_READ_VER CMD2_READ_VER /* really ?? */ -#define CMDL_READ_VER CMD0_READ_VER -#define CMDV_READ_VER CMD0_READ_VER - -#define CMD0_SETMODE 0x84 -#define CMD1_SETMODE 0x09 -#define CMD2_SETMODE 0x55 -#define CMDT_SETMODE CMD2_SETMODE -#define CMDL_SETMODE CMD0_SETMODE - -#define CMD0_GETMODE 0x85 -#define CMD1_GETMODE 0x84 -#define CMD2_GETMODE 0x5a -#define CMDT_GETMODE CMD2_GETMODE -#define CMDL_GETMODE CMD0_GETMODE - -#define CMD0_SET_XA 0x86 - -#define CMD0_GET_XA 0x87 - -#define CMD0_CAPACITY 0x88 -#define CMD1_CAPACITY 0x85 -#define CMD2_CAPACITY 0x25 -#define CMDL_CAPACITY CMD0_CAPACITY /* missing in some firmware versions */ - -#define CMD0_READSUBQ 0x89 -#define CMD1_READSUBQ 0x87 -#define CMD2_READSUBQ 0x42 -#define CMDT_READSUBQ CMD2_READSUBQ -#define CMDL_READSUBQ CMD0_READSUBQ -#define CMDV_READSUBQ CMD0_READSUBQ - -#define CMD0_DISKCODE 0x8a - -#define CMD0_DISKINFO 0x8b -#define CMD1_DISKINFO CMD0_DISKINFO -#define CMD2_DISKINFO 0x43 -#define CMDT_DISKINFO CMD2_DISKINFO -#define CMDL_DISKINFO CMD0_DISKINFO -#define CMDV_DISKINFO CMD0_DISKINFO - -#define CMD0_READTOC 0x8c -#define CMD1_READTOC CMD0_READTOC -#define CMD2_READTOC 0x??? -#define CMDL_READTOC CMD0_READTOC -#define CMDV_READTOC CMD0_READTOC - -#define CMD0_PAU_RES 0x8d -#define CMD1_PAU_RES 0x0d -#define CMD2_PAU_RES 0x4b -#define CMDT_PAUSE CMD2_PAU_RES -#define CMDL_PAU_RES CMD0_PAU_RES -#define CMDV_PAUSE CMD0_PAU_RES - -#define CMD0_PACKET 0x8e -#define CMD1_PACKET CMD0_PACKET -#define CMD2_PACKET 0x??? -#define CMDL_PACKET CMD0_PACKET -#define CMDV_PACKET 0x??? - -/*==========================================================================*/ -/*==========================================================================*/ -#endif /* _LINUX_SBPCD_H */ -/*==========================================================================*/ -/* - * 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-indent-level: 8 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -8 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * End: - */ diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c deleted file mode 100644 index 76c24e679e68..000000000000 --- a/drivers/cdrom/sjcd.c +++ /dev/null @@ -1,1815 +0,0 @@ -/* -- sjcd.c - * - * Sanyo CD-ROM device driver implementation, Version 1.6 - * Copyright (C) 1995 Vadim V. Model - * - * model@cecmow.enet.dec.com - * vadim@rbrf.ru - * vadim@ipsun.ras.ru - * - * - * This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de); - * it was developed under use of mcd.c from Martin Harriss, with help of - * Eric van der Maarel (H.T.M.v.d.Maarel@marin.nl). - * - * It is planned to include these routines into sbpcd.c later - to make - * a "mixed use" on one cable possible for all kinds of drives which use - * the SoundBlaster/Panasonic style CDROM interface. But today, the - * ability to install directly from CDROM is more important than flexibility. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * History: - * 1.1 First public release with kernel version 1.3.7. - * Written by Vadim Model. - * 1.2 Added detection and configuration of cdrom interface - * on ISP16 soundcard. - * Allow for command line options: sjcd=,, - * 1.3 Some minor changes to README.sjcd. - * 1.4 MSS Sound support!! Listen to a CD through the speakers. - * 1.5 Module support and bugfixes. - * Tray locking. - * 1.6 Removed ISP16 code from this driver. - * Allow only to set io base address on command line: sjcd= - * Changes to Documentation/cdrom/sjcd - * Added cleanup after any error in the initialisation. - * 1.7 Added code to set the sector size tables to prevent the bug present in - * the previous version of this driver. Coded added by Anthony Barbachan - * from bugfix tip originally suggested by Alan Cox. - * - * November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - */ - -#define SJCD_VERSION_MAJOR 1 -#define SJCD_VERSION_MINOR 7 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "sjcd.h" - -static int sjcd_present = 0; -static struct request_queue *sjcd_queue; - -#define MAJOR_NR SANYO_CDROM_MAJOR -#define QUEUE (sjcd_queue) -#define CURRENT elv_next_request(sjcd_queue) - -#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */ - -/* - * buffer for block size conversion - */ -static char sjcd_buf[2048 * SJCD_BUF_SIZ]; -static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn; -static volatile int sjcd_buf_in, sjcd_buf_out = -1; - -/* - * Status. - */ -static unsigned short sjcd_status_valid = 0; -static unsigned short sjcd_door_closed; -static unsigned short sjcd_door_was_open; -static unsigned short sjcd_media_is_available; -static unsigned short sjcd_media_is_changed; -static unsigned short sjcd_toc_uptodate = 0; -static unsigned short sjcd_command_failed; -static volatile unsigned char sjcd_completion_status = 0; -static volatile unsigned char sjcd_completion_error = 0; -static unsigned short sjcd_command_is_in_progress = 0; -static unsigned short sjcd_error_reported = 0; -static DEFINE_SPINLOCK(sjcd_lock); - -static int sjcd_open_count; - -static int sjcd_audio_status; -static struct sjcd_play_msf sjcd_playing; - -static int sjcd_base = SJCD_BASE_ADDR; - -module_param(sjcd_base, int, 0); - -static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq); - -/* - * Data transfer. - */ -static volatile unsigned short sjcd_transfer_is_active = 0; - -enum sjcd_transfer_state { - SJCD_S_IDLE = 0, - SJCD_S_START = 1, - SJCD_S_MODE = 2, - SJCD_S_READ = 3, - SJCD_S_DATA = 4, - SJCD_S_STOP = 5, - SJCD_S_STOPPING = 6 -}; -static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE; -static long sjcd_transfer_timeout = 0; -static int sjcd_read_count = 0; -static unsigned char sjcd_mode = 0; - -#define SJCD_READ_TIMEOUT 5000 - -#if defined( SJCD_GATHER_STAT ) -/* - * Statistic. - */ -static struct sjcd_stat statistic; -#endif - -/* - * Timer. - */ -static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0); - -#define SJCD_SET_TIMER( func, tmout ) \ - ( sjcd_delay_timer.expires = jiffies+tmout, \ - sjcd_delay_timer.function = ( void * )func, \ - add_timer( &sjcd_delay_timer ) ) - -#define CLEAR_TIMER del_timer( &sjcd_delay_timer ) - -/* - * Set up device, i.e., use command line data to set - * base address. - */ -#ifndef MODULE -static int __init sjcd_setup(char *str) -{ - int ints[2]; - (void) get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] > 0) - sjcd_base = ints[1]; - - return 1; -} - -__setup("sjcd=", sjcd_setup); - -#endif - -/* - * Special converters. - */ -static unsigned char bin2bcd(int bin) -{ - int u, v; - - u = bin % 10; - v = bin / 10; - return (u | (v << 4)); -} - -static int bcd2bin(unsigned char bcd) -{ - return ((bcd >> 4) * 10 + (bcd & 0x0F)); -} - -static long msf2hsg(struct msf *mp) -{ - return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75 - + bcd2bin(mp->min) * 4500 - 150); -} - -static void hsg2msf(long hsg, struct msf *msf) -{ - hsg += 150; - msf->min = hsg / 4500; - hsg %= 4500; - msf->sec = hsg / 75; - msf->frame = hsg % 75; - msf->min = bin2bcd(msf->min); /* convert to BCD */ - msf->sec = bin2bcd(msf->sec); - msf->frame = bin2bcd(msf->frame); -} - -/* - * Send a command to cdrom. Invalidate status. - */ -static void sjcd_send_cmd(unsigned char cmd) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: send_cmd( 0x%x )\n", cmd); -#endif - outb(cmd, SJCDPORT(0)); - sjcd_command_is_in_progress = 1; - sjcd_status_valid = 0; - sjcd_command_failed = 0; -} - -/* - * Send a command with one arg to cdrom. Invalidate status. - */ -static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a); -#endif - outb(cmd, SJCDPORT(0)); - outb(a, SJCDPORT(0)); - sjcd_command_is_in_progress = 1; - sjcd_status_valid = 0; - sjcd_command_failed = 0; -} - -/* - * Send a command with four args to cdrom. Invalidate status. - */ -static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a, - unsigned char b, unsigned char c, - unsigned char d) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: send_4_cmd( 0x%x )\n", cmd); -#endif - outb(cmd, SJCDPORT(0)); - outb(a, SJCDPORT(0)); - outb(b, SJCDPORT(0)); - outb(c, SJCDPORT(0)); - outb(d, SJCDPORT(0)); - sjcd_command_is_in_progress = 1; - sjcd_status_valid = 0; - sjcd_command_failed = 0; -} - -/* - * Send a play or read command to cdrom. Invalidate Status. - */ -static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: send_long_cmd( 0x%x )\n", cmd); -#endif - outb(cmd, SJCDPORT(0)); - outb(pms->start.min, SJCDPORT(0)); - outb(pms->start.sec, SJCDPORT(0)); - outb(pms->start.frame, SJCDPORT(0)); - outb(pms->end.min, SJCDPORT(0)); - outb(pms->end.sec, SJCDPORT(0)); - outb(pms->end.frame, SJCDPORT(0)); - sjcd_command_is_in_progress = 1; - sjcd_status_valid = 0; - sjcd_command_failed = 0; -} - -/* - * Get a value from the data port. Should not block, so we use a little - * wait for a while. Returns 0 if OK. - */ -static int sjcd_load_response(void *buf, int len) -{ - unsigned char *resp = (unsigned char *) buf; - - for (; len; --len) { - int i; - for (i = 200; - i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)));); - if (i > 0) - *resp++ = (unsigned char) inb(SJCDPORT(0)); - else - break; - } - return (len); -} - -/* - * Load and parse command completion status (drive info byte and maybe error). - * Sorry, no error classification yet. - */ -static void sjcd_load_status(void) -{ - sjcd_media_is_changed = 0; - sjcd_completion_error = 0; - sjcd_completion_status = inb(SJCDPORT(0)); - if (sjcd_completion_status & SST_DOOR_OPENED) { - sjcd_door_closed = sjcd_media_is_available = 0; - } else { - sjcd_door_closed = 1; - if (sjcd_completion_status & SST_MEDIA_CHANGED) - sjcd_media_is_available = sjcd_media_is_changed = - 1; - else if (sjcd_completion_status & 0x0F) { - /* - * OK, we seem to catch an error ... - */ - while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))); - sjcd_completion_error = inb(SJCDPORT(0)); - if ((sjcd_completion_status & 0x08) && - (sjcd_completion_error & 0x40)) - sjcd_media_is_available = 0; - else - sjcd_command_failed = 1; - } else - sjcd_media_is_available = 1; - } - /* - * Ok, status loaded successfully. - */ - sjcd_status_valid = 1, sjcd_error_reported = 0; - sjcd_command_is_in_progress = 0; - - /* - * If the disk is changed, the TOC is not valid. - */ - if (sjcd_media_is_changed) - sjcd_toc_uptodate = 0; -#if defined( SJCD_TRACE ) - printk("SJCD: status %02x.%02x loaded.\n", - (int) sjcd_completion_status, (int) sjcd_completion_error); -#endif -} - -/* - * Read status from cdrom. Check to see if the status is available. - */ -static int sjcd_check_status(void) -{ - /* - * Try to load the response from cdrom into buffer. - */ - if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) { - sjcd_load_status(); - return (1); - } else { - /* - * No status is available. - */ - return (0); - } -} - -/* - * This is just timeout counter, and nothing more. Surprised ? :-) - */ -static volatile long sjcd_status_timeout; - -/* - * We need about 10 seconds to wait. The longest command takes about 5 seconds - * to probe the disk (usually after tray closed or drive reset). Other values - * should be thought of for other commands. - */ -#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000 - -static void sjcd_status_timer(void) -{ - if (sjcd_check_status()) { - /* - * The command completed and status is loaded, stop waiting. - */ - wake_up(&sjcd_waitq); - } else if (--sjcd_status_timeout <= 0) { - /* - * We are timed out. - */ - wake_up(&sjcd_waitq); - } else { - /* - * We have still some time to wait. Try again. - */ - SJCD_SET_TIMER(sjcd_status_timer, 1); - } -} - -/* - * Wait for status for 10 sec approx. Returns non-positive when timed out. - * Should not be used while reading data CDs. - */ -static int sjcd_wait_for_status(void) -{ - sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT; - SJCD_SET_TIMER(sjcd_status_timer, 1); - sleep_on(&sjcd_waitq); -#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE ) - if (sjcd_status_timeout <= 0) - printk("SJCD: Error Wait For Status.\n"); -#endif - return (sjcd_status_timeout); -} - -static int sjcd_receive_status(void) -{ - int i; -#if defined( SJCD_TRACE ) - printk("SJCD: receive_status\n"); -#endif - /* - * Wait a bit for status available. - */ - for (i = 200; i-- && (sjcd_check_status() == 0);); - if (i < 0) { -#if defined( SJCD_TRACE ) - printk("SJCD: long wait for status\n"); -#endif - if (sjcd_wait_for_status() <= 0) - printk("SJCD: Timeout when read status.\n"); - else - i = 0; - } - return (i); -} - -/* - * Load the status. Issue get status command and wait for status available. - */ -static void sjcd_get_status(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: get_status\n"); -#endif - sjcd_send_cmd(SCMD_GET_STATUS); - sjcd_receive_status(); -} - -/* - * Check the drive if the disk is changed. Should be revised. - */ -static int sjcd_disk_change(struct gendisk *disk) -{ -#if 0 - printk("SJCD: sjcd_disk_change(%s)\n", disk->disk_name); -#endif - if (!sjcd_command_is_in_progress) - sjcd_get_status(); - return (sjcd_status_valid ? sjcd_media_is_changed : 0); -} - -/* - * Read the table of contents (TOC) and TOC header if necessary. - * We assume that the drive contains no more than 99 toc entries. - */ -static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS]; -static unsigned char sjcd_first_track_no, sjcd_last_track_no; -#define sjcd_disk_length sjcd_table_of_contents[0].un.track_msf - -static int sjcd_update_toc(void) -{ - struct sjcd_hw_disk_info info; - int i; -#if defined( SJCD_TRACE ) - printk("SJCD: update toc:\n"); -#endif - /* - * check to see if we need to do anything - */ - if (sjcd_toc_uptodate) - return (0); - - /* - * Get the TOC start information. - */ - sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK); - sjcd_receive_status(); - - if (!sjcd_status_valid) { - printk("SJCD: cannot load status.\n"); - return (-1); - } - - if (!sjcd_media_is_available) { - printk("SJCD: no disk in drive\n"); - return (-1); - } - - if (!sjcd_command_failed) { - if (sjcd_load_response(&info, sizeof(info)) != 0) { - printk - ("SJCD: cannot load response about TOC start.\n"); - return (-1); - } - sjcd_first_track_no = bcd2bin(info.un.track_no); - } else { - printk("SJCD: get first failed\n"); - return (-1); - } -#if defined( SJCD_TRACE ) - printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no); -#endif - /* - * Get the TOC finish information. - */ - sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK); - sjcd_receive_status(); - - if (!sjcd_status_valid) { - printk("SJCD: cannot load status.\n"); - return (-1); - } - - if (!sjcd_media_is_available) { - printk("SJCD: no disk in drive\n"); - return (-1); - } - - if (!sjcd_command_failed) { - if (sjcd_load_response(&info, sizeof(info)) != 0) { - printk - ("SJCD: cannot load response about TOC finish.\n"); - return (-1); - } - sjcd_last_track_no = bcd2bin(info.un.track_no); - } else { - printk("SJCD: get last failed\n"); - return (-1); - } -#if defined( SJCD_TRACE ) - printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no); -#endif - for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) { - /* - * Get the first track information. - */ - sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i)); - sjcd_receive_status(); - - if (!sjcd_status_valid) { - printk("SJCD: cannot load status.\n"); - return (-1); - } - - if (!sjcd_media_is_available) { - printk("SJCD: no disk in drive\n"); - return (-1); - } - - if (!sjcd_command_failed) { - if (sjcd_load_response(&sjcd_table_of_contents[i], - sizeof(struct - sjcd_hw_disk_info)) - != 0) { - printk - ("SJCD: cannot load info for %d track\n", - i); - return (-1); - } - } else { - printk("SJCD: get info %d failed\n", i); - return (-1); - } - } - - /* - * Get the disk length info. - */ - sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE); - sjcd_receive_status(); - - if (!sjcd_status_valid) { - printk("SJCD: cannot load status.\n"); - return (-1); - } - - if (!sjcd_media_is_available) { - printk("SJCD: no disk in drive\n"); - return (-1); - } - - if (!sjcd_command_failed) { - if (sjcd_load_response(&info, sizeof(info)) != 0) { - printk - ("SJCD: cannot load response about disk size.\n"); - return (-1); - } - sjcd_disk_length.min = info.un.track_msf.min; - sjcd_disk_length.sec = info.un.track_msf.sec; - sjcd_disk_length.frame = info.un.track_msf.frame; - } else { - printk("SJCD: get size failed\n"); - return (1); - } -#if defined( SJCD_TRACE ) - printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min, - sjcd_disk_length.sec, sjcd_disk_length.frame); -#endif - return (0); -} - -/* - * Load subchannel information. - */ -static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp) -{ - int s; -#if defined( SJCD_TRACE ) - printk("SJCD: load sub q\n"); -#endif - sjcd_send_cmd(SCMD_GET_QINFO); - s = sjcd_receive_status(); - if (s < 0 || sjcd_command_failed || !sjcd_status_valid) { - sjcd_send_cmd(0xF2); - s = sjcd_receive_status(); - if (s < 0 || sjcd_command_failed || !sjcd_status_valid) - return (-1); - sjcd_send_cmd(SCMD_GET_QINFO); - s = sjcd_receive_status(); - if (s < 0 || sjcd_command_failed || !sjcd_status_valid) - return (-1); - } - if (sjcd_media_is_available) - if (sjcd_load_response(qp, sizeof(*qp)) == 0) - return (0); - return (-1); -} - -/* - * Start playing from the specified position. - */ -static int sjcd_play(struct sjcd_play_msf *mp) -{ - struct sjcd_play_msf msf; - - /* - * Turn the device to play mode. - */ - sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY); - if (sjcd_receive_status() < 0) - return (-1); - - /* - * Seek to the starting point. - */ - msf.start = mp->start; - msf.end.min = msf.end.sec = msf.end.frame = 0x00; - sjcd_send_6_cmd(SCMD_SEEK, &msf); - if (sjcd_receive_status() < 0) - return (-1); - - /* - * Start playing. - */ - sjcd_send_6_cmd(SCMD_PLAY, mp); - return (sjcd_receive_status()); -} - -/* - * Tray control functions. - */ -static int sjcd_tray_close(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: tray_close\n"); -#endif - sjcd_send_cmd(SCMD_CLOSE_TRAY); - return (sjcd_receive_status()); -} - -static int sjcd_tray_lock(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: tray_lock\n"); -#endif - sjcd_send_cmd(SCMD_LOCK_TRAY); - return (sjcd_receive_status()); -} - -static int sjcd_tray_unlock(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: tray_unlock\n"); -#endif - sjcd_send_cmd(SCMD_UNLOCK_TRAY); - return (sjcd_receive_status()); -} - -static int sjcd_tray_open(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: tray_open\n"); -#endif - sjcd_send_cmd(SCMD_EJECT_TRAY); - return (sjcd_receive_status()); -} - -/* - * Do some user commands. - */ -static int sjcd_ioctl(struct inode *ip, struct file *fp, - unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; -#if defined( SJCD_TRACE ) - printk("SJCD:ioctl\n"); -#endif - - sjcd_get_status(); - if (!sjcd_status_valid) - return (-EIO); - if (sjcd_update_toc() < 0) - return (-EIO); - - switch (cmd) { - case CDROMSTART:{ -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: start\n"); -#endif - return (0); - } - - case CDROMSTOP:{ -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: stop\n"); -#endif - sjcd_send_cmd(SCMD_PAUSE); - (void) sjcd_receive_status(); - sjcd_audio_status = CDROM_AUDIO_NO_STATUS; - return (0); - } - - case CDROMPAUSE:{ - struct sjcd_hw_qinfo q_info; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: pause\n"); -#endif - if (sjcd_audio_status == CDROM_AUDIO_PLAY) { - sjcd_send_cmd(SCMD_PAUSE); - (void) sjcd_receive_status(); - if (sjcd_get_q_info(&q_info) < 0) { - sjcd_audio_status = - CDROM_AUDIO_NO_STATUS; - } else { - sjcd_audio_status = - CDROM_AUDIO_PAUSED; - sjcd_playing.start = q_info.abs; - } - return (0); - } else - return (-EINVAL); - } - - case CDROMRESUME:{ -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: resume\n"); -#endif - if (sjcd_audio_status == CDROM_AUDIO_PAUSED) { - /* - * continue play starting at saved location - */ - if (sjcd_play(&sjcd_playing) < 0) { - sjcd_audio_status = - CDROM_AUDIO_ERROR; - return (-EIO); - } else { - sjcd_audio_status = - CDROM_AUDIO_PLAY; - return (0); - } - } else - return (-EINVAL); - } - - case CDROMPLAYTRKIND:{ - struct cdrom_ti ti; - int s = -EFAULT; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: playtrkind\n"); -#endif - if (!copy_from_user(&ti, argp, sizeof(ti))) { - s = 0; - if (ti.cdti_trk0 < sjcd_first_track_no) - return (-EINVAL); - if (ti.cdti_trk1 > sjcd_last_track_no) - ti.cdti_trk1 = sjcd_last_track_no; - if (ti.cdti_trk0 > ti.cdti_trk1) - return (-EINVAL); - - sjcd_playing.start = - sjcd_table_of_contents[ti.cdti_trk0]. - un.track_msf; - sjcd_playing.end = - (ti.cdti_trk1 < - sjcd_last_track_no) ? - sjcd_table_of_contents[ti.cdti_trk1 + - 1].un. - track_msf : sjcd_table_of_contents[0]. - un.track_msf; - - if (sjcd_play(&sjcd_playing) < 0) { - sjcd_audio_status = - CDROM_AUDIO_ERROR; - return (-EIO); - } else - sjcd_audio_status = - CDROM_AUDIO_PLAY; - } - return (s); - } - - case CDROMPLAYMSF:{ - struct cdrom_msf sjcd_msf; - int s; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: playmsf\n"); -#endif - if ((s = - access_ok(VERIFY_READ, argp, sizeof(sjcd_msf)) - ? 0 : -EFAULT) == 0) { - if (sjcd_audio_status == CDROM_AUDIO_PLAY) { - sjcd_send_cmd(SCMD_PAUSE); - (void) sjcd_receive_status(); - sjcd_audio_status = - CDROM_AUDIO_NO_STATUS; - } - - if (copy_from_user(&sjcd_msf, argp, - sizeof(sjcd_msf))) - return (-EFAULT); - - sjcd_playing.start.min = - bin2bcd(sjcd_msf.cdmsf_min0); - sjcd_playing.start.sec = - bin2bcd(sjcd_msf.cdmsf_sec0); - sjcd_playing.start.frame = - bin2bcd(sjcd_msf.cdmsf_frame0); - sjcd_playing.end.min = - bin2bcd(sjcd_msf.cdmsf_min1); - sjcd_playing.end.sec = - bin2bcd(sjcd_msf.cdmsf_sec1); - sjcd_playing.end.frame = - bin2bcd(sjcd_msf.cdmsf_frame1); - - if (sjcd_play(&sjcd_playing) < 0) { - sjcd_audio_status = - CDROM_AUDIO_ERROR; - return (-EIO); - } else - sjcd_audio_status = - CDROM_AUDIO_PLAY; - } - return (s); - } - - case CDROMREADTOCHDR:{ - struct cdrom_tochdr toc_header; -#if defined (SJCD_TRACE ) - printk("SJCD: ioctl: readtocheader\n"); -#endif - toc_header.cdth_trk0 = sjcd_first_track_no; - toc_header.cdth_trk1 = sjcd_last_track_no; - if (copy_to_user(argp, &toc_header, - sizeof(toc_header))) - return -EFAULT; - return 0; - } - - case CDROMREADTOCENTRY:{ - struct cdrom_tocentry toc_entry; - int s; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: readtocentry\n"); -#endif - if ((s = - access_ok(VERIFY_WRITE, argp, sizeof(toc_entry)) - ? 0 : -EFAULT) == 0) { - struct sjcd_hw_disk_info *tp; - - if (copy_from_user(&toc_entry, argp, - sizeof(toc_entry))) - return (-EFAULT); - if (toc_entry.cdte_track == CDROM_LEADOUT) - tp = &sjcd_table_of_contents[0]; - else if (toc_entry.cdte_track < - sjcd_first_track_no) - return (-EINVAL); - else if (toc_entry.cdte_track > - sjcd_last_track_no) - return (-EINVAL); - else - tp = &sjcd_table_of_contents - [toc_entry.cdte_track]; - - toc_entry.cdte_adr = - tp->track_control & 0x0F; - toc_entry.cdte_ctrl = - tp->track_control >> 4; - - switch (toc_entry.cdte_format) { - case CDROM_LBA: - toc_entry.cdte_addr.lba = - msf2hsg(&(tp->un.track_msf)); - break; - case CDROM_MSF: - toc_entry.cdte_addr.msf.minute = - bcd2bin(tp->un.track_msf.min); - toc_entry.cdte_addr.msf.second = - bcd2bin(tp->un.track_msf.sec); - toc_entry.cdte_addr.msf.frame = - bcd2bin(tp->un.track_msf. - frame); - break; - default: - return (-EINVAL); - } - if (copy_to_user(argp, &toc_entry, - sizeof(toc_entry))) - s = -EFAULT; - } - return (s); - } - - case CDROMSUBCHNL:{ - struct cdrom_subchnl subchnl; - int s; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: subchnl\n"); -#endif - if ((s = - access_ok(VERIFY_WRITE, argp, sizeof(subchnl)) - ? 0 : -EFAULT) == 0) { - struct sjcd_hw_qinfo q_info; - - if (copy_from_user(&subchnl, argp, - sizeof(subchnl))) - return (-EFAULT); - - if (sjcd_get_q_info(&q_info) < 0) - return (-EIO); - - subchnl.cdsc_audiostatus = - sjcd_audio_status; - subchnl.cdsc_adr = - q_info.track_control & 0x0F; - subchnl.cdsc_ctrl = - q_info.track_control >> 4; - subchnl.cdsc_trk = - bcd2bin(q_info.track_no); - subchnl.cdsc_ind = bcd2bin(q_info.x); - - switch (subchnl.cdsc_format) { - case CDROM_LBA: - subchnl.cdsc_absaddr.lba = - msf2hsg(&(q_info.abs)); - subchnl.cdsc_reladdr.lba = - msf2hsg(&(q_info.rel)); - break; - case CDROM_MSF: - subchnl.cdsc_absaddr.msf.minute = - bcd2bin(q_info.abs.min); - subchnl.cdsc_absaddr.msf.second = - bcd2bin(q_info.abs.sec); - subchnl.cdsc_absaddr.msf.frame = - bcd2bin(q_info.abs.frame); - subchnl.cdsc_reladdr.msf.minute = - bcd2bin(q_info.rel.min); - subchnl.cdsc_reladdr.msf.second = - bcd2bin(q_info.rel.sec); - subchnl.cdsc_reladdr.msf.frame = - bcd2bin(q_info.rel.frame); - break; - default: - return (-EINVAL); - } - if (copy_to_user(argp, &subchnl, - sizeof(subchnl))) - s = -EFAULT; - } - return (s); - } - - case CDROMVOLCTRL:{ - struct cdrom_volctrl vol_ctrl; - int s; -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: volctrl\n"); -#endif - if ((s = - access_ok(VERIFY_READ, argp, sizeof(vol_ctrl)) - ? 0 : -EFAULT) == 0) { - unsigned char dummy[4]; - - if (copy_from_user(&vol_ctrl, argp, - sizeof(vol_ctrl))) - return (-EFAULT); - sjcd_send_4_cmd(SCMD_SET_VOLUME, - vol_ctrl.channel0, 0xFF, - vol_ctrl.channel1, 0xFF); - if (sjcd_receive_status() < 0) - return (-EIO); - (void) sjcd_load_response(dummy, 4); - } - return (s); - } - - case CDROMEJECT:{ -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: eject\n"); -#endif - if (!sjcd_command_is_in_progress) { - sjcd_tray_unlock(); - sjcd_send_cmd(SCMD_EJECT_TRAY); - (void) sjcd_receive_status(); - } - return (0); - } - -#if defined( SJCD_GATHER_STAT ) - case 0xABCD:{ -#if defined( SJCD_TRACE ) - printk("SJCD: ioctl: statistic\n"); -#endif - if (copy_to_user(argp, &statistic, sizeof(statistic))) - return -EFAULT; - return 0; - } -#endif - - default: - return (-EINVAL); - } -} - -/* - * Invalidate internal buffers of the driver. - */ -static void sjcd_invalidate_buffers(void) -{ - int i; - for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1); - sjcd_buf_out = -1; -} - -/* - * Take care of the different block sizes between cdrom and Linux. - * When Linux gets variable block sizes this will probably go away. - */ - -static int current_valid(void) -{ - return CURRENT && - rq_data_dir(CURRENT) == READ && - CURRENT->sector != -1; -} - -static void sjcd_transfer(void) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: transfer:\n"); -#endif - if (current_valid()) { - while (CURRENT->nr_sectors) { - int i, bn = CURRENT->sector / 4; - for (i = 0; - i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn; - i++); - if (i < SJCD_BUF_SIZ) { - int offs = - (i * 4 + (CURRENT->sector & 3)) * 512; - int nr_sectors = 4 - (CURRENT->sector & 3); - if (sjcd_buf_out != i) { - sjcd_buf_out = i; - if (sjcd_buf_bn[i] != bn) { - sjcd_buf_out = -1; - continue; - } - } - if (nr_sectors > CURRENT->nr_sectors) - nr_sectors = CURRENT->nr_sectors; -#if defined( SJCD_TRACE ) - printk("SJCD: copy out\n"); -#endif - memcpy(CURRENT->buffer, sjcd_buf + offs, - nr_sectors * 512); - CURRENT->nr_sectors -= nr_sectors; - CURRENT->sector += nr_sectors; - CURRENT->buffer += nr_sectors * 512; - } else { - sjcd_buf_out = -1; - break; - } - } - } -#if defined( SJCD_TRACE ) - printk("SJCD: transfer: done\n"); -#endif -} - -static void sjcd_poll(void) -{ -#if defined( SJCD_GATHER_STAT ) - /* - * Update total number of ticks. - */ - statistic.ticks++; - statistic.tticks[sjcd_transfer_state]++; -#endif - - ReSwitch:switch (sjcd_transfer_state) { - - case SJCD_S_IDLE:{ -#if defined( SJCD_GATHER_STAT ) - statistic.idle_ticks++; -#endif -#if defined( SJCD_TRACE ) - printk("SJCD_S_IDLE\n"); -#endif - return; - } - - case SJCD_S_START:{ -#if defined( SJCD_GATHER_STAT ) - statistic.start_ticks++; -#endif - sjcd_send_cmd(SCMD_GET_STATUS); - sjcd_transfer_state = - sjcd_mode == - SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE; - sjcd_transfer_timeout = 500; -#if defined( SJCD_TRACE ) - printk("SJCD_S_START: goto SJCD_S_%s mode\n", - sjcd_transfer_state == - SJCD_S_READ ? "READ" : "MODE"); -#endif - break; - } - - case SJCD_S_MODE:{ - if (sjcd_check_status()) { - /* - * Previous command is completed. - */ - if (!sjcd_status_valid - || sjcd_command_failed) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - - sjcd_mode = 0; /* unknown mode; should not be valid when failed */ - sjcd_send_1_cmd(SCMD_SET_MODE, - SCMD_MODE_COOKED); - sjcd_transfer_state = SJCD_S_READ; - sjcd_transfer_timeout = 1000; -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_MODE: goto SJCD_S_READ mode\n"); -#endif - } -#if defined( SJCD_GATHER_STAT ) - else - statistic.mode_ticks++; -#endif - break; - } - - case SJCD_S_READ:{ - if (sjcd_status_valid ? 1 : sjcd_check_status()) { - /* - * Previous command is completed. - */ - if (!sjcd_status_valid - || sjcd_command_failed) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - if (!sjcd_media_is_available) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - if (sjcd_mode != SCMD_MODE_COOKED) { - /* - * We seem to come from set mode. So discard one byte of result. - */ - if (sjcd_load_response - (&sjcd_mode, 1) != 0) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = - SJCD_S_STOP; - goto ReSwitch; - } - if (sjcd_mode != SCMD_MODE_COOKED) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = - SJCD_S_STOP; - goto ReSwitch; - } - } - - if (current_valid()) { - struct sjcd_play_msf msf; - - sjcd_next_bn = CURRENT->sector / 4; - hsg2msf(sjcd_next_bn, &msf.start); - msf.end.min = 0; - msf.end.sec = 0; - msf.end.frame = sjcd_read_count = - SJCD_BUF_SIZ; -#if defined( SJCD_TRACE ) - printk - ("SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n", - msf.start.min, msf.start.sec, - msf.start.frame, msf.end.min, - msf.end.sec, msf.end.frame); - printk - ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n", - sjcd_next_bn, sjcd_buf_in, - sjcd_buf_out, - sjcd_buf_bn[sjcd_buf_in]); -#endif - sjcd_send_6_cmd(SCMD_DATA_READ, - &msf); - sjcd_transfer_state = SJCD_S_DATA; - sjcd_transfer_timeout = 500; -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: go to SJCD_S_DATA mode\n"); -#endif - } else { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - } -#if defined( SJCD_GATHER_STAT ) - else - statistic.read_ticks++; -#endif - break; - } - - case SJCD_S_DATA:{ - unsigned char stat; - - sjcd_s_data:stat = - inb(SJCDPORT - (1)); -#if defined( SJCD_TRACE ) - printk("SJCD_S_DATA: status = 0x%02x\n", stat); -#endif - if (SJCD_STATUS_AVAILABLE(stat)) { - /* - * No data is waiting for us in the drive buffer. Status of operation - * completion is available. Read and parse it. - */ - sjcd_load_status(); - - if (!sjcd_status_valid - || sjcd_command_failed) { -#if defined( SJCD_TRACE ) - printk - ("SJCD: read block %d failed, maybe audio disk? Giving up\n", - sjcd_next_bn); -#endif - if (current_valid()) - end_request(CURRENT, 0); -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - - if (!sjcd_media_is_available) { - printk - ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n"); - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - - sjcd_transfer_state = SJCD_S_READ; - goto ReSwitch; - } else if (SJCD_DATA_AVAILABLE(stat)) { - /* - * One frame is read into device buffer. We must copy it to our memory. - * Otherwise cdrom hangs up. Check to see if we have something to copy - * to. - */ - if (!current_valid() - && sjcd_buf_in == sjcd_buf_out) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n"); - printk - (" ... all the date would be discarded\n"); -#endif - sjcd_transfer_state = SJCD_S_STOP; - goto ReSwitch; - } - - /* - * Everything seems to be OK. Just read the frame and recalculate - * indices. - */ - sjcd_buf_bn[sjcd_buf_in] = -1; /* ??? */ - insb(SJCDPORT(2), - sjcd_buf + 2048 * sjcd_buf_in, 2048); -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n", - sjcd_next_bn, sjcd_buf_in, - sjcd_buf_out, - sjcd_buf_bn[sjcd_buf_in]); -#endif - sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++; - if (sjcd_buf_out == -1) - sjcd_buf_out = sjcd_buf_in; - if (++sjcd_buf_in == SJCD_BUF_SIZ) - sjcd_buf_in = 0; - - /* - * Only one frame is ready at time. So we should turn over to wait for - * another frame. If we need that, of course. - */ - if (--sjcd_read_count == 0) { - /* - * OK, request seems to be precessed. Continue transferring... - */ - if (!sjcd_transfer_is_active) { - while (current_valid()) { - /* - * Continue transferring. - */ - sjcd_transfer(); - if (CURRENT-> - nr_sectors == - 0) - end_request - (CURRENT, 1); - else - break; - } - } - if (current_valid() && - (CURRENT->sector / 4 < - sjcd_next_bn - || CURRENT->sector / 4 > - sjcd_next_bn + - SJCD_BUF_SIZ)) { -#if defined( SJCD_TRACE ) - printk - ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n"); -#endif - sjcd_transfer_state = - SJCD_S_STOP; - goto ReSwitch; - } - } - /* - * Now we should turn around rather than wait for while. - */ - goto sjcd_s_data; - } -#if defined( SJCD_GATHER_STAT ) - else - statistic.data_ticks++; -#endif - break; - } - - case SJCD_S_STOP:{ - sjcd_read_count = 0; - sjcd_send_cmd(SCMD_STOP); - sjcd_transfer_state = SJCD_S_STOPPING; - sjcd_transfer_timeout = 500; -#if defined( SJCD_GATHER_STAT ) - statistic.stop_ticks++; -#endif - break; - } - - case SJCD_S_STOPPING:{ - unsigned char stat; - - stat = inb(SJCDPORT(1)); -#if defined( SJCD_TRACE ) - printk("SJCD_S_STOP: status = 0x%02x\n", stat); -#endif - if (SJCD_DATA_AVAILABLE(stat)) { - int i; -#if defined( SJCD_TRACE ) - printk("SJCD_S_STOP: discard data\n"); -#endif - /* - * Discard all the data from the pipe. Foolish method. - */ - for (i = 2048; i--; - (void) inb(SJCDPORT(2))); - sjcd_transfer_timeout = 500; - } else if (SJCD_STATUS_AVAILABLE(stat)) { - sjcd_load_status(); - if (sjcd_status_valid - && sjcd_media_is_changed) { - sjcd_toc_uptodate = 0; - sjcd_invalidate_buffers(); - } - if (current_valid()) { - if (sjcd_status_valid) - sjcd_transfer_state = - SJCD_S_READ; - else - sjcd_transfer_state = - SJCD_S_START; - } else - sjcd_transfer_state = SJCD_S_IDLE; - goto ReSwitch; - } -#if defined( SJCD_GATHER_STAT ) - else - statistic.stopping_ticks++; -#endif - break; - } - - default: - printk("SJCD: poll: invalid state %d\n", - sjcd_transfer_state); - return; - } - - if (--sjcd_transfer_timeout == 0) { - printk("SJCD: timeout in state %d\n", sjcd_transfer_state); - while (current_valid()) - end_request(CURRENT, 0); - sjcd_send_cmd(SCMD_STOP); - sjcd_transfer_state = SJCD_S_IDLE; - goto ReSwitch; - } - - /* - * Get back in some time. 1 should be replaced with count variable to - * avoid unnecessary testings. - */ - SJCD_SET_TIMER(sjcd_poll, 1); -} - -static void do_sjcd_request(request_queue_t * q) -{ -#if defined( SJCD_TRACE ) - printk("SJCD: do_sjcd_request(%ld+%ld)\n", - CURRENT->sector, CURRENT->nr_sectors); -#endif - sjcd_transfer_is_active = 1; - while (current_valid()) { - sjcd_transfer(); - if (CURRENT->nr_sectors == 0) - end_request(CURRENT, 1); - else { - sjcd_buf_out = -1; /* Want to read a block not in buffer */ - if (sjcd_transfer_state == SJCD_S_IDLE) { - if (!sjcd_toc_uptodate) { - if (sjcd_update_toc() < 0) { - printk - ("SJCD: transfer: discard\n"); - while (current_valid()) - end_request(CURRENT, 0); - break; - } - } - sjcd_transfer_state = SJCD_S_START; - SJCD_SET_TIMER(sjcd_poll, HZ / 100); - } - break; - } - } - sjcd_transfer_is_active = 0; -#if defined( SJCD_TRACE ) - printk - ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n", - sjcd_next_bn, sjcd_buf_in, sjcd_buf_out, - sjcd_buf_bn[sjcd_buf_in]); - printk("do_sjcd_request ends\n"); -#endif -} - -/* - * Open the device special file. Check disk is in. - */ -static int sjcd_open(struct inode *ip, struct file *fp) -{ - /* - * Check the presence of device. - */ - if (!sjcd_present) - return (-ENXIO); - - /* - * Only read operations are allowed. Really? (:-) - */ - if (fp->f_mode & 2) - return (-EROFS); - - if (sjcd_open_count == 0) { - int s, sjcd_open_tries; -/* We don't know that, do we? */ -/* - sjcd_audio_status = CDROM_AUDIO_NO_STATUS; -*/ - sjcd_mode = 0; - sjcd_door_was_open = 0; - sjcd_transfer_state = SJCD_S_IDLE; - sjcd_invalidate_buffers(); - sjcd_status_valid = 0; - - /* - * Strict status checking. - */ - for (sjcd_open_tries = 4; --sjcd_open_tries;) { - if (!sjcd_status_valid) - sjcd_get_status(); - if (!sjcd_status_valid) { -#if defined( SJCD_DIAGNOSTIC ) - printk - ("SJCD: open: timed out when check status.\n"); -#endif - goto err_out; - } else if (!sjcd_media_is_available) { -#if defined( SJCD_DIAGNOSTIC ) - printk("SJCD: open: no disk in drive\n"); -#endif - if (!sjcd_door_closed) { - sjcd_door_was_open = 1; -#if defined( SJCD_TRACE ) - printk - ("SJCD: open: close the tray\n"); -#endif - s = sjcd_tray_close(); - if (s < 0 || !sjcd_status_valid - || sjcd_command_failed) { -#if defined( SJCD_DIAGNOSTIC ) - printk - ("SJCD: open: tray close attempt failed\n"); -#endif - goto err_out; - } - continue; - } else - goto err_out; - } - break; - } - s = sjcd_tray_lock(); - if (s < 0 || !sjcd_status_valid || sjcd_command_failed) { -#if defined( SJCD_DIAGNOSTIC ) - printk("SJCD: open: tray lock attempt failed\n"); -#endif - goto err_out; - } -#if defined( SJCD_TRACE ) - printk("SJCD: open: done\n"); -#endif - } - - ++sjcd_open_count; - return (0); - - err_out: - return (-EIO); -} - -/* - * On close, we flush all sjcd blocks from the buffer cache. - */ -static int sjcd_release(struct inode *inode, struct file *file) -{ - int s; - -#if defined( SJCD_TRACE ) - printk("SJCD: release\n"); -#endif - if (--sjcd_open_count == 0) { - sjcd_invalidate_buffers(); - s = sjcd_tray_unlock(); - if (s < 0 || !sjcd_status_valid || sjcd_command_failed) { -#if defined( SJCD_DIAGNOSTIC ) - printk - ("SJCD: release: tray unlock attempt failed.\n"); -#endif - } - if (sjcd_door_was_open) { - s = sjcd_tray_open(); - if (s < 0 || !sjcd_status_valid - || sjcd_command_failed) { -#if defined( SJCD_DIAGNOSTIC ) - printk - ("SJCD: release: tray unload attempt failed.\n"); -#endif - } - } - } - return 0; -} - -/* - * A list of file operations allowed for this cdrom. - */ -static struct block_device_operations sjcd_fops = { - .owner = THIS_MODULE, - .open = sjcd_open, - .release = sjcd_release, - .ioctl = sjcd_ioctl, - .media_changed = sjcd_disk_change, -}; - -/* - * Following stuff is intended for initialization of the cdrom. It - * first looks for presence of device. If the device is present, it - * will be reset. Then read the version of the drive and load status. - * The version is two BCD-coded bytes. - */ -static struct { - unsigned char major, minor; -} sjcd_version; - -static struct gendisk *sjcd_disk; - -/* - * Test for presence of drive and initialize it. Called at boot time. - * Probe cdrom, find out version and status. - */ -static int __init sjcd_init(void) -{ - int i; - - printk(KERN_INFO - "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n", - SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR); - -#if defined( SJCD_TRACE ) - printk("SJCD: sjcd=0x%x: ", sjcd_base); -#endif - - if (register_blkdev(MAJOR_NR, "sjcd")) - return -EIO; - - sjcd_queue = blk_init_queue(do_sjcd_request, &sjcd_lock); - if (!sjcd_queue) - goto out0; - - blk_queue_hardsect_size(sjcd_queue, 2048); - - sjcd_disk = alloc_disk(1); - if (!sjcd_disk) { - printk(KERN_ERR "SJCD: can't allocate disk"); - goto out1; - } - sjcd_disk->major = MAJOR_NR, - sjcd_disk->first_minor = 0, - sjcd_disk->fops = &sjcd_fops, - sprintf(sjcd_disk->disk_name, "sjcd"); - - if (!request_region(sjcd_base, 4,"sjcd")) { - printk - ("SJCD: Init failed, I/O port (%X) is already in use\n", - sjcd_base); - goto out2; - } - - /* - * Check for card. Since we are booting now, we can't use standard - * wait algorithm. - */ - printk(KERN_INFO "SJCD: Resetting: "); - sjcd_send_cmd(SCMD_RESET); - for (i = 1000; i > 0 && !sjcd_status_valid; --i) { - unsigned long timer; - - /* - * Wait 10ms approx. - */ - for (timer = jiffies; time_before_eq(jiffies, timer);); - if ((i % 100) == 0) - printk("."); - (void) sjcd_check_status(); - } - if (i == 0 || sjcd_command_failed) { - printk(" reset failed, no drive found.\n"); - goto out3; - } else - printk("\n"); - - /* - * Get and print out cdrom version. - */ - printk(KERN_INFO "SJCD: Getting version: "); - sjcd_send_cmd(SCMD_GET_VERSION); - for (i = 1000; i > 0 && !sjcd_status_valid; --i) { - unsigned long timer; - - /* - * Wait 10ms approx. - */ - for (timer = jiffies; time_before_eq(jiffies, timer);); - if ((i % 100) == 0) - printk("."); - (void) sjcd_check_status(); - } - if (i == 0 || sjcd_command_failed) { - printk(" get version failed, no drive found.\n"); - goto out3; - } - - if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) { - printk(" %1x.%02x\n", (int) sjcd_version.major, - (int) sjcd_version.minor); - } else { - printk(" read version failed, no drive found.\n"); - goto out3; - } - - /* - * Check and print out the tray state. (if it is needed?). - */ - if (!sjcd_status_valid) { - printk(KERN_INFO "SJCD: Getting status: "); - sjcd_send_cmd(SCMD_GET_STATUS); - for (i = 1000; i > 0 && !sjcd_status_valid; --i) { - unsigned long timer; - - /* - * Wait 10ms approx. - */ - for (timer = jiffies; - time_before_eq(jiffies, timer);); - if ((i % 100) == 0) - printk("."); - (void) sjcd_check_status(); - } - if (i == 0 || sjcd_command_failed) { - printk(" get status failed, no drive found.\n"); - goto out3; - } else - printk("\n"); - } - - printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base); - sjcd_disk->queue = sjcd_queue; - add_disk(sjcd_disk); - - sjcd_present++; - return (0); -out3: - release_region(sjcd_base, 4); -out2: - put_disk(sjcd_disk); -out1: - blk_cleanup_queue(sjcd_queue); -out0: - if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL)) - printk("SJCD: cannot unregister device.\n"); - return (-EIO); -} - -static void __exit sjcd_exit(void) -{ - del_gendisk(sjcd_disk); - put_disk(sjcd_disk); - release_region(sjcd_base, 4); - blk_cleanup_queue(sjcd_queue); - if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL)) - printk("SJCD: cannot unregister device.\n"); - printk(KERN_INFO "SJCD: module: removed.\n"); -} - -module_init(sjcd_init); -module_exit(sjcd_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR); diff --git a/drivers/cdrom/sjcd.h b/drivers/cdrom/sjcd.h deleted file mode 100644 index 0aa5e714659d..000000000000 --- a/drivers/cdrom/sjcd.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Definitions for a Sanyo CD-ROM interface. - * - * Copyright (C) 1995 Vadim V. Model - * model@cecmow.enet.dec.com - * vadim@rbrf.msk.su - * vadim@ipsun.ras.ru - * Eric van der Maarel - * H.T.M.v.d.Maarel@marin.nl - * - * This information is based on mcd.c from M. Harriss and sjcd102.lst from - * E. Moenkeberg. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __SJCD_H__ -#define __SJCD_H__ - -/* - * Change this to set the I/O port address as default. More flexibility - * come with setup implementation. - */ -#define SJCD_BASE_ADDR 0x340 - -/* - * Change this to set the irq as default. Really SANYO do not use interrupts - * at all. - */ -#define SJCD_INTR_NR 0 - -/* - * Change this to set the dma as default value. really SANYO does not use - * direct memory access at all. - */ -#define SJCD_DMA_NR 0 - -/* - * Macros which allow us to find out the status of the drive. - */ -#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0) -#define SJCD_DATA_AVAILABLE( x ) (((x)&0x01)==0) - -/* - * Port access macro. Three ports are available: S-data port (command port), - * status port (read only) and D-data port (read only). - */ -#define SJCDPORT( x ) ( sjcd_base + ( x ) ) -#define SJCD_STATUS_PORT SJCDPORT( 1 ) -#define SJCD_S_DATA_PORT SJCDPORT( 0 ) -#define SJCD_COMMAND_PORT SJCDPORT( 0 ) -#define SJCD_D_DATA_PORT SJCDPORT( 2 ) - -/* - * Drive info bits. Drive info available as first (mandatory) byte of - * command completion status. - */ -#define SST_NOT_READY 0x10 /* no disk in the drive (???) */ -#define SST_MEDIA_CHANGED 0x20 /* disk is changed */ -#define SST_DOOR_OPENED 0x40 /* door is open */ - -/* commands */ - -#define SCMD_EJECT_TRAY 0xD0 /* eject tray if not locked */ -#define SCMD_LOCK_TRAY 0xD2 /* lock tray when in */ -#define SCMD_UNLOCK_TRAY 0xD4 /* unlock tray when in */ -#define SCMD_CLOSE_TRAY 0xD6 /* load tray in */ - -#define SCMD_RESET 0xFA /* soft reset */ -#define SCMD_GET_STATUS 0x80 -#define SCMD_GET_VERSION 0xCC - -#define SCMD_DATA_READ 0xA0 /* are the same, depend on mode&args */ -#define SCMD_SEEK 0xA0 -#define SCMD_PLAY 0xA0 - -#define SCMD_GET_QINFO 0xA8 - -#define SCMD_SET_MODE 0xC4 -#define SCMD_MODE_PLAY 0xE0 -#define SCMD_MODE_COOKED (0xF8 & ~0x20) -#define SCMD_MODE_RAW 0xF9 -#define SCMD_MODE_x20_BIT 0x20 /* What is it for ? */ - -#define SCMD_SET_VOLUME 0xAE -#define SCMD_PAUSE 0xE0 -#define SCMD_STOP 0xE0 - -#define SCMD_GET_DISK_INFO 0xAA - -/* - * Some standard arguments for SCMD_GET_DISK_INFO. - */ -#define SCMD_GET_1_TRACK 0xA0 /* get the first track information */ -#define SCMD_GET_L_TRACK 0xA1 /* get the last track information */ -#define SCMD_GET_D_SIZE 0xA2 /* get the whole disk information */ - -/* - * Borrowed from hd.c. Allows to optimize multiple port read commands. - */ -#define S_READ_DATA( port, buf, nr ) insb( port, buf, nr ) - -/* - * We assume that there are no audio disks with TOC length more than this - * number (I personally have never seen disks with more than 20 fragments). - */ -#define SJCD_MAX_TRACKS 100 - -struct msf { - unsigned char min; - unsigned char sec; - unsigned char frame; -}; - -struct sjcd_hw_disk_info { - unsigned char track_control; - unsigned char track_no; - unsigned char x, y, z; - union { - unsigned char track_no; - struct msf track_msf; - } un; -}; - -struct sjcd_hw_qinfo { - unsigned char track_control; - unsigned char track_no; - unsigned char x; - struct msf rel; - struct msf abs; -}; - -struct sjcd_play_msf { - struct msf start; - struct msf end; -}; - -struct sjcd_disk_info { - unsigned char first; - unsigned char last; - struct msf disk_length; - struct msf first_track; -}; - -struct sjcd_toc { - unsigned char ctrl_addr; - unsigned char track; - unsigned char point_index; - struct msf track_time; - struct msf disk_time; -}; - -#if defined( SJCD_GATHER_STAT ) - -struct sjcd_stat { - int ticks; - int tticks[ 8 ]; - int idle_ticks; - int start_ticks; - int mode_ticks; - int read_ticks; - int data_ticks; - int stop_ticks; - int stopping_ticks; -}; - -#endif - -#endif diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c deleted file mode 100644 index f77ada933ea0..000000000000 --- a/drivers/cdrom/sonycd535.c +++ /dev/null @@ -1,1689 +0,0 @@ -/* - * Sony CDU-535 interface device driver - * - * This is a modified version of the CDU-31A device driver (see below). - * Changes were made using documentation for the CDU-531 (which Sony - * assures me is very similar to the 535) and partial disassembly of the - * DOS driver. I used Minyard's driver and replaced the CDU-31A - * commands with the CDU-531 commands. This was complicated by a different - * interface protocol with the drive. The driver is still polled. - * - * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec. - * I tried polling without the sony_sleep during the data transfers but - * it did not speed things up any. - * - * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict - * with CDU-31A driver. This is the also the number from the Linux - * Device Driver Registry for the Sony Drive. Hope nobody else is using it. - * - * 1993-08-29 (rgj) remove the configuring of the interface board address - * from the top level configuration, you have to modify it in this file. - * - * 1995-01-26 Made module-capable (Joel Katz ) - * - * 1995-05-20 - * Modified to support CDU-510/515 series - * (Claudio Porfiri) - * Fixed to report verify_area() failures - * (Heiko Eissfeldt ) - * - * 1995-06-01 - * More changes to support CDU-510/515 series - * (Claudio Porfiri) - * - * November 1999 -- Make kernel-parameter implementation work with 2.3.x - * Removed init_module & cleanup_module in favor of - * module_init & module_exit. - * Torben Mathiasen - * - * September 2003 - Fix SMP support by removing cli/sti calls. - * Using spinlocks with a wait_queue instead. - * Felipe Damasio - * - * Things to do: - * - handle errors and status better, put everything into a single word - * - use interrupts (code mostly there, but a big hole still missing) - * - handle multi-session CDs? - * - use DMA? - * - * Known Bugs: - * - - * - * Ken Pizzini (ken@halcyon.com) - * - * Original by: - * Ron Jeppesen (ronj.an@site007.saic.com) - * - * - *------------------------------------------------------------------------ - * Sony CDROM interface device driver. - * - * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above) - * - * Colossians 3:17 - * - * The Sony interface device driver handles Sony interface CDROM - * drives and provides a complete block-level interface as well as an - * ioctl() interface compatible with the Sun (as specified in - * include/linux/cdrom.h). With this interface, CDROMs can be - * accessed and standard audio CDs can be played back normally. - * - * This interface is (unfortunately) a polled interface. This is - * because most Sony interfaces are set up with DMA and interrupts - * disables. Some (like mine) do not even have the capability to - * handle interrupts or DMA. For this reason you will see a bit of - * the following: - * - * snap = jiffies; - * while (jiffies-snap < SONY_JIFFIES_TIMEOUT) - * { - * if (some_condition()) - * break; - * sony_sleep(); - * } - * if (some_condition not met) - * { - * return an_error; - * } - * - * This ugly hack waits for something to happen, sleeping a little - * between every try. (The conditional is written so that jiffies - * wrap-around is handled properly.) - * - * One thing about these drives: They talk in MSF (Minute Second Frame) format. - * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a - * disk. The funny thing is that these are sent to the drive in BCD, but the - * interface wants to see them in decimal. A lot of conversion goes on. - * - * Copyright (C) 1993 Corey Minyard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -# include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REALLY_SLOW_IO -#include -#include -#include - -#include - -#define MAJOR_NR CDU535_CDROM_MAJOR -#include - -#define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */ -#include "sonycd535.h" - -/* - * this is the base address of the interface card for the Sony CDU-535 - * CDROM drive. If your jumpers are set for an address other than - * this one (the default), change the following line to the - * proper address. - */ -#ifndef CDU535_ADDRESS -# define CDU535_ADDRESS 0x340 -#endif -#ifndef CDU535_INTERRUPT -# define CDU535_INTERRUPT 0 -#endif -#ifndef CDU535_HANDLE -# define CDU535_HANDLE "cdu535" -#endif -#ifndef CDU535_MESSAGE_NAME -# define CDU535_MESSAGE_NAME "Sony CDU-535" -#endif - -#define CDU535_BLOCK_SIZE 2048 - -#ifndef MAX_SPINUP_RETRY -# define MAX_SPINUP_RETRY 3 /* 1 is sufficient for most drives... */ -#endif -#ifndef RETRY_FOR_BAD_STATUS -# define RETRY_FOR_BAD_STATUS 100 /* in 10th of second */ -#endif - -#ifndef DEBUG -# define DEBUG 1 -#endif - -/* - * SONY535_BUFFER_SIZE determines the size of internal buffer used - * by the drive. It must be at least 2K and the larger the buffer - * the better the transfer rate. It does however take system memory. - * On my system I get the following transfer rates using dd to read - * 10 Mb off /dev/cdrom. - * - * 8K buffer 43 Kb/sec - * 16K buffer 66 Kb/sec - * 32K buffer 91 Kb/sec - * 64K buffer 111 Kb/sec - * 128K buffer 123 Kb/sec - * 512K buffer 123 Kb/sec - */ -#define SONY535_BUFFER_SIZE (64*1024) - -/* - * if LOCK_DOORS is defined then the eject button is disabled while - * the device is open. - */ -#ifndef NO_LOCK_DOORS -# define LOCK_DOORS -#endif - -static int read_subcode(void); -static void sony_get_toc(void); -static int cdu_open(struct inode *inode, struct file *filp); -static inline unsigned int int_to_bcd(unsigned int val); -static unsigned int bcd_to_int(unsigned int bcd); -static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2], - Byte * response, int n_response, int ignoreStatusBit7); - -/* The base I/O address of the Sony Interface. This is a variable (not a - #define) so it can be easily changed via some future ioctl() */ -static unsigned int sony535_cd_base_io = CDU535_ADDRESS; -module_param(sony535_cd_base_io, int, 0); - -/* - * The following are I/O addresses of the various registers for the drive. The - * comment for the base address also applies here. - */ -static unsigned short select_unit_reg; -static unsigned short result_reg; -static unsigned short command_reg; -static unsigned short read_status_reg; -static unsigned short data_reg; - -static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */ -static struct request_queue *sonycd535_queue; - -static int initialized; /* Has the drive been initialized? */ -static int sony_disc_changed = 1; /* Has the disk been changed - since the last check? */ -static int sony_toc_read; /* Has the table of contents been - read? */ -static unsigned int sony_buffer_size; /* Size in bytes of the read-ahead - buffer. */ -static unsigned int sony_buffer_sectors; /* Size (in 2048 byte records) of - the read-ahead buffer. */ -static unsigned int sony_usage; /* How many processes have the - drive open. */ - -static int sony_first_block = -1; /* First OS block (512 byte) in - the read-ahead buffer */ -static int sony_last_block = -1; /* Last OS block (512 byte) in - the read-ahead buffer */ - -static struct s535_sony_toc *sony_toc; /* Points to the table of - contents. */ - -static struct s535_sony_subcode *last_sony_subcode; /* Points to the last - subcode address read */ -static Byte **sony_buffer; /* Points to the pointers - to the sector buffers */ - -static int sony_inuse; /* is the drive in use? Only one - open at a time allowed */ - -/* - * The audio status uses the values from read subchannel data as specified - * in include/linux/cdrom.h. - */ -static int sony_audio_status = CDROM_AUDIO_NO_STATUS; - -/* - * The following are a hack for pausing and resuming audio play. The drive - * does not work as I would expect it, if you stop it then start it again, - * the drive seeks back to the beginning and starts over. This holds the - * position during a pause so a resume can restart it. It uses the - * audio status variable above to tell if it is paused. - * I just kept the CDU-31A driver behavior rather than using the PAUSE - * command on the CDU-535. - */ -static Byte cur_pos_msf[3]; -static Byte final_pos_msf[3]; - -/* What IRQ is the drive using? 0 if none. */ -static int sony535_irq_used = CDU535_INTERRUPT; - -/* The interrupt handler will wake this queue up when it gets an interrupt. */ -static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait); - - -/* - * This routine returns 1 if the disk has been changed since the last - * check or 0 if it hasn't. Setting flag to 0 resets the changed flag. - */ -static int -cdu535_check_media_change(struct gendisk *disk) -{ - /* if driver is not initialized, always return 0 */ - int retval = initialized ? sony_disc_changed : 0; - sony_disc_changed = 0; - return retval; -} - -static inline void -enable_interrupts(void) -{ -#ifdef USE_IRQ - /* - * This code was taken from cdu31a.c; it will not - * directly work for the cdu535 as written... - */ - curr_control_reg |= ( SONY_ATTN_INT_EN_BIT - | SONY_RES_RDY_INT_EN_BIT - | SONY_DATA_RDY_INT_EN_BIT); - outb(curr_control_reg, sony_cd_control_reg); -#endif -} - -static inline void -disable_interrupts(void) -{ -#ifdef USE_IRQ - /* - * This code was taken from cdu31a.c; it will not - * directly work for the cdu535 as written... - */ - curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT - | SONY_RES_RDY_INT_EN_BIT - | SONY_DATA_RDY_INT_EN_BIT); - outb(curr_control_reg, sony_cd_control_reg); -#endif -} - -static irqreturn_t -cdu535_interrupt(int irq, void *dev_id) -{ - disable_interrupts(); - if (waitqueue_active(&cdu535_irq_wait)) { - wake_up(&cdu535_irq_wait); - return IRQ_HANDLED; - } - printk(CDU535_MESSAGE_NAME - ": Got an interrupt but nothing was waiting\n"); - return IRQ_NONE; -} - - -/* - * Wait a little while. - */ -static inline void -sony_sleep(void) -{ - if (sony535_irq_used <= 0) { /* poll */ - yield(); - } else { /* Interrupt driven */ - DEFINE_WAIT(wait); - - spin_lock_irq(&sonycd535_lock); - enable_interrupts(); - prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE); - spin_unlock_irq(&sonycd535_lock); - schedule(); - finish_wait(&cdu535_irq_wait, &wait); - } -} - -/*------------------start of SONY CDU535 very specific ---------------------*/ - -/**************************************************************************** - * void select_unit( int unit_no ) - * - * Select the specified unit (0-3) so that subsequent commands reference it - ****************************************************************************/ -static void -select_unit(int unit_no) -{ - unsigned int select_mask = ~(1 << unit_no); - outb(select_mask, select_unit_reg); -} - -/*************************************************************************** - * int read_result_reg( Byte *data_ptr ) - * - * Read a result byte from the Sony CDU controller, store in location pointed - * to by data_ptr. Return zero on success, TIME_OUT if we did not receive - * data. - ***************************************************************************/ -static int -read_result_reg(Byte *data_ptr) -{ - unsigned long snap; - int read_status; - - snap = jiffies; - while (jiffies-snap < SONY_JIFFIES_TIMEOUT) { - read_status = inb(read_status_reg); - if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) { -#if DEBUG > 1 - printk(CDU535_MESSAGE_NAME - ": read_result_reg(): readStatReg = 0x%x\n", read_status); -#endif - *data_ptr = inb(result_reg); - return 0; - } else { - sony_sleep(); - } - } - printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n"); - return TIME_OUT; -} - -/**************************************************************************** - * int read_exec_status( Byte status[2] ) - * - * Read the execution status of the last command and put into status. - * Handles reading second status word if available. Returns 0 on success, - * TIME_OUT on failure. - ****************************************************************************/ -static int -read_exec_status(Byte status[2]) -{ - status[1] = 0; - if (read_result_reg(&(status[0])) != 0) - return TIME_OUT; - if ((status[0] & 0x80) != 0) { /* byte two follows */ - if (read_result_reg(&(status[1])) != 0) - return TIME_OUT; - } -#if DEBUG > 1 - printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n", - status[0], status[1]); -#endif - return 0; -} - -/**************************************************************************** - * int check_drive_status( void ) - * - * Check the current drive status. Using this before executing a command - * takes care of the problem of unsolicited drive status-2 messages. - * Add a check of the audio status if we think the disk is playing. - ****************************************************************************/ -static int -check_drive_status(void) -{ - Byte status, e_status[2]; - int CDD, ATN; - Byte cmd; - - select_unit(0); - if (sony_audio_status == CDROM_AUDIO_PLAY) { /* check status */ - outb(SONY535_REQUEST_AUDIO_STATUS, command_reg); - if (read_result_reg(&status) == 0) { - switch (status) { - case 0x0: - break; /* play in progress */ - case 0x1: - break; /* paused */ - case 0x3: /* audio play completed */ - case 0x5: /* play not requested */ - sony_audio_status = CDROM_AUDIO_COMPLETED; - read_subcode(); - break; - case 0x4: /* error during play */ - sony_audio_status = CDROM_AUDIO_ERROR; - break; - } - } - } - /* now check drive status */ - outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg); - if (read_result_reg(&status) != 0) - return TIME_OUT; - -#if DEBUG > 1 - printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status); -#endif - - if (status == 0) - return 0; - - ATN = status & 0xf; - CDD = (status >> 4) & 0xf; - - switch (ATN) { - case 0x0: - break; /* go on to CDD stuff */ - case SONY535_ATN_BUSY: - if (initialized) - printk(CDU535_MESSAGE_NAME " error: drive busy\n"); - return CD_BUSY; - case SONY535_ATN_EJECT_IN_PROGRESS: - printk(CDU535_MESSAGE_NAME " error: eject in progress\n"); - sony_audio_status = CDROM_AUDIO_INVALID; - return CD_BUSY; - case SONY535_ATN_RESET_OCCURRED: - case SONY535_ATN_DISC_CHANGED: - case SONY535_ATN_RESET_AND_DISC_CHANGED: -#if DEBUG > 0 - printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n"); -#endif - sony_disc_changed = 1; - sony_toc_read = 0; - sony_audio_status = CDROM_AUDIO_NO_STATUS; - sony_first_block = -1; - sony_last_block = -1; - if (initialized) { - cmd = SONY535_SPIN_UP; - do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0); - sony_get_toc(); - } - return 0; - default: - printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN); - return CD_BUSY; - } - switch (CDD) { /* the 531 docs are not helpful in decoding this */ - case 0x0: /* just use the values from the DOS driver */ - case 0x2: - case 0xa: - break; /* no error */ - case 0xc: - printk(CDU535_MESSAGE_NAME - ": check_drive_status(): CDD = 0xc! Not properly handled!\n"); - return CD_BUSY; /* ? */ - default: - return CD_BUSY; - } - return 0; -} /* check_drive_status() */ - -/***************************************************************************** - * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2], - * Byte *response, int n_response, int ignore_status_bit7 ) - * - * Generic routine for executing commands. The command and its parameters - * should be placed in the cmd[] array, number of bytes in the command is - * stored in nCmd. The response from the command will be stored in the - * response array. The number of bytes you expect back (excluding status) - * should be passed in n_response. Finally, some - * commands set bit 7 of the return status even when there is no second - * status byte, on these commands set ignoreStatusBit7 TRUE. - * If the command was sent and data received back, then we return 0, - * else we return TIME_OUT. You still have to check the status yourself. - * You should call check_drive_status() before calling this routine - * so that you do not lose notifications of disk changes, etc. - ****************************************************************************/ -static int -do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2], - Byte * response, int n_response, int ignore_status_bit7) -{ - int i; - - /* write out the command */ - for (i = 0; i < n_cmd; i++) - outb(cmd[i], command_reg); - - /* read back the status */ - if (read_result_reg(status) != 0) - return TIME_OUT; - if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) { - /* get second status byte */ - if (read_result_reg(status + 1) != 0) - return TIME_OUT; - } else { - status[1] = 0; - } -#if DEBUG > 2 - printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n", - *cmd, status[0], status[1]); -#endif - - /* do not know about when I should read set of data and when not to */ - if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0) - return 0; - - /* else, read in rest of data */ - for (i = 0; 0 < n_response; n_response--, i++) - if (read_result_reg(response + i) != 0) - return TIME_OUT; - return 0; -} /* do_sony_cmd() */ - -/************************************************************************** - * int set_drive_mode( int mode, Byte status[2] ) - * - * Set the drive mode to the specified value (mode=0 is audio, mode=e0 - * is mode-1 CDROM - **************************************************************************/ -static int -set_drive_mode(int mode, Byte status[2]) -{ - Byte cmd_buff[2]; - Byte ret_buff[1]; - - cmd_buff[0] = SONY535_SET_DRIVE_MODE; - cmd_buff[1] = mode; - return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1); -} - -/*************************************************************************** - * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2], - * Byte *data_buff, int buff_size ) - * - * Read n_blocks of data from the CDROM starting at position params[0:2], - * number of blocks in stored in params[3:5] -- both these are already - * int bcd format. - * Transfer the data into the buffer pointed at by data_buff. buff_size - * gives the number of bytes available in the buffer. - * The routine returns number of bytes read in if successful, otherwise - * it returns one of the standard error returns. - ***************************************************************************/ -static int -seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2], - Byte **buff, int buf_size) -{ - Byte cmd_buff[7]; - int i; - int read_status; - unsigned long snap; - Byte *data_buff; - int sector_count = 0; - - if (buf_size < CDU535_BLOCK_SIZE * n_blocks) - return NO_ROOM; - - set_drive_mode(SONY535_CDROM_DRIVE_MODE, status); - - /* send command to read the data */ - cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1; - for (i = 0; i < 6; i++) - cmd_buff[i + 1] = params[i]; - for (i = 0; i < 7; i++) - outb(cmd_buff[i], command_reg); - - /* read back the data one block at a time */ - while (0 < n_blocks--) { - /* wait for data to be ready */ - int data_valid = 0; - snap = jiffies; - while (jiffies-snap < SONY_JIFFIES_TIMEOUT) { - read_status = inb(read_status_reg); - if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) { - read_exec_status(status); - return BAD_STATUS; - } - if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) { - /* data is ready, read it */ - data_buff = buff[sector_count++]; - for (i = 0; i < CDU535_BLOCK_SIZE; i++) - *data_buff++ = inb(data_reg); /* unrolling this loop does not seem to help */ - data_valid = 1; - break; /* exit the timeout loop */ - } - sony_sleep(); /* data not ready, sleep a while */ - } - if (!data_valid) - return TIME_OUT; /* if we reach this stage */ - } - - /* read all the data, now read the status */ - if ((i = read_exec_status(status)) != 0) - return i; - return CDU535_BLOCK_SIZE * sector_count; -} /* seek_and_read_N_blocks() */ - -/**************************************************************************** - * int request_toc_data( Byte status[2], struct s535_sony_toc *toc ) - * - * Read in the table of contents data. Converts all the bcd data - * into integers in the toc structure. - ****************************************************************************/ -static int -request_toc_data(Byte status[2], struct s535_sony_toc *toc) -{ - int to_status; - int i, j, n_tracks, track_no; - int first_track_num, last_track_num; - Byte cmd_no = 0xb2; - Byte track_address_buffer[5]; - - /* read the fixed portion of the table of contents */ - if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0) - return to_status; - - /* convert the data into integers so we can use them */ - first_track_num = bcd_to_int(toc->first_track_num); - last_track_num = bcd_to_int(toc->last_track_num); - n_tracks = last_track_num - first_track_num + 1; - - /* read each of the track address descriptors */ - for (i = 0; i < n_tracks; i++) { - /* read the descriptor into a temporary buffer */ - for (j = 0; j < 5; j++) { - if (read_result_reg(track_address_buffer + j) != 0) - return TIME_OUT; - if (j == 1) /* need to convert from bcd */ - track_no = bcd_to_int(track_address_buffer[j]); - } - /* copy the descriptor to proper location - sonycd.c just fills */ - memcpy(toc->tracks + i, track_address_buffer, 5); - } - return 0; -} /* request_toc_data() */ - -/*************************************************************************** - * int spin_up_drive( Byte status[2] ) - * - * Spin up the drive (unless it is already spinning). - ***************************************************************************/ -static int -spin_up_drive(Byte status[2]) -{ - Byte cmd; - - /* first see if the drive is already spinning */ - cmd = SONY535_REQUEST_DRIVE_STATUS_1; - if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0) - return TIME_OUT; - if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0) - return 0; /* it's already spinning */ - - /* otherwise, give the spin-up command */ - cmd = SONY535_SPIN_UP; - return do_sony_cmd(&cmd, 1, status, NULL, 0, 0); -} - -/*--------------------end of SONY CDU535 very specific ---------------------*/ - -/* Convert from an integer 0-99 to BCD */ -static inline unsigned int -int_to_bcd(unsigned int val) -{ - int retval; - - retval = (val / 10) << 4; - retval = retval | val % 10; - return retval; -} - - -/* Convert from BCD to an integer from 0-99 */ -static unsigned int -bcd_to_int(unsigned int bcd) -{ - return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f); -} - - -/* - * Convert a logical sector value (like the OS would want to use for - * a block device) to an MSF format. - */ -static void -log_to_msf(unsigned int log, Byte *msf) -{ - log = log + LOG_START_OFFSET; - msf[0] = int_to_bcd(log / 4500); - log = log % 4500; - msf[1] = int_to_bcd(log / 75); - msf[2] = int_to_bcd(log % 75); -} - - -/* - * Convert an MSF format to a logical sector. - */ -static unsigned int -msf_to_log(Byte *msf) -{ - unsigned int log; - - - log = bcd_to_int(msf[2]); - log += bcd_to_int(msf[1]) * 75; - log += bcd_to_int(msf[0]) * 4500; - log = log - LOG_START_OFFSET; - - return log; -} - - -/* - * Take in integer size value and put it into a buffer like - * the drive would want to see a number-of-sector value. - */ -static void -size_to_buf(unsigned int size, Byte *buf) -{ - buf[0] = size / 65536; - size = size % 65536; - buf[1] = size / 256; - buf[2] = size % 256; -} - - -/* - * The OS calls this to perform a read or write operation to the drive. - * Write obviously fail. Reads to a read ahead of sony_buffer_size - * bytes to help speed operations. This especially helps since the OS - * may use 1024 byte blocks and the drive uses 2048 byte blocks. Since most - * data access on a CD is done sequentially, this saves a lot of operations. - */ -static void -do_cdu535_request(request_queue_t * q) -{ - struct request *req; - unsigned int read_size; - int block; - int nsect; - int copyoff; - int spin_up_retry; - Byte params[10]; - Byte status[2]; - Byte cmd[2]; - - while (1) { - req = elv_next_request(q); - if (!req) - return; - - block = req->sector; - nsect = req->nr_sectors; - if (!blk_fs_request(req)) { - end_request(req, 0); - continue; - } - if (rq_data_dir(req) == WRITE) { - end_request(req, 0); - continue; - } - /* - * If the block address is invalid or the request goes beyond - * the end of the media, return an error. - */ - if (sony_toc->lead_out_start_lba <= (block/4)) { - end_request(req, 0); - return; - } - if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) { - end_request(req, 0); - return; - } - while (0 < nsect) { - /* - * If the requested sector is not currently in - * the read-ahead buffer, it must be read in. - */ - if ((block < sony_first_block) || (sony_last_block < block)) { - sony_first_block = (block / 4) * 4; - log_to_msf(block / 4, params); - - /* - * If the full read-ahead would go beyond the end of the media, trim - * it back to read just till the end of the media. - */ - if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) { - sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1; - read_size = sony_toc->lead_out_start_lba - (block / 4); - } else { - sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1; - read_size = sony_buffer_sectors; - } - size_to_buf(read_size, ¶ms[3]); - - /* - * Read the data. If the drive was not spinning, - * spin it up and try some more. - */ - for (spin_up_retry=0 ;; ++spin_up_retry) { - /* This loop has been modified to support the Sony - * CDU-510/515 series, thanks to Claudio Porfiri - * . - */ - /* - * This part is to deal with very slow hardware. We - * try at most MAX_SPINUP_RETRY times to read the same - * block. A check for seek_and_read_N_blocks' result is - * performed; if the result is wrong, the CDROM's engine - * is restarted and the operation is tried again. - */ - /* - * 1995-06-01: The system got problems when downloading - * from Slackware CDROM, the problem seems to be: - * seek_and_read_N_blocks returns BAD_STATUS and we - * should wait for a while before retrying, so a new - * part was added to discriminate the return value from - * seek_and_read_N_blocks for the various cases. - */ - int readStatus = seek_and_read_N_blocks(params, read_size, - status, sony_buffer, (read_size * CDU535_BLOCK_SIZE)); - if (0 <= readStatus) /* Good data; common case, placed first */ - break; - if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) { - /* give up */ - if (readStatus == NO_ROOM) - printk(CDU535_MESSAGE_NAME " No room to read from CD\n"); - else - printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n", - status[0]); - sony_first_block = -1; - sony_last_block = -1; - end_request(req, 0); - return; - } - if (readStatus == BAD_STATUS) { - /* Sleep for a while, then retry */ - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irq(&sonycd535_lock); - schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10); - spin_lock_irq(&sonycd535_lock); - } -#if DEBUG > 0 - printk(CDU535_MESSAGE_NAME - " debug: calling spin up when reading data!\n"); -#endif - cmd[0] = SONY535_SPIN_UP; - do_sony_cmd(cmd, 1, status, NULL, 0, 0); - } - } - /* - * The data is in memory now, copy it to the buffer and advance to the - * next block to read. - */ - copyoff = block - sony_first_block; - memcpy(req->buffer, - sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512); - - block += 1; - nsect -= 1; - req->buffer += 512; - } - - end_request(req, 1); - } -} - -/* - * Read the table of contents from the drive and set sony_toc_read if - * successful. - */ -static void -sony_get_toc(void) -{ - Byte status[2]; - if (!sony_toc_read) { - /* do not call check_drive_status() from here since it can call this routine */ - if (request_toc_data(status, sony_toc) < 0) - return; - sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf); - sony_toc_read = 1; - } -} - - -/* - * Search for a specific track in the table of contents. track is - * passed in bcd format - */ -static int -find_track(int track) -{ - int i; - int num_tracks; - - - num_tracks = bcd_to_int(sony_toc->last_track_num) - - bcd_to_int(sony_toc->first_track_num) + 1; - for (i = 0; i < num_tracks; i++) { - if (sony_toc->tracks[i].track == track) { - return i; - } - } - - return -1; -} - -/* - * Read the subcode and put it int last_sony_subcode for future use. - */ -static int -read_subcode(void) -{ - Byte cmd = SONY535_REQUEST_SUB_Q_DATA; - Byte status[2]; - int dsc_status; - - if (check_drive_status() != 0) - return -EIO; - - if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode, - sizeof(struct s535_sony_subcode), 1)) != 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n", - status[0], dsc_status); - return -EIO; - } - return 0; -} - - -/* - * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If - * the drive is playing, the subchannel needs to be read (since it would be - * changing). If the drive is paused or completed, the subcode information has - * already been stored, just use that. The ioctl call wants things in decimal - * (not BCD), so all the conversions are done. - */ -static int -sony_get_subchnl_info(void __user *arg) -{ - struct cdrom_subchnl schi; - - /* Get attention stuff */ - if (check_drive_status() != 0) - return -EIO; - - sony_get_toc(); - if (!sony_toc_read) { - return -EIO; - } - if (copy_from_user(&schi, arg, sizeof schi)) - return -EFAULT; - - switch (sony_audio_status) { - case CDROM_AUDIO_PLAY: - if (read_subcode() < 0) { - return -EIO; - } - break; - - case CDROM_AUDIO_PAUSED: - case CDROM_AUDIO_COMPLETED: - break; - - case CDROM_AUDIO_NO_STATUS: - schi.cdsc_audiostatus = sony_audio_status; - if (copy_to_user(arg, &schi, sizeof schi)) - return -EFAULT; - return 0; - break; - - case CDROM_AUDIO_INVALID: - case CDROM_AUDIO_ERROR: - default: - return -EIO; - } - - schi.cdsc_audiostatus = sony_audio_status; - schi.cdsc_adr = last_sony_subcode->address; - schi.cdsc_ctrl = last_sony_subcode->control; - schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num); - schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num); - if (schi.cdsc_format == CDROM_MSF) { - schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]); - schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]); - schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]); - - schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]); - schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]); - schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]); - } else if (schi.cdsc_format == CDROM_LBA) { - schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf); - schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf); - } - return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0; -} - - -/* - * The big ugly ioctl handler. - */ -static int -cdu_ioctl(struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) -{ - Byte status[2]; - Byte cmd_buff[10], params[10]; - int i; - int dsc_status; - void __user *argp = (void __user *)arg; - - if (check_drive_status() != 0) - return -EIO; - - switch (cmd) { - case CDROMSTART: /* Spin up the drive */ - if (spin_up_drive(status) < 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n", - status[0]); - return -EIO; - } - return 0; - break; - - case CDROMSTOP: /* Spin down the drive */ - cmd_buff[0] = SONY535_HOLD; - do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); - - /* - * Spin the drive down, ignoring the error if the disk was - * already not spinning. - */ - sony_audio_status = CDROM_AUDIO_NO_STATUS; - cmd_buff[0] = SONY535_SPIN_DOWN; - dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); - if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) || - ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n", - status[0]); - return -EIO; - } - return 0; - break; - - case CDROMPAUSE: /* Pause the drive */ - cmd_buff[0] = SONY535_HOLD; /* CDU-31 driver uses AUDIO_STOP, not pause */ - if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n", - status[0]); - return -EIO; - } - /* Get the current position and save it for resuming */ - if (read_subcode() < 0) { - return -EIO; - } - cur_pos_msf[0] = last_sony_subcode->abs_msf[0]; - cur_pos_msf[1] = last_sony_subcode->abs_msf[1]; - cur_pos_msf[2] = last_sony_subcode->abs_msf[2]; - sony_audio_status = CDROM_AUDIO_PAUSED; - return 0; - break; - - case CDROMRESUME: /* Start the drive after being paused */ - set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status); - - if (sony_audio_status != CDROM_AUDIO_PAUSED) { - return -EINVAL; - } - spin_up_drive(status); - - /* Start the drive at the saved position. */ - cmd_buff[0] = SONY535_PLAY_AUDIO; - cmd_buff[1] = 0; /* play back starting at this address */ - cmd_buff[2] = cur_pos_msf[0]; - cmd_buff[3] = cur_pos_msf[1]; - cmd_buff[4] = cur_pos_msf[2]; - cmd_buff[5] = SONY535_PLAY_AUDIO; - cmd_buff[6] = 2; /* set ending address */ - cmd_buff[7] = final_pos_msf[0]; - cmd_buff[8] = final_pos_msf[1]; - cmd_buff[9] = final_pos_msf[2]; - if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) || - (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n", - status[0]); - return -EIO; - } - sony_audio_status = CDROM_AUDIO_PLAY; - return 0; - break; - - case CDROMPLAYMSF: /* Play starting at the given MSF address. */ - if (copy_from_user(params, argp, 6)) - return -EFAULT; - spin_up_drive(status); - set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status); - - /* The parameters are given in int, must be converted */ - for (i = 0; i < 3; i++) { - cmd_buff[2 + i] = int_to_bcd(params[i]); - cmd_buff[7 + i] = int_to_bcd(params[i + 3]); - } - cmd_buff[0] = SONY535_PLAY_AUDIO; - cmd_buff[1] = 0; /* play back starting at this address */ - /* cmd_buff[2-4] are filled in for loop above */ - cmd_buff[5] = SONY535_PLAY_AUDIO; - cmd_buff[6] = 2; /* set ending address */ - /* cmd_buff[7-9] are filled in for loop above */ - if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) || - (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n", - status[0]); - return -EIO; - } - /* Save the final position for pauses and resumes */ - final_pos_msf[0] = cmd_buff[7]; - final_pos_msf[1] = cmd_buff[8]; - final_pos_msf[2] = cmd_buff[9]; - sony_audio_status = CDROM_AUDIO_PLAY; - return 0; - break; - - case CDROMREADTOCHDR: /* Read the table of contents header */ - { - struct cdrom_tochdr __user *hdr = argp; - struct cdrom_tochdr loc_hdr; - - sony_get_toc(); - if (!sony_toc_read) - return -EIO; - loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num); - loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num); - if (copy_to_user(hdr, &loc_hdr, sizeof *hdr)) - return -EFAULT; - } - return 0; - break; - - case CDROMREADTOCENTRY: /* Read a given table of contents entry */ - { - struct cdrom_tocentry __user *entry = argp; - struct cdrom_tocentry loc_entry; - int track_idx; - Byte *msf_val = NULL; - - sony_get_toc(); - if (!sony_toc_read) { - return -EIO; - } - - if (copy_from_user(&loc_entry, entry, sizeof loc_entry)) - return -EFAULT; - - /* Lead out is handled separately since it is special. */ - if (loc_entry.cdte_track == CDROM_LEADOUT) { - loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ; - loc_entry.cdte_ctrl = sony_toc->control2; - msf_val = sony_toc->lead_out_start_msf; - } else { - track_idx = find_track(int_to_bcd(loc_entry.cdte_track)); - if (track_idx < 0) - return -EINVAL; - loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ; - loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control; - msf_val = sony_toc->tracks[track_idx].track_start_msf; - } - - /* Logical buffer address or MSF format requested? */ - if (loc_entry.cdte_format == CDROM_LBA) { - loc_entry.cdte_addr.lba = msf_to_log(msf_val); - } else if (loc_entry.cdte_format == CDROM_MSF) { - loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val); - loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1)); - loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2)); - } - if (copy_to_user(entry, &loc_entry, sizeof *entry)) - return -EFAULT; - } - return 0; - break; - - case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ - { - struct cdrom_ti ti; - int track_idx; - - sony_get_toc(); - if (!sony_toc_read) - return -EIO; - - if (copy_from_user(&ti, argp, sizeof ti)) - return -EFAULT; - if ((ti.cdti_trk0 < sony_toc->first_track_num) - || (sony_toc->last_track_num < ti.cdti_trk0) - || (ti.cdti_trk1 < ti.cdti_trk0)) { - return -EINVAL; - } - track_idx = find_track(int_to_bcd(ti.cdti_trk0)); - if (track_idx < 0) - return -EINVAL; - params[1] = sony_toc->tracks[track_idx].track_start_msf[0]; - params[2] = sony_toc->tracks[track_idx].track_start_msf[1]; - params[3] = sony_toc->tracks[track_idx].track_start_msf[2]; - /* - * If we want to stop after the last track, use the lead-out - * MSF to do that. - */ - if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) { - log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1, - &(params[4])); - } else { - track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1)); - if (track_idx < 0) - return -EINVAL; - log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1, - &(params[4])); - } - params[0] = 0x03; - - spin_up_drive(status); - - set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status); - - /* Start the drive at the saved position. */ - cmd_buff[0] = SONY535_PLAY_AUDIO; - cmd_buff[1] = 0; /* play back starting at this address */ - cmd_buff[2] = params[1]; - cmd_buff[3] = params[2]; - cmd_buff[4] = params[3]; - cmd_buff[5] = SONY535_PLAY_AUDIO; - cmd_buff[6] = 2; /* set ending address */ - cmd_buff[7] = params[4]; - cmd_buff[8] = params[5]; - cmd_buff[9] = params[6]; - if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) || - (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n", - status[0]); - printk("... Params: %x %x %x %x %x %x %x\n", - params[0], params[1], params[2], - params[3], params[4], params[5], params[6]); - return -EIO; - } - /* Save the final position for pauses and resumes */ - final_pos_msf[0] = params[4]; - final_pos_msf[1] = params[5]; - final_pos_msf[2] = params[6]; - sony_audio_status = CDROM_AUDIO_PLAY; - return 0; - } - - case CDROMSUBCHNL: /* Get subchannel info */ - return sony_get_subchnl_info(argp); - - case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */ - { - struct cdrom_volctrl volctrl; - - if (copy_from_user(&volctrl, argp, sizeof volctrl)) - return -EFAULT; - cmd_buff[0] = SONY535_SET_VOLUME; - cmd_buff[1] = volctrl.channel0; - cmd_buff[2] = volctrl.channel1; - if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n", - status[0]); - return -EIO; - } - } - return 0; - - case CDROMEJECT: /* Eject the drive */ - cmd_buff[0] = SONY535_STOP; - do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); - cmd_buff[0] = SONY535_SPIN_DOWN; - do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); - - sony_audio_status = CDROM_AUDIO_INVALID; - cmd_buff[0] = SONY535_EJECT_CADDY; - if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n", - status[0]); - return -EIO; - } - return 0; - break; - - default: - return -EINVAL; - } -} - - -/* - * Open the drive for operations. Spin the drive up and read the table of - * contents if these have not already been done. - */ -static int -cdu_open(struct inode *inode, - struct file *filp) -{ - Byte status[2], cmd_buff[2]; - - if (sony_inuse) - return -EBUSY; - if (check_drive_status() != 0) - return -EIO; - sony_inuse = 1; - - if (spin_up_drive(status) != 0) { - printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n", - status[0]); - sony_inuse = 0; - return -EIO; - } - sony_get_toc(); - if (!sony_toc_read) { - cmd_buff[0] = SONY535_SPIN_DOWN; - do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); - sony_inuse = 0; - return -EIO; - } - check_disk_change(inode->i_bdev); - sony_usage++; - -#ifdef LOCK_DOORS - /* disable the eject button while mounted */ - cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON; - do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0); -#endif - - return 0; -} - - -/* - * Close the drive. Spin it down if no task is using it. The spin - * down will fail if playing audio, so audio play is OK. - */ -static int -cdu_release(struct inode *inode, - struct file *filp) -{ - Byte status[2], cmd_no; - - sony_inuse = 0; - - if (0 < sony_usage) { - sony_usage--; - } - if (sony_usage == 0) { - check_drive_status(); - - if (sony_audio_status != CDROM_AUDIO_PLAY) { - cmd_no = SONY535_SPIN_DOWN; - do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0); - } -#ifdef LOCK_DOORS - /* enable the eject button after umount */ - cmd_no = SONY535_ENABLE_EJECT_BUTTON; - do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0); -#endif - } - return 0; -} - -static struct block_device_operations cdu_fops = -{ - .owner = THIS_MODULE, - .open = cdu_open, - .release = cdu_release, - .ioctl = cdu_ioctl, - .media_changed = cdu535_check_media_change, -}; - -static struct gendisk *cdu_disk; - -/* - * Initialize the driver. - */ -static int __init sony535_init(void) -{ - struct s535_sony_drive_config drive_config; - Byte cmd_buff[3]; - Byte ret_buff[2]; - Byte status[2]; - unsigned long snap; - int got_result = 0; - int tmp_irq; - int i; - int err; - - /* Setting the base I/O address to 0 will disable it. */ - if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0)) - return 0; - - /* Set up all the register locations */ - result_reg = sony535_cd_base_io; - command_reg = sony535_cd_base_io; - data_reg = sony535_cd_base_io + 1; - read_status_reg = sony535_cd_base_io + 2; - select_unit_reg = sony535_cd_base_io + 3; - -#ifndef USE_IRQ - sony535_irq_used = 0; /* polling only until this is ready... */ -#endif - /* we need to poll until things get initialized */ - tmp_irq = sony535_irq_used; - sony535_irq_used = 0; - -#if DEBUG > 0 - printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n", - sony535_cd_base_io); -#endif - /* look for the CD-ROM, follows the procedure in the DOS driver */ - inb(select_unit_reg); - /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */ - schedule_timeout_interruptible((HZ+17)*40/18); - inb(result_reg); - - outb(0, read_status_reg); /* does a reset? */ - snap = jiffies; - while (jiffies-snap < SONY_JIFFIES_TIMEOUT) { - select_unit(0); - if (inb(result_reg) != 0xff) { - got_result = 1; - break; - } - sony_sleep(); - } - - if (!got_result || check_drive_status() == TIME_OUT) - goto Enodev; - - /* CD-ROM drive responded -- get the drive configuration */ - cmd_buff[0] = SONY535_INQUIRY; - if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0) - goto Enodev; - - /* was able to get the configuration, - * set drive mode as rest of init - */ -#if DEBUG > 0 - /* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */ - if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 ) - printk(CDU535_MESSAGE_NAME - "Inquiry command returned status = 0x%x\n", status[0]); -#endif - /* now ready to use interrupts, if available */ - sony535_irq_used = tmp_irq; - - /* A negative sony535_irq_used will attempt an autoirq. */ - if (sony535_irq_used < 0) { - unsigned long irq_mask, delay; - - irq_mask = probe_irq_on(); - enable_interrupts(); - outb(0, read_status_reg); /* does a reset? */ - delay = jiffies + HZ/10; - while (time_before(jiffies, delay)) ; - - sony535_irq_used = probe_irq_off(irq_mask); - disable_interrupts(); - } - if (sony535_irq_used > 0) { - if (request_irq(sony535_irq_used, cdu535_interrupt, - IRQF_DISABLED, CDU535_HANDLE, NULL)) { - printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME - " driver; polling instead.\n", sony535_irq_used); - sony535_irq_used = 0; - } - } - cmd_buff[0] = SONY535_SET_DRIVE_MODE; - cmd_buff[1] = 0x0; /* default audio */ - if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0) - goto Enodev_irq; - - /* set the drive mode successful, we are set! */ - sony_buffer_size = SONY535_BUFFER_SIZE; - sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE; - - printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s", - drive_config.vendor_id, - drive_config.product_id, - drive_config.product_rev_level); - printk(" base address %03X, ", sony535_cd_base_io); - if (tmp_irq > 0) - printk("IRQ%d, ", tmp_irq); - printk("using %d byte buffer\n", sony_buffer_size); - - if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) { - err = -EIO; - goto out1; - } - sonycd535_queue = blk_init_queue(do_cdu535_request, &sonycd535_lock); - if (!sonycd535_queue) { - err = -ENOMEM; - goto out1a; - } - - blk_queue_hardsect_size(sonycd535_queue, CDU535_BLOCK_SIZE); - sony_toc = kmalloc(sizeof(struct s535_sony_toc), GFP_KERNEL); - err = -ENOMEM; - if (!sony_toc) - goto out2; - last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL); - if (!last_sony_subcode) - goto out3; - sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL); - if (!sony_buffer) - goto out4; - for (i = 0; i < sony_buffer_sectors; i++) { - sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL); - if (!sony_buffer[i]) { - while (--i>=0) - kfree(sony_buffer[i]); - goto out5; - } - } - initialized = 1; - - cdu_disk = alloc_disk(1); - if (!cdu_disk) - goto out6; - cdu_disk->major = MAJOR_NR; - cdu_disk->first_minor = 0; - cdu_disk->fops = &cdu_fops; - sprintf(cdu_disk->disk_name, "cdu"); - - if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) { - printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n", - sony535_cd_base_io); - goto out7; - } - cdu_disk->queue = sonycd535_queue; - add_disk(cdu_disk); - return 0; - -out7: - put_disk(cdu_disk); -out6: - for (i = 0; i < sony_buffer_sectors; i++) - kfree(sony_buffer[i]); -out5: - kfree(sony_buffer); -out4: - kfree(last_sony_subcode); -out3: - kfree(sony_toc); -out2: - blk_cleanup_queue(sonycd535_queue); -out1a: - unregister_blkdev(MAJOR_NR, CDU535_HANDLE); -out1: - if (sony535_irq_used) - free_irq(sony535_irq_used, NULL); - return err; -Enodev_irq: - if (sony535_irq_used) - free_irq(sony535_irq_used, NULL); -Enodev: - printk("Did not find a " CDU535_MESSAGE_NAME " drive\n"); - return -EIO; -} - -#ifndef MODULE - -/* - * accept "kernel command line" parameters - * (added by emoenke@gwdg.de) - * - * use: tell LILO: - * sonycd535=0x320 - * - * the address value has to be the existing CDROM port address. - */ -static int __init -sonycd535_setup(char *strings) -{ - int ints[3]; - (void)get_options(strings, ARRAY_SIZE(ints), ints); - /* if IRQ change and default io base desired, - * then call with io base of 0 - */ - if (ints[0] > 0) - if (ints[1] != 0) - sony535_cd_base_io = ints[1]; - if (ints[0] > 1) - sony535_irq_used = ints[2]; - if ((strings != NULL) && (*strings != '\0')) - printk(CDU535_MESSAGE_NAME - ": Warning: Unknown interface type: %s\n", strings); - - return 1; -} - -__setup("sonycd535=", sonycd535_setup); - -#endif /* MODULE */ - -static void __exit -sony535_exit(void) -{ - int i; - - release_region(sony535_cd_base_io, 4); - for (i = 0; i < sony_buffer_sectors; i++) - kfree(sony_buffer[i]); - kfree(sony_buffer); - kfree(last_sony_subcode); - kfree(sony_toc); - del_gendisk(cdu_disk); - put_disk(cdu_disk); - blk_cleanup_queue(sonycd535_queue); - if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL) - printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n"); - else - printk(KERN_INFO CDU535_HANDLE " module released\n"); -} - -module_init(sony535_init); -module_exit(sony535_exit); - - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR); diff --git a/drivers/cdrom/sonycd535.h b/drivers/cdrom/sonycd535.h deleted file mode 100644 index 5dea1ef168d6..000000000000 --- a/drivers/cdrom/sonycd535.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef SONYCD535_H -#define SONYCD535_H - -/* - * define all the commands recognized by the CDU-531/5 - */ -#define SONY535_REQUEST_DRIVE_STATUS_1 (0x80) -#define SONY535_REQUEST_SENSE (0x82) -#define SONY535_REQUEST_DRIVE_STATUS_2 (0x84) -#define SONY535_REQUEST_ERROR_STATUS (0x86) -#define SONY535_REQUEST_AUDIO_STATUS (0x88) -#define SONY535_INQUIRY (0x8a) - -#define SONY535_SET_INACTIVITY_TIME (0x90) - -#define SONY535_SEEK_AND_READ_N_BLOCKS_1 (0xa0) -#define SONY535_SEEK_AND_READ_N_BLOCKS_2 (0xa4) -#define SONY535_PLAY_AUDIO (0xa6) - -#define SONY535_REQUEST_DISC_CAPACITY (0xb0) -#define SONY535_REQUEST_TOC_DATA (0xb2) -#define SONY535_REQUEST_SUB_Q_DATA (0xb4) -#define SONY535_REQUEST_ISRC (0xb6) -#define SONY535_REQUEST_UPC_EAN (0xb8) - -#define SONY535_SET_DRIVE_MODE (0xc0) -#define SONY535_REQUEST_DRIVE_MODE (0xc2) -#define SONY535_SET_RETRY_COUNT (0xc4) - -#define SONY535_DIAGNOSTIC_1 (0xc6) -#define SONY535_DIAGNOSTIC_4 (0xcc) -#define SONY535_DIAGNOSTIC_5 (0xce) - -#define SONY535_EJECT_CADDY (0xd0) -#define SONY535_DISABLE_EJECT_BUTTON (0xd2) -#define SONY535_ENABLE_EJECT_BUTTON (0xd4) - -#define SONY535_HOLD (0xe0) -#define SONY535_AUDIO_PAUSE_ON_OFF (0xe2) -#define SONY535_SET_VOLUME (0xe8) - -#define SONY535_STOP (0xf0) -#define SONY535_SPIN_UP (0xf2) -#define SONY535_SPIN_DOWN (0xf4) - -#define SONY535_CLEAR_PARAMETERS (0xf6) -#define SONY535_CLEAR_ENDING_ADDRESS (0xf8) - -/* - * define some masks - */ -#define SONY535_DATA_NOT_READY_BIT (0x1) -#define SONY535_RESULT_NOT_READY_BIT (0x2) - -/* - * drive status 1 - */ -#define SONY535_STATUS1_COMMAND_ERROR (0x1) -#define SONY535_STATUS1_DATA_ERROR (0x2) -#define SONY535_STATUS1_SEEK_ERROR (0x4) -#define SONY535_STATUS1_DISC_TYPE_ERROR (0x8) -#define SONY535_STATUS1_NOT_SPINNING (0x10) -#define SONY535_STATUS1_EJECT_BUTTON_PRESSED (0x20) -#define SONY535_STATUS1_CADDY_NOT_INSERTED (0x40) -#define SONY535_STATUS1_BYTE_TWO_FOLLOWS (0x80) - -/* - * drive status 2 - */ -#define SONY535_CDD_LOADING_ERROR (0x7) -#define SONY535_CDD_NO_DISC (0x8) -#define SONY535_CDD_UNLOADING_ERROR (0x9) -#define SONY535_CDD_CADDY_NOT_INSERTED (0xd) -#define SONY535_ATN_RESET_OCCURRED (0x2) -#define SONY535_ATN_DISC_CHANGED (0x4) -#define SONY535_ATN_RESET_AND_DISC_CHANGED (0x6) -#define SONY535_ATN_EJECT_IN_PROGRESS (0xe) -#define SONY535_ATN_BUSY (0xf) - -/* - * define some parameters - */ -#define SONY535_AUDIO_DRIVE_MODE (0) -#define SONY535_CDROM_DRIVE_MODE (0xe0) - -#define SONY535_PLAY_OP_PLAYBACK (0) -#define SONY535_PLAY_OP_ENTER_HOLD (1) -#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR (2) -#define SONY535_PLAY_OP_SCAN_FORWARD (3) -#define SONY535_PLAY_OP_SCAN_BACKWARD (4) - -/* - * convert from msf format to block number - */ -#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f)) -#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2]) - -/* - * error return values from the doSonyCmd() routines - */ -#define TIME_OUT (-1) -#define NO_CDROM (-2) -#define BAD_STATUS (-3) -#define CD_BUSY (-4) -#define NOT_DATA_CD (-5) -#define NO_ROOM (-6) - -#define LOG_START_OFFSET 150 /* Offset of first logical sector */ - -#define SONY_JIFFIES_TIMEOUT (5*HZ) /* Maximum time - the drive will wait/try for an - operation */ -#define SONY_READY_RETRIES (50000) /* How many times to retry a - spin waiting for a register - to come ready */ -#define SONY535_FAST_POLLS (10000) /* how many times recheck - status waiting for a data - to become ready */ - -typedef unsigned char Byte; - -/* - * This is the complete status returned from the drive configuration request - * command. - */ -struct s535_sony_drive_config -{ - char vendor_id[8]; - char product_id[16]; - char product_rev_level[4]; -}; - -/* The following is returned from the request sub-q data command */ -struct s535_sony_subcode -{ - unsigned char address :4; - unsigned char control :4; - unsigned char track_num; - unsigned char index_num; - unsigned char rel_msf[3]; - unsigned char abs_msf[3]; -}; - -struct s535_sony_disc_capacity -{ - Byte mFirstTrack, sFirstTrack, fFirstTrack; - Byte mLeadOut, sLeadOut, fLeadOut; -}; - -/* - * The following is returned from the request TOC (Table Of Contents) command. - * (last_track_num-first_track_num+1) values are valid in tracks. - */ -struct s535_sony_toc -{ - unsigned char reserved0 :4; - unsigned char control0 :4; - unsigned char point0; - unsigned char first_track_num; - unsigned char reserved0a; - unsigned char reserved0b; - unsigned char reserved1 :4; - unsigned char control1 :4; - unsigned char point1; - unsigned char last_track_num; - unsigned char dummy1; - unsigned char dummy2; - unsigned char reserved2 :4; - unsigned char control2 :4; - unsigned char point2; - unsigned char lead_out_start_msf[3]; - struct - { - unsigned char reserved :4; - unsigned char control :4; - unsigned char track; - unsigned char track_start_msf[3]; - } tracks[100]; - - unsigned int lead_out_start_lba; -}; - -#endif /* SONYCD535_H */ From 72d3a38ee083a96c09032e608a4c7e047ce26760 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jul 2007 09:40:44 +0200 Subject: [PATCH 395/551] unexport bio_{,un}map_user bio_{,un}map_user no longer have any modular users. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- fs/bio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/bio.c b/fs/bio.c index 093345f00128..33e46340a766 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1223,8 +1223,6 @@ EXPORT_SYMBOL(bio_hw_segments); EXPORT_SYMBOL(bio_add_page); EXPORT_SYMBOL(bio_add_pc_page); EXPORT_SYMBOL(bio_get_nr_vecs); -EXPORT_SYMBOL(bio_map_user); -EXPORT_SYMBOL(bio_unmap_user); EXPORT_SYMBOL(bio_map_kern); EXPORT_SYMBOL(bio_pair_release); EXPORT_SYMBOL(bio_split); From c66ab6fa705e1b2887a6d9246b798bdc526839e2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 21:17:17 +0200 Subject: [PATCH 396/551] splice: abstract out actor data For direct splicing (or private splicing), the output may not be a file. So abstract out the handling into a specified actor function and put the data in the splice_desc structure earlier, so we can build on top of that. This is the first step in better splice handling for drivers, and also for implementing vmsplice _to_ user memory. Signed-off-by: Jens Axboe --- fs/ocfs2/file.c | 9 +++- fs/splice.c | 99 +++++++++++++++++++++++++++------------ include/linux/pipe_fs_i.h | 10 ++-- 3 files changed, 83 insertions(+), 35 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index ac6c96431bbc..93565c03d315 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1636,9 +1636,14 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe, int ret, err; struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; + struct splice_desc sd = { + .total_len = len, + .flags = flags, + .pos = *ppos, + .file = out, + }; - ret = __splice_from_pipe(pipe, out, ppos, len, flags, - ocfs2_splice_write_actor); + ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor); if (ret > 0) { *ppos += ret; diff --git a/fs/splice.c b/fs/splice.c index e7d7080de2f9..68f6328236a6 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -668,31 +668,24 @@ out_ret: * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ -ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, - struct file *out, loff_t *ppos, size_t len, - unsigned int flags, splice_actor *actor) +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, + splice_actor *actor) { int ret, do_wakeup, err; - struct splice_desc sd; ret = 0; do_wakeup = 0; - sd.total_len = len; - sd.flags = flags; - sd.file = out; - sd.pos = *ppos; - for (;;) { if (pipe->nrbufs) { struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; const struct pipe_buf_operations *ops = buf->ops; - sd.len = buf->len; - if (sd.len > sd.total_len) - sd.len = sd.total_len; + sd->len = buf->len; + if (sd->len > sd->total_len) + sd->len = sd->total_len; - err = actor(pipe, buf, &sd); + err = actor(pipe, buf, sd); if (err <= 0) { if (!ret && err != -ENODATA) ret = err; @@ -704,10 +697,10 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, buf->offset += err; buf->len -= err; - sd.len -= err; - sd.pos += err; - sd.total_len -= err; - if (sd.len) + sd->len -= err; + sd->pos += err; + sd->total_len -= err; + if (sd->len) continue; if (!buf->len) { @@ -719,7 +712,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, do_wakeup = 1; } - if (!sd.total_len) + if (!sd->total_len) break; } @@ -732,7 +725,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, break; } - if (flags & SPLICE_F_NONBLOCK) { + if (sd->flags & SPLICE_F_NONBLOCK) { if (!ret) ret = -EAGAIN; break; @@ -772,6 +765,12 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, { ssize_t ret; struct inode *inode = out->f_mapping->host; + struct splice_desc sd = { + .total_len = len, + .flags = flags, + .pos = *ppos, + .file = out, + }; /* * The actor worker might be calling ->prepare_write and @@ -780,7 +779,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, * pipe->inode, we have to order lock acquiry here. */ inode_double_lock(inode, pipe->inode); - ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); + ret = __splice_from_pipe(pipe, &sd, actor); inode_double_unlock(inode, pipe->inode); return ret; @@ -804,6 +803,12 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, { struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; + struct splice_desc sd = { + .total_len = len, + .flags = flags, + .pos = *ppos, + .file = out, + }; ssize_t ret; int err; @@ -811,7 +816,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, if (unlikely(err)) return err; - ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); + ret = __splice_from_pipe(pipe, &sd, pipe_to_file); if (ret > 0) { unsigned long nr_pages; @@ -956,14 +961,17 @@ static long do_splice_to(struct file *in, loff_t *ppos, return in->f_op->splice_read(in, ppos, pipe, len, flags); } -long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - size_t len, unsigned int flags) +/* + * Splices from an input file to an actor, using a 'direct' pipe. + */ +ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, + splice_direct_actor *actor) { struct pipe_inode_info *pipe; long ret, bytes; - loff_t out_off; umode_t i_mode; - int i; + size_t len; + int i, flags; /* * We require the input being a regular file, as we don't want to @@ -999,7 +1007,13 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, */ ret = 0; bytes = 0; - out_off = 0; + len = sd->total_len; + flags = sd->flags; + + /* + * Don't block on output, we have to drain the direct pipe. + */ + sd->flags &= ~SPLICE_F_NONBLOCK; while (len) { size_t read_len, max_read_len; @@ -1009,19 +1023,19 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, */ max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); - ret = do_splice_to(in, ppos, pipe, max_read_len, flags); + ret = do_splice_to(in, &sd->pos, pipe, max_read_len, flags); if (unlikely(ret < 0)) goto out_release; read_len = ret; + sd->total_len = read_len; /* * NOTE: nonblocking mode only applies to the input. We * must not do the output in nonblocking mode as then we * could get stuck data in the internal pipe: */ - ret = do_splice_from(pipe, out, &out_off, read_len, - flags & ~SPLICE_F_NONBLOCK); + ret = actor(pipe, sd); if (unlikely(ret < 0)) goto out_release; @@ -1066,6 +1080,33 @@ out_release: return bytes; return ret; + +} +EXPORT_SYMBOL(splice_direct_to_actor); + +static int direct_splice_actor(struct pipe_inode_info *pipe, + struct splice_desc *sd) +{ + struct file *file = sd->file; + + return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags); +} + +long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, + size_t len, unsigned int flags) +{ + struct splice_desc sd = { + .len = len, + .total_len = len, + .flags = flags, + .pos = *ppos, + .file = out, + }; + size_t ret; + + ret = splice_direct_to_actor(in, &sd, direct_splice_actor); + *ppos = sd.pos; + return ret; } /* diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index c8884f971228..883ba9b78d3f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -94,13 +94,15 @@ struct splice_desc { typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, struct splice_desc *); +typedef int (splice_direct_actor)(struct pipe_inode_info *, + struct splice_desc *); extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int, splice_actor *); - -extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int, - splice_actor *); +extern ssize_t __splice_from_pipe(struct pipe_inode_info *, + struct splice_desc *, splice_actor *); +extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, + splice_direct_actor *); #endif From 6a14b90bb6bc7cd83e2a444bf457a2ea645cbfe7 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 14 Jun 2007 13:08:55 +0200 Subject: [PATCH 397/551] vmsplice: add vmsplice-to-user support A bit of a cheat, it actually just copies the data to userspace. But this makes the interface nice and symmetric and enables people to build on splice, with room for future improvement in performance. Signed-off-by: Jens Axboe --- fs/ocfs2/file.c | 2 +- fs/splice.c | 178 ++++++++++++++++++++++++++++++++------ include/linux/pipe_fs_i.h | 8 +- 3 files changed, 158 insertions(+), 30 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 93565c03d315..222f108ee454 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1640,7 +1640,7 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe, .total_len = len, .flags = flags, .pos = *ppos, - .file = out, + .u.file = out, }; ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor); diff --git a/fs/splice.c b/fs/splice.c index 68f6328236a6..13846f723d72 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -528,7 +528,7 @@ EXPORT_SYMBOL(generic_file_splice_read); static int pipe_to_sendpage(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd) { - struct file *file = sd->file; + struct file *file = sd->u.file; loff_t pos = sd->pos; int ret, more; @@ -566,7 +566,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd) { - struct file *file = sd->file; + struct file *file = sd->u.file; struct address_space *mapping = file->f_mapping; unsigned int offset, this_len; struct page *page; @@ -769,7 +769,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, .total_len = len, .flags = flags, .pos = *ppos, - .file = out, + .u.file = out, }; /* @@ -807,7 +807,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, .total_len = len, .flags = flags, .pos = *ppos, - .file = out, + .u.file = out, }; ssize_t ret; int err; @@ -1087,7 +1087,7 @@ EXPORT_SYMBOL(splice_direct_to_actor); static int direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) { - struct file *file = sd->file; + struct file *file = sd->u.file; return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags); } @@ -1100,7 +1100,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, .total_len = len, .flags = flags, .pos = *ppos, - .file = out, + .u.file = out, }; size_t ret; @@ -1289,28 +1289,131 @@ static int get_iovec_page_array(const struct iovec __user *iov, return error; } +static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf, + struct splice_desc *sd) +{ + char *src; + int ret; + + ret = buf->ops->pin(pipe, buf); + if (unlikely(ret)) + return ret; + + /* + * See if we can use the atomic maps, by prefaulting in the + * pages and doing an atomic copy + */ + if (!fault_in_pages_writeable(sd->u.userptr, sd->len)) { + src = buf->ops->map(pipe, buf, 1); + ret = __copy_to_user_inatomic(sd->u.userptr, src + buf->offset, + sd->len); + buf->ops->unmap(pipe, buf, src); + if (!ret) { + ret = sd->len; + goto out; + } + } + + /* + * No dice, use slow non-atomic map and copy + */ + src = buf->ops->map(pipe, buf, 0); + + ret = sd->len; + if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len)) + ret = -EFAULT; + +out: + if (ret > 0) + sd->u.userptr += ret; + buf->ops->unmap(pipe, buf, src); + return ret; +} + +/* + * For lack of a better implementation, implement vmsplice() to userspace + * as a simple copy of the pipes pages to the user iov. + */ +static long vmsplice_to_user(struct file *file, const struct iovec __user *iov, + unsigned long nr_segs, unsigned int flags) +{ + struct pipe_inode_info *pipe; + struct splice_desc sd; + ssize_t size; + int error; + long ret; + + pipe = pipe_info(file->f_path.dentry->d_inode); + if (!pipe) + return -EBADF; + + if (pipe->inode) + mutex_lock(&pipe->inode->i_mutex); + + error = ret = 0; + while (nr_segs) { + void __user *base; + size_t len; + + /* + * Get user address base and length for this iovec. + */ + error = get_user(base, &iov->iov_base); + if (unlikely(error)) + break; + error = get_user(len, &iov->iov_len); + if (unlikely(error)) + break; + + /* + * Sanity check this iovec. 0 read succeeds. + */ + if (unlikely(!len)) + break; + if (unlikely(!base)) { + error = -EFAULT; + break; + } + + sd.len = 0; + sd.total_len = len; + sd.flags = flags; + sd.u.userptr = base; + sd.pos = 0; + + size = __splice_from_pipe(pipe, &sd, pipe_to_user); + if (size < 0) { + if (!ret) + ret = size; + + break; + } + + ret += size; + + if (size < len) + break; + + nr_segs--; + iov++; + } + + if (pipe->inode) + mutex_unlock(&pipe->inode->i_mutex); + + if (!ret) + ret = error; + + return ret; +} + /* * vmsplice splices a user address range into a pipe. It can be thought of * as splice-from-memory, where the regular splice is splice-from-file (or * to file). In both cases the output is a pipe, naturally. - * - * Note that vmsplice only supports splicing _from_ user memory to a pipe, - * not the other way around. Splicing from user memory is a simple operation - * that can be supported without any funky alignment restrictions or nasty - * vm tricks. We simply map in the user memory and fill them into a pipe. - * The reverse isn't quite as easy, though. There are two possible solutions - * for that: - * - * - memcpy() the data internally, at which point we might as well just - * do a regular read() on the buffer anyway. - * - Lots of nasty vm tricks, that are neither fast nor flexible (it - * has restriction limitations on both ends of the pipe). - * - * Alas, it isn't here. - * */ -static long do_vmsplice(struct file *file, const struct iovec __user *iov, - unsigned long nr_segs, unsigned int flags) +static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, + unsigned long nr_segs, unsigned int flags) { struct pipe_inode_info *pipe; struct page *pages[PIPE_BUFFERS]; @@ -1325,10 +1428,6 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, pipe = pipe_info(file->f_path.dentry->d_inode); if (!pipe) return -EBADF; - if (unlikely(nr_segs > UIO_MAXIOV)) - return -EINVAL; - else if (unlikely(!nr_segs)) - return 0; spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, flags & SPLICE_F_GIFT); @@ -1338,6 +1437,22 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, return splice_to_pipe(pipe, &spd); } +/* + * Note that vmsplice only really supports true splicing _from_ user memory + * to a pipe, not the other way around. Splicing from user memory is a simple + * operation that can be supported without any funky alignment restrictions + * or nasty vm tricks. We simply map in the user memory and fill them into + * a pipe. The reverse isn't quite as easy, though. There are two possible + * solutions for that: + * + * - memcpy() the data internally, at which point we might as well just + * do a regular read() on the buffer anyway. + * - Lots of nasty vm tricks, that are neither fast nor flexible (it + * has restriction limitations on both ends of the pipe). + * + * Currently we punt and implement it as a normal copy, see pipe_to_user(). + * + */ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, unsigned long nr_segs, unsigned int flags) { @@ -1345,11 +1460,18 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, long error; int fput; + if (unlikely(nr_segs > UIO_MAXIOV)) + return -EINVAL; + else if (unlikely(!nr_segs)) + return 0; + error = -EBADF; file = fget_light(fd, &fput); if (file) { if (file->f_mode & FMODE_WRITE) - error = do_vmsplice(file, iov, nr_segs, flags); + error = vmsplice_to_pipe(file, iov, nr_segs, flags); + else if (file->f_mode & FMODE_READ) + error = vmsplice_to_user(file, iov, nr_segs, flags); fput_light(file, fput); } diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 883ba9b78d3f..6e7bfc125425 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -88,7 +88,13 @@ int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); struct splice_desc { unsigned int len, total_len; /* current and remaining length */ unsigned int flags; /* splice flags */ - struct file *file; /* file to read/write */ + /* + * actor() private data + */ + union { + void __user *userptr; /* memory to write to */ + struct file *file; /* file to read/write */ + } u; loff_t pos; /* file position */ }; From 534f2aaa6ab07cd71164180bc958a7dcde41db11 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 1 Jun 2007 14:52:37 +0200 Subject: [PATCH 398/551] sys_sendfile: switch to using ->splice_read, if available This patch makes sendfile prefer to use ->splice_read(), if it's available in the file_operations structure. Signed-off-by: Jens Axboe --- fs/read_write.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 4d03008f015b..47da8a4a0fbe 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "read_write.h" #include @@ -25,7 +26,7 @@ const struct file_operations generic_ro_fops = { .read = do_sync_read, .aio_read = generic_file_aio_read, .mmap = generic_file_readonly_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; EXPORT_SYMBOL(generic_ro_fops); @@ -708,7 +709,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, struct inode * in_inode, * out_inode; loff_t pos; ssize_t retval; - int fput_needed_in, fput_needed_out; + int fput_needed_in, fput_needed_out, fl; /* * Get input file, and verify that it is ok.. @@ -723,7 +724,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, in_inode = in_file->f_path.dentry->d_inode; if (!in_inode) goto fput_in; - if (!in_file->f_op || !in_file->f_op->sendfile) + if (!in_file->f_op || (!in_file->f_op->sendfile && + !in_file->f_op->splice_read)) goto fput_in; retval = -ESPIPE; if (!ppos) @@ -776,7 +778,21 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, count = max - pos; } - retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); + if (in_file->f_op->splice_read) { + fl = 0; +#if 0 + /* + * We need to debate whether we can enable this or not. The + * man page documents EAGAIN return for the output at least, + * and the application is arguably buggy if it doesn't expect + * EAGAIN on a non-blocking file descriptor. + */ + if (in_file->f_flags & O_NONBLOCK) + fl = SPLICE_F_NONBLOCK; +#endif + retval = do_splice_direct(in_file, ppos, out_file, count, fl); + } else + retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); if (retval > 0) { add_rchar(current, retval); From 5ffc4ef45b3b0a57872f631b4e4ceb8ace0d7496 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 1 Jun 2007 11:49:19 +0200 Subject: [PATCH 399/551] sendfile: remove .sendfile from filesystems that use generic_file_sendfile() They can use generic_file_splice_read() instead. Since sys_sendfile() now prefers that, there should be no change in behaviour. Signed-off-by: Jens Axboe --- fs/adfs/file.c | 2 +- fs/affs/file.c | 2 +- fs/afs/file.c | 2 +- fs/bfs/file.c | 2 +- fs/block_dev.c | 1 - fs/cifs/cifsfs.c | 8 +++---- fs/coda/file.c | 11 +++++---- fs/ecryptfs/file.c | 15 ++++++------ fs/ext2/file.c | 1 - fs/ext3/file.c | 1 - fs/ext4/file.c | 1 - fs/fat/file.c | 2 +- fs/fuse/file.c | 4 ++-- fs/gfs2/ops_file.c | 1 - fs/hfs/inode.c | 2 +- fs/hfsplus/inode.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/file.c | 2 +- fs/jffs2/file.c | 2 +- fs/jfs/file.c | 1 - fs/minix/file.c | 2 +- fs/ntfs/file.c | 2 +- fs/ocfs2/file.c | 1 - fs/qnx4/file.c | 2 +- fs/ramfs/file-mmu.c | 2 +- fs/ramfs/file-nommu.c | 2 +- fs/reiserfs/file.c | 1 - fs/smbfs/file.c | 9 ++++---- fs/sysv/file.c | 2 +- fs/udf/file.c | 2 +- fs/ufs/file.c | 2 +- fs/xfs/linux-2.6/xfs_file.c | 26 --------------------- fs/xfs/linux-2.6/xfs_linux.h | 1 - fs/xfs/linux-2.6/xfs_lrw.c | 44 ------------------------------------ fs/xfs/linux-2.6/xfs_lrw.h | 3 --- fs/xfs/linux-2.6/xfs_vnode.h | 6 ----- fs/xfs/xfs_vnodeops.c | 3 --- 37 files changed, 43 insertions(+), 131 deletions(-) diff --git a/fs/adfs/file.c b/fs/adfs/file.c index f544a2855923..36e381c6a99a 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c @@ -33,7 +33,7 @@ const struct file_operations adfs_file_operations = { .fsync = file_fsync, .write = do_sync_write, .aio_write = generic_file_aio_write, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations adfs_file_inode_operations = { diff --git a/fs/affs/file.c b/fs/affs/file.c index c8796906f584..c314a35f0918 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -35,7 +35,7 @@ const struct file_operations affs_file_operations = { .open = affs_file_open, .release = affs_file_release, .fsync = file_fsync, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations affs_file_inode_operations = { diff --git a/fs/afs/file.c b/fs/afs/file.c index 9c0e721d9fc2..aede7eb66dd4 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -32,7 +32,7 @@ const struct file_operations afs_file_operations = { .aio_read = generic_file_aio_read, .aio_write = afs_file_write, .mmap = generic_file_readonly_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .fsync = afs_fsync, }; diff --git a/fs/bfs/file.c b/fs/bfs/file.c index ef4d1fa04e65..24310e9ee05a 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -24,7 +24,7 @@ const struct file_operations bfs_file_operations = { .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb) diff --git a/fs/block_dev.c b/fs/block_dev.c index ea1480a16f51..b3e9bfa748cf 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1346,7 +1346,6 @@ const struct file_operations def_blk_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, #endif - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, }; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 7c04752b76cb..8b0cbf4a4ad0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -616,7 +616,7 @@ const struct file_operations cifs_file_ops = { .fsync = cifs_fsync, .flush = cifs_flush, .mmap = cifs_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .llseek = cifs_llseek, #ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, @@ -637,7 +637,7 @@ const struct file_operations cifs_file_direct_ops = { .lock = cifs_lock, .fsync = cifs_fsync, .flush = cifs_flush, - .sendfile = generic_file_sendfile, /* BB removeme BB */ + .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, #endif /* CONFIG_CIFS_POSIX */ @@ -656,7 +656,7 @@ const struct file_operations cifs_file_nobrl_ops = { .fsync = cifs_fsync, .flush = cifs_flush, .mmap = cifs_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .llseek = cifs_llseek, #ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, @@ -676,7 +676,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { .release = cifs_close, .fsync = cifs_fsync, .flush = cifs_flush, - .sendfile = generic_file_sendfile, /* BB removeme BB */ + .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .ioctl = cifs_ioctl, #endif /* CONFIG_CIFS_POSIX */ diff --git a/fs/coda/file.c b/fs/coda/file.c index 5ef2b609ec7d..99dbe866816d 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -47,8 +47,9 @@ coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *p } static ssize_t -coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count, - read_actor_t actor, void *target) +coda_file_splice_read(struct file *coda_file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t count, + unsigned int flags) { struct coda_file_info *cfi; struct file *host_file; @@ -57,10 +58,10 @@ coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count, BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; - if (!host_file->f_op || !host_file->f_op->sendfile) + if (!host_file->f_op || !host_file->f_op->splice_read) return -EINVAL; - return host_file->f_op->sendfile(host_file, ppos, count, actor, target); + return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags); } static ssize_t @@ -295,6 +296,6 @@ const struct file_operations coda_file_operations = { .flush = coda_flush, .release = coda_release, .fsync = coda_fsync, - .sendfile = coda_file_sendfile, + .splice_read = coda_file_splice_read, }; diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 59288d817078..94f456fe4d9b 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -338,16 +338,17 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag) return rc; } -static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos, - size_t count, read_actor_t actor, void *target) +static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos, + struct pipe_inode_info *pipe, size_t count, + unsigned int flags) { struct file *lower_file = NULL; int rc = -EINVAL; lower_file = ecryptfs_file_to_lower(file); - if (lower_file->f_op && lower_file->f_op->sendfile) - rc = lower_file->f_op->sendfile(lower_file, ppos, count, - actor, target); + if (lower_file->f_op && lower_file->f_op->splice_read) + rc = lower_file->f_op->splice_read(lower_file, ppos, pipe, + count, flags); return rc; } @@ -364,7 +365,7 @@ const struct file_operations ecryptfs_dir_fops = { .release = ecryptfs_release, .fsync = ecryptfs_fsync, .fasync = ecryptfs_fasync, - .sendfile = ecryptfs_sendfile, + .splice_read = ecryptfs_splice_read, }; const struct file_operations ecryptfs_main_fops = { @@ -381,7 +382,7 @@ const struct file_operations ecryptfs_main_fops = { .release = ecryptfs_release, .fsync = ecryptfs_fsync, .fasync = ecryptfs_fasync, - .sendfile = ecryptfs_sendfile, + .splice_read = ecryptfs_splice_read, }; static int diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 566d4e2d3852..072a1909b2bc 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -53,7 +53,6 @@ const struct file_operations ext2_file_operations = { .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, }; diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 1e6f13864536..acc4913d3019 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -120,7 +120,6 @@ const struct file_operations ext3_file_operations = { .open = generic_file_open, .release = ext3_release_file, .fsync = ext3_sync_file, - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, }; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 3c6c1fd2be90..d4c8186aed64 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -120,7 +120,6 @@ const struct file_operations ext4_file_operations = { .open = generic_file_open, .release = ext4_release_file, .fsync = ext4_sync_file, - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, }; diff --git a/fs/fat/file.c b/fs/fat/file.c index 55d3c7461c5b..69a83b59dce8 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -134,7 +134,7 @@ const struct file_operations fat_file_operations = { .release = fat_file_release, .ioctl = fat_generic_ioctl, .fsync = file_fsync, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; static int fat_cont_expand(struct inode *inode, loff_t size) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index adf7995232b8..f79de7c8cdfa 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -802,7 +802,7 @@ static const struct file_operations fuse_file_operations = { .release = fuse_release, .fsync = fuse_fsync, .lock = fuse_file_lock, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; static const struct file_operations fuse_direct_io_file_operations = { @@ -814,7 +814,7 @@ static const struct file_operations fuse_direct_io_file_operations = { .release = fuse_release, .fsync = fuse_fsync, .lock = fuse_file_lock, - /* no mmap and sendfile */ + /* no mmap and splice_read */ }; static const struct address_space_operations fuse_file_aops = { diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 064df8804582..7dc3be108204 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -635,7 +635,6 @@ const struct file_operations gfs2_file_fops = { .release = gfs2_close, .fsync = gfs2_fsync, .lock = gfs2_lock, - .sendfile = generic_file_sendfile, .flock = gfs2_flock, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 9a934db0bd8a..bc835f272a6e 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -607,7 +607,7 @@ static const struct file_operations hfs_file_operations = { .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .fsync = file_fsync, .open = hfs_file_open, .release = hfs_file_release, diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 45dab5d6cc10..409ce5429c91 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -288,7 +288,7 @@ static const struct file_operations hfsplus_file_operations = { .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .fsync = file_fsync, .open = hfsplus_file_open, .release = hfsplus_file_release, diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 8286491dbf31..c77862032e84 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -390,7 +390,7 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) static const struct file_operations hostfs_file_fops = { .llseek = generic_file_llseek, .read = do_sync_read, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .write = do_sync_write, diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index b4eafc0f1e54..5b53e5c5d8df 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -129,7 +129,7 @@ const struct file_operations hpfs_file_ops = .mmap = generic_file_mmap, .release = hpfs_file_release, .fsync = hpfs_file_fsync, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations hpfs_file_iops = diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 99871279a1ed..c2530197be0c 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -47,7 +47,7 @@ const struct file_operations jffs2_file_operations = .ioctl = jffs2_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, - .sendfile = generic_file_sendfile + .splice_read = generic_file_splice_read, }; /* jffs2_file_inode_operations */ diff --git a/fs/jfs/file.c b/fs/jfs/file.c index f7f8eff19b7b..87eb93694af7 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -108,7 +108,6 @@ const struct file_operations jfs_file_operations = { .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, .fsync = jfs_fsync, diff --git a/fs/minix/file.c b/fs/minix/file.c index f92baa1d7570..17765f697e50 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -23,7 +23,7 @@ const struct file_operations minix_file_operations = { .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = minix_sync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations minix_file_inode_operations = { diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 7ed56390b582..ffcc504a1667 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2276,7 +2276,7 @@ const struct file_operations ntfs_file_ops = { mounted filesystem. */ .mmap = generic_file_mmap, /* Mmap file. */ .open = ntfs_file_open, /* Open file. */ - .sendfile = generic_file_sendfile, /* Zero-copy data send with + .splice_read = generic_file_splice_read /* Zero-copy data send with the data source being on the ntfs partition. We do not need to care about the diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 222f108ee454..ed1ffa70cc38 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1822,7 +1822,6 @@ const struct inode_operations ocfs2_special_file_iops = { const struct file_operations ocfs2_fops = { .read = do_sync_read, .write = do_sync_write, - .sendfile = generic_file_sendfile, .mmap = ocfs2_mmap, .fsync = ocfs2_sync_file, .release = ocfs2_file_release, diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c index 44649981bbc8..867f42b02035 100644 --- a/fs/qnx4/file.c +++ b/fs/qnx4/file.c @@ -25,7 +25,7 @@ const struct file_operations qnx4_file_operations = .read = do_sync_read, .aio_read = generic_file_aio_read, .mmap = generic_file_mmap, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, #ifdef CONFIG_QNX4FS_RW .write = do_sync_write, .aio_write = generic_file_aio_write, diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 2f14774a124f..97bdc0b2f9d2 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c @@ -41,7 +41,7 @@ const struct file_operations ramfs_file_operations = { .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = simple_sync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .llseek = generic_file_llseek, }; diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 5d258c40a2fd..cad2b7ace630 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = { .write = do_sync_write, .aio_write = generic_file_aio_write, .fsync = simple_sync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, .llseek = generic_file_llseek, }; diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 9e451a68580f..30eebfb1b2d8 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -1531,7 +1531,6 @@ const struct file_operations reiserfs_file_operations = { .open = generic_file_open, .release = reiserfs_file_release, .fsync = reiserfs_sync_file, - .sendfile = generic_file_sendfile, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .splice_read = generic_file_splice_read, diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index aea3f8aa54c0..c5d78a7e492b 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -262,8 +262,9 @@ out: } static ssize_t -smb_file_sendfile(struct file *file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) +smb_file_splice_read(struct file *file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t count, + unsigned int flags) { struct dentry *dentry = file->f_path.dentry; ssize_t status; @@ -277,7 +278,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos, DENTRY_PATH(dentry), status); goto out; } - status = generic_file_sendfile(file, ppos, count, actor, target); + status = generic_file_splice_read(file, ppos, pipe, count, flags); out: return status; } @@ -416,7 +417,7 @@ const struct file_operations smb_file_operations = .open = smb_file_open, .release = smb_file_release, .fsync = smb_fsync, - .sendfile = smb_file_sendfile, + .splice_read = smb_file_splice_read, }; const struct inode_operations smb_file_inode_operations = diff --git a/fs/sysv/file.c b/fs/sysv/file.c index 0732ddb9020b..589be21d884e 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c @@ -27,7 +27,7 @@ const struct file_operations sysv_file_operations = { .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = sysv_sync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations sysv_file_inode_operations = { diff --git a/fs/udf/file.c b/fs/udf/file.c index 51b5764685e7..df070bee8d4f 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -261,7 +261,7 @@ const struct file_operations udf_file_operations = { .aio_write = udf_file_aio_write, .release = udf_release_file, .fsync = udf_fsync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; const struct inode_operations udf_file_inode_operations = { diff --git a/fs/ufs/file.c b/fs/ufs/file.c index 1e096323bad4..6705d74c6d2d 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -60,5 +60,5 @@ const struct file_operations ufs_file_operations = { .mmap = generic_file_mmap, .open = generic_file_open, .fsync = ufs_sync_file, - .sendfile = generic_file_sendfile, + .splice_read = generic_file_splice_read, }; diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index cb51dc961355..8c43cd2e237a 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -123,30 +123,6 @@ xfs_file_aio_write_invis( return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } -STATIC ssize_t -xfs_file_sendfile( - struct file *filp, - loff_t *pos, - size_t count, - read_actor_t actor, - void *target) -{ - return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode), - filp, pos, 0, count, actor, target, NULL); -} - -STATIC ssize_t -xfs_file_sendfile_invis( - struct file *filp, - loff_t *pos, - size_t count, - read_actor_t actor, - void *target) -{ - return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode), - filp, pos, IO_INVIS, count, actor, target, NULL); -} - STATIC ssize_t xfs_file_splice_read( struct file *infilp, @@ -452,7 +428,6 @@ const struct file_operations xfs_file_operations = { .write = do_sync_write, .aio_read = xfs_file_aio_read, .aio_write = xfs_file_aio_write, - .sendfile = xfs_file_sendfile, .splice_read = xfs_file_splice_read, .splice_write = xfs_file_splice_write, .unlocked_ioctl = xfs_file_ioctl, @@ -475,7 +450,6 @@ const struct file_operations xfs_invis_file_operations = { .write = do_sync_write, .aio_read = xfs_file_aio_read_invis, .aio_write = xfs_file_aio_write_invis, - .sendfile = xfs_file_sendfile_invis, .splice_read = xfs_file_splice_read_invis, .splice_write = xfs_file_splice_write_invis, .unlocked_ioctl = xfs_file_ioctl_invis, diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 715adad7dd4d..af24a457d3a3 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -101,7 +101,6 @@ * Feature macros (disable/enable) */ #undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */ -#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */ #define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */ #ifdef CONFIG_SMP #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ed90403f0ee7..765ec16a6e39 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -286,50 +286,6 @@ xfs_read( return ret; } -ssize_t -xfs_sendfile( - bhv_desc_t *bdp, - struct file *filp, - loff_t *offset, - int ioflags, - size_t count, - read_actor_t actor, - void *target, - cred_t *credp) -{ - xfs_inode_t *ip = XFS_BHVTOI(bdp); - xfs_mount_t *mp = ip->i_mount; - ssize_t ret; - - XFS_STATS_INC(xs_read_calls); - if (XFS_FORCED_SHUTDOWN(mp)) - return -EIO; - - xfs_ilock(ip, XFS_IOLOCK_SHARED); - - if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && - (!(ioflags & IO_INVIS))) { - bhv_vrwlock_t locktype = VRWLOCK_READ; - int error; - - error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), - *offset, count, - FILP_DELAY_FLAG(filp), &locktype); - if (error) { - xfs_iunlock(ip, XFS_IOLOCK_SHARED); - return -error; - } - } - xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore, - (void *)(unsigned long)target, count, *offset, ioflags); - ret = generic_file_sendfile(filp, offset, count, actor, target); - if (ret > 0) - XFS_STATS_ADD(xs_read_bytes, ret); - - xfs_iunlock(ip, XFS_IOLOCK_SHARED); - return ret; -} - ssize_t xfs_splice_read( 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 7ac51b1d2161..7c60a1eed88b 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h @@ -90,9 +90,6 @@ extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, const struct iovec *, unsigned int, loff_t *, int, struct cred *); -extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, - loff_t *, int, size_t, read_actor_t, - void *, struct cred *); extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *, struct pipe_inode_info *, size_t, int, int, struct cred *); diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index d1b2d01843d1..013048a92643 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -139,9 +139,6 @@ typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, const struct iovec *, unsigned int, loff_t *, int, struct cred *); -typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, - loff_t *, int, size_t, read_actor_t, - void *, struct cred *); typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *, struct pipe_inode_info *, size_t, int, int, struct cred *); @@ -206,7 +203,6 @@ typedef struct bhv_vnodeops { vop_close_t vop_close; vop_read_t vop_read; vop_write_t vop_write; - vop_sendfile_t vop_sendfile; vop_splice_read_t vop_splice_read; vop_splice_write_t vop_splice_write; vop_ioctl_t vop_ioctl; @@ -254,8 +250,6 @@ typedef struct bhv_vnodeops { VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) -#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \ - VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr) #define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \ VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr) #define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \ diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index de17aed578f0..70bc82f65311 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -4680,9 +4680,6 @@ bhv_vnodeops_t xfs_vnodeops = { .vop_open = xfs_open, .vop_close = xfs_close, .vop_read = xfs_read, -#ifdef HAVE_SENDFILE - .vop_sendfile = xfs_sendfile, -#endif #ifdef HAVE_SPLICE .vop_splice_read = xfs_splice_read, .vop_splice_write = xfs_splice_write, From 0452a4e5d021900b07ebdeecb9ed03b49f164f3f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 1 Jun 2007 11:55:49 +0200 Subject: [PATCH 400/551] sendfile: kill generic_file_sendfile() It's no longer used. Signed-off-by: Jens Axboe --- include/linux/fs.h | 1 - mm/filemap.c | 20 -------------------- 2 files changed, 21 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 6a41f4cab14c..87c1d3e9d6cb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1762,7 +1762,6 @@ extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *, unsigned long, loff_t, loff_t *, size_t, ssize_t); extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); -extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); extern void do_generic_mapping_read(struct address_space *mapping, struct file_ra_state *, struct file *, loff_t *, read_descriptor_t *, read_actor_t); diff --git a/mm/filemap.c b/mm/filemap.c index d1d9814f99dd..c6ebd9f912ab 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1245,26 +1245,6 @@ int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long o return written; } -ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) -{ - read_descriptor_t desc; - - if (!count) - return 0; - - desc.written = 0; - desc.count = count; - desc.arg.data = target; - desc.error = 0; - - do_generic_file_read(in_file, ppos, &desc, actor); - if (desc.written) - return desc.written; - return desc.error; -} -EXPORT_SYMBOL(generic_file_sendfile); - static ssize_t do_readahead(struct address_space *mapping, struct file *filp, unsigned long index, unsigned long nr) From 130610d6f681c5d970340897f5db000d04a7ef78 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 21:20:00 +0200 Subject: [PATCH 401/551] splice: add void cookie to the actor data We need that for passing driver private info. Signed-off-by: Jens Axboe --- include/linux/pipe_fs_i.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 6e7bfc125425..f277a9cdb50d 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -94,6 +94,7 @@ struct splice_desc { union { void __user *userptr; /* memory to write to */ struct file *file; /* file to read/write */ + void *data; /* cookie */ } u; loff_t pos; /* file position */ }; From fd5821404e6823997666d668f62c76eae228abc9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 21:20:37 +0200 Subject: [PATCH 402/551] loop: convert to using splice_direct_to_actor() instead of sendfile() This gets rid of the dependency on ->sendfile() for receiving data and converts loop to ->splice_read() instead. Also includes an IV offset fix from Hugh Dickins. Signed-off-by: Jens Axboe --- drivers/block/loop.c | 64 ++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0ed5470d2533..87d84e7d5432 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -74,6 +74,7 @@ #include #include #include +#include #include @@ -401,50 +402,73 @@ struct lo_read_data { }; static int -lo_read_actor(read_descriptor_t *desc, struct page *page, - unsigned long offset, unsigned long size) +lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, + struct splice_desc *sd) { - unsigned long count = desc->count; - struct lo_read_data *p = desc->arg.data; + struct lo_read_data *p = sd->u.data; struct loop_device *lo = p->lo; + struct page *page = buf->page; sector_t IV; + size_t size; + int ret; - IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); + ret = buf->ops->pin(pipe, buf); + if (unlikely(ret)) + return ret; - if (size > count) - size = count; + IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + + (buf->offset >> 9); + size = sd->len; + if (size > p->bsize) + size = p->bsize; - if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) { - size = 0; + if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) { printk(KERN_ERR "loop: transfer error block %ld\n", page->index); - desc->error = -EINVAL; + size = -EINVAL; } flush_dcache_page(p->page); - desc->count = count - size; - desc->written += size; - p->offset += size; + if (size > 0) + p->offset += size; + return size; } +static int +lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) +{ + return __splice_from_pipe(pipe, sd, lo_splice_actor); +} + static int do_lo_receive(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) { struct lo_read_data cookie; + struct splice_desc sd; struct file *file; - int retval; + long retval; cookie.lo = lo; cookie.page = bvec->bv_page; cookie.offset = bvec->bv_offset; cookie.bsize = bsize; + + sd.len = 0; + sd.total_len = bvec->bv_len; + sd.flags = 0; + sd.pos = pos; + sd.u.data = &cookie; + file = lo->lo_backing_file; - retval = file->f_op->sendfile(file, &pos, bvec->bv_len, - lo_read_actor, &cookie); - return (retval < 0)? retval: 0; + retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); + + if (retval < 0) + return retval; + + return 0; } static int @@ -679,8 +703,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file, if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) goto out_putf; - /* new backing store needs to support loop (eg sendfile) */ - if (!inode->i_fop->sendfile) + /* new backing store needs to support loop (eg splice_read) */ + if (!inode->i_fop->splice_read) goto out_putf; /* size of the new backing store needs to be the same */ @@ -760,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, * If we can't read - sorry. If we only can't write - well, * it's going to be read-only. */ - if (!file->f_op->sendfile) + if (!file->f_op->splice_read) goto out_putf; if (aops->prepare_write && aops->commit_write) lo_flags |= LO_FLAGS_USE_AOPS; From f0930fffa99e7fe0a0c4b6c7d9a244dc88288c27 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 1 Jun 2007 11:51:43 +0200 Subject: [PATCH 403/551] sendfile: convert nfs to using splice_read() Acked-by: Trond Myklebust Signed-off-by: Jens Axboe --- fs/nfs/file.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 9eb8eb4e4a08..8689b736fdd9 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -41,7 +41,9 @@ static int nfs_file_open(struct inode *, struct file *); static int nfs_file_release(struct inode *, struct file *); static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); static int nfs_file_mmap(struct file *, struct vm_area_struct *); -static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); +static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t count, unsigned int flags); static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, unsigned long nr_segs, loff_t pos); static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, @@ -65,7 +67,7 @@ const struct file_operations nfs_file_operations = { .fsync = nfs_fsync, .lock = nfs_lock, .flock = nfs_flock, - .sendfile = nfs_file_sendfile, + .splice_read = nfs_file_splice_read, .check_flags = nfs_check_flags, }; @@ -224,20 +226,21 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov, } static ssize_t -nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, - read_actor_t actor, void *target) +nfs_file_splice_read(struct file *filp, loff_t *ppos, + struct pipe_inode_info *pipe, size_t count, + unsigned int flags) { struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; ssize_t res; - dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n", + dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n", dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long long) *ppos); res = nfs_revalidate_mapping(inode, filp->f_mapping); if (!res) - res = generic_file_sendfile(filp, ppos, count, actor, target); + res = generic_file_splice_read(filp, ppos, pipe, count, flags); return res; } From cf8208d0eabd1d5d2625ec02a175a294c3f30d36 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 21:22:14 +0200 Subject: [PATCH 404/551] sendfile: convert nfsd to splice_direct_to_actor() Signed-off-by: Jens Axboe --- fs/nfsd/vfs.c | 47 ++++++++++++++++++++----------- include/linux/sunrpc/svc.h | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- net/sunrpc/svc.c | 2 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 7e6aa245b5d5..15471a9efe0e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -801,26 +801,32 @@ found: } /* - * Grab and keep cached pages assosiated with a file in the svc_rqst - * so that they can be passed to the netowork sendmsg/sendpage routines - * directrly. They will be released after the sending has completed. + * Grab and keep cached pages associated with a file in the svc_rqst + * so that they can be passed to the network sendmsg/sendpage routines + * directly. They will be released after the sending has completed. */ static int -nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size) +nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, + struct splice_desc *sd) { - unsigned long count = desc->count; - struct svc_rqst *rqstp = desc->arg.data; + struct svc_rqst *rqstp = sd->u.data; struct page **pp = rqstp->rq_respages + rqstp->rq_resused; + struct page *page = buf->page; + size_t size; + int ret; - if (size > count) - size = count; + ret = buf->ops->pin(pipe, buf); + if (unlikely(ret)) + return ret; + + size = sd->len; if (rqstp->rq_res.page_len == 0) { get_page(page); put_page(*pp); *pp = page; rqstp->rq_resused++; - rqstp->rq_res.page_base = offset; + rqstp->rq_res.page_base = buf->offset; rqstp->rq_res.page_len = size; } else if (page != pp[-1]) { get_page(page); @@ -832,11 +838,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset } else rqstp->rq_res.page_len += size; - desc->count = count - size; - desc->written += size; return size; } +static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe, + struct splice_desc *sd) +{ + return __splice_from_pipe(pipe, sd, nfsd_splice_actor); +} + static __be32 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, struct kvec *vec, int vlen, unsigned long *count) @@ -861,10 +871,15 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, if (ra && ra->p_set) file->f_ra = ra->p_ra; - if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { - rqstp->rq_resused = 1; - host_err = file->f_op->sendfile(file, &offset, *count, - nfsd_read_actor, rqstp); + if (file->f_op->splice_read && rqstp->rq_splice_ok) { + struct splice_desc sd = { + .len = 0, + .total_len = *count, + .pos = offset, + .u.data = rqstp, + }; + + host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); } else { oldfs = get_fs(); set_fs(KERNEL_DS); diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 4a7ae8ab6eb8..129d50f2225c 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -253,7 +253,7 @@ struct svc_rqst { * determine what device number * to report (real or virtual) */ - int rq_sendfile_ok; /* turned off in gss privacy + int rq_splice_ok; /* turned off in gss privacy * to prevent encrypting page * cache pages */ wait_queue_head_t rq_wait; /* synchronization */ diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 099a983797da..c094583386fd 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -853,7 +853,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs u32 priv_len, maj_stat; int pad, saved_len, remaining_len, offset; - rqstp->rq_sendfile_ok = 0; + rqstp->rq_splice_ok = 0; priv_len = svc_getnl(&buf->head[0]); if (rqstp->rq_deferred) { diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index e673ef993904..55ea6df069de 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -814,7 +814,7 @@ svc_process(struct svc_rqst *rqstp) rqstp->rq_res.tail[0].iov_base = NULL; rqstp->rq_res.tail[0].iov_len = 0; /* Will be turned off only in gss privacy case: */ - rqstp->rq_sendfile_ok = 1; + rqstp->rq_splice_ok = 1; /* tcp needs a space for the record length... */ if (rqstp->rq_prot == IPPROTO_TCP) svc_putnl(resv, 0); From ebf9909343392c929d9943c04f421cd42e03b530 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Mon, 4 Jun 2007 09:12:05 +0200 Subject: [PATCH 405/551] splice: relay support Signed-off-by: Jens Axboe --- kernel/relay.c | 241 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 191 insertions(+), 50 deletions(-) diff --git a/kernel/relay.c b/kernel/relay.c index 95db8c79fe8f..d1d1920f2800 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -21,6 +21,7 @@ #include #include #include +#include /* list of open channels, for cpu hotplug */ static DEFINE_MUTEX(relay_channels_mutex); @@ -121,6 +122,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size) buf->page_array[i] = alloc_page(GFP_KERNEL); if (unlikely(!buf->page_array[i])) goto depopulate; + set_page_private(buf->page_array[i], (unsigned long)buf); } mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL); if (!mem) @@ -970,43 +972,6 @@ static int subbuf_read_actor(size_t read_start, return ret; } -/* - * subbuf_send_actor - send up to one subbuf's worth of data - */ -static int subbuf_send_actor(size_t read_start, - struct rchan_buf *buf, - size_t avail, - read_descriptor_t *desc, - read_actor_t actor) -{ - unsigned long pidx, poff; - unsigned int subbuf_pages; - int ret = 0; - - subbuf_pages = buf->chan->alloc_size >> PAGE_SHIFT; - pidx = (read_start / PAGE_SIZE) % subbuf_pages; - poff = read_start & ~PAGE_MASK; - while (avail) { - struct page *p = buf->page_array[pidx]; - unsigned int len; - - len = PAGE_SIZE - poff; - if (len > avail) - len = avail; - - len = actor(desc, p, poff, len); - if (desc->error) - break; - - avail -= len; - ret += len; - poff = 0; - pidx = (pidx + 1) % subbuf_pages; - } - - return ret; -} - typedef int (*subbuf_actor_t) (size_t read_start, struct rchan_buf *buf, size_t avail, @@ -1067,19 +1032,195 @@ static ssize_t relay_file_read(struct file *filp, NULL, &desc); } -static ssize_t relay_file_sendfile(struct file *filp, - loff_t *ppos, - size_t count, - read_actor_t actor, - void *target) +static void relay_pipe_buf_release(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) { - read_descriptor_t desc; - desc.written = 0; - desc.count = count; - desc.arg.data = target; - desc.error = 0; - return relay_file_read_subbufs(filp, ppos, subbuf_send_actor, - actor, &desc); + struct rchan_buf *rbuf; + + rbuf = (struct rchan_buf *)page_private(buf->page); + + rbuf->bytes_consumed += PAGE_SIZE; + + if (rbuf->bytes_consumed == rbuf->chan->subbuf_size) { + relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1); + rbuf->bytes_consumed = 0; + } +} + +static struct pipe_buf_operations relay_pipe_buf_ops = { + .can_merge = 0, + .map = generic_pipe_buf_map, + .unmap = generic_pipe_buf_unmap, + .pin = generic_pipe_buf_pin, + .release = relay_pipe_buf_release, + .steal = generic_pipe_buf_steal, + .get = generic_pipe_buf_get, +}; + +/** + * subbuf_splice_actor - splice up to one subbuf's worth of data + */ +static int subbuf_splice_actor(struct file *in, + loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, + unsigned int flags, + int *nonpad_ret) +{ + unsigned int pidx, poff; + unsigned int subbuf_pages; + int ret = 0; + int do_wakeup = 0; + struct rchan_buf *rbuf = in->private_data; + unsigned int subbuf_size = rbuf->chan->subbuf_size; + size_t read_start = ((size_t)*ppos) % rbuf->chan->alloc_size; + size_t avail = subbuf_size - read_start % subbuf_size; + size_t read_subbuf = read_start / subbuf_size; + size_t padding = rbuf->padding[read_subbuf]; + size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding; + + if (rbuf->subbufs_produced == rbuf->subbufs_consumed) + return 0; + + if (len > avail) + len = avail; + + if (pipe->inode) + mutex_lock(&pipe->inode->i_mutex); + + subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT; + pidx = (read_start / PAGE_SIZE) % subbuf_pages; + poff = read_start & ~PAGE_MASK; + + for (;;) { + unsigned int this_len; + unsigned int this_end; + int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); + struct pipe_buffer *buf = pipe->bufs + newbuf; + + if (!pipe->readers) { + send_sig(SIGPIPE, current, 0); + if (!ret) + ret = -EPIPE; + break; + } + + if (pipe->nrbufs < PIPE_BUFFERS) { + this_len = PAGE_SIZE - poff; + if (this_len > avail) + this_len = avail; + + buf->page = rbuf->page_array[pidx]; + buf->offset = poff; + this_end = read_start + ret + this_len; + if (this_end > nonpad_end) { + if (read_start + ret >= nonpad_end) + buf->len = 0; + else + buf->len = nonpad_end - (read_start + ret); + } else + buf->len = this_len; + + *nonpad_ret += buf->len; + + buf->ops = &relay_pipe_buf_ops; + pipe->nrbufs++; + + avail -= this_len; + ret += this_len; + poff = 0; + pidx = (pidx + 1) % subbuf_pages; + + if (pipe->inode) + do_wakeup = 1; + + if (!avail) + break; + + if (pipe->nrbufs < PIPE_BUFFERS) + continue; + + break; + } + + if (flags & SPLICE_F_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + + if (do_wakeup) { + smp_mb(); + if (waitqueue_active(&pipe->wait)) + wake_up_interruptible_sync(&pipe->wait); + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); + do_wakeup = 0; + } + + pipe->waiting_writers++; + pipe_wait(pipe); + pipe->waiting_writers--; + } + + if (pipe->inode) + mutex_unlock(&pipe->inode->i_mutex); + + if (do_wakeup) { + smp_mb(); + if (waitqueue_active(&pipe->wait)) + wake_up_interruptible(&pipe->wait); + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); + } + + return ret; +} + +static ssize_t relay_file_splice_read(struct file *in, + loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, + unsigned int flags) +{ + ssize_t spliced; + int ret; + int nonpad_ret = 0; + + ret = 0; + spliced = 0; + + while (len) { + ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret); + if (ret < 0) + break; + else if (!ret) { + break; + if (spliced) + break; + if (flags & SPLICE_F_NONBLOCK) { + ret = -EAGAIN; + break; + } + } + + *ppos += ret; + if (ret > len) + len = 0; + else + len -= ret; + spliced += nonpad_ret; + nonpad_ret = 0; + } + + if (spliced) + return spliced; + + return ret; } const struct file_operations relay_file_operations = { @@ -1089,7 +1230,7 @@ const struct file_operations relay_file_operations = { .read = relay_file_read, .llseek = no_llseek, .release = relay_file_release, - .sendfile = relay_file_sendfile, + .splice_read = relay_file_splice_read, }; EXPORT_SYMBOL_GPL(relay_file_operations); From d6b29d7cee064f28ca097e906de7453541351095 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 4 Jun 2007 09:59:47 +0200 Subject: [PATCH 406/551] splice: divorce the splice structure/function definitions from the pipe header We need to move even more stuff into the header so that folks can use the splice_to_pipe() implementation instead of open-coding a lot of pipe knowledge (see relay implementation), so move to our own header file finally. Signed-off-by: Jens Axboe --- drivers/block/loop.c | 2 +- drivers/char/mem.c | 2 +- fs/nfsd/vfs.c | 2 +- fs/ocfs2/file.c | 2 +- fs/read_write.c | 2 +- fs/splice.c | 26 +++----------- include/linux/pipe_fs_i.h | 41 ---------------------- include/linux/splice.h | 72 +++++++++++++++++++++++++++++++++++++++ kernel/relay.c | 2 +- 9 files changed, 83 insertions(+), 68 deletions(-) create mode 100644 include/linux/splice.h diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 87d84e7d5432..08f53df03e8c 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -74,7 +74,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/char/mem.c b/drivers/char/mem.c index cc9a9d0df979..d2e4cfd79f27 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 15471a9efe0e..8176fbf5c006 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index ed1ffa70cc38..44c2e2afa465 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/fs/read_write.c b/fs/read_write.c index 47da8a4a0fbe..2527cf035b0e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include "read_write.h" #include diff --git a/fs/splice.c b/fs/splice.c index 13846f723d72..bea9f1581ca0 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -29,22 +29,6 @@ #include #include -struct partial_page { - unsigned int offset; - unsigned int len; -}; - -/* - * Passed to splice_to_pipe - */ -struct splice_pipe_desc { - struct page **pages; /* page map */ - struct partial_page *partial; /* pages[] may not be contig */ - int nr_pages; /* number of pages in map */ - unsigned int flags; /* splice flags */ - const struct pipe_buf_operations *ops;/* ops associated with output pipe */ -}; - /* * Attempt to steal a page from a pipe buffer. This should perhaps go into * a vm helper function, it's already simplified quite a bit by the @@ -170,11 +154,11 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = { }; /* - * Pipe output worker. This sets up our pipe format with the page cache - * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). + * Pipe output worker. This fills a pipe with the information contained + * from splice_pipe_desc(). */ -static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, - struct splice_pipe_desc *spd) +ssize_t splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd) { unsigned int spd_pages = spd->nr_pages; int ret, do_wakeup, page_nr; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index f277a9cdb50d..7ba228d52f58 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -71,45 +71,4 @@ void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); -/* - * splice is tied to pipes as a transport (at least for now), so we'll just - * add the splice flags here. - */ -#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ -#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */ - /* we may still block on the fd we splice */ - /* from/to, of course */ -#define SPLICE_F_MORE (0x04) /* expect more data */ -#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ - -/* - * Passed to the actors - */ -struct splice_desc { - unsigned int len, total_len; /* current and remaining length */ - unsigned int flags; /* splice flags */ - /* - * actor() private data - */ - union { - void __user *userptr; /* memory to write to */ - struct file *file; /* file to read/write */ - void *data; /* cookie */ - } u; - loff_t pos; /* file position */ -}; - -typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, - struct splice_desc *); -typedef int (splice_direct_actor)(struct pipe_inode_info *, - struct splice_desc *); - -extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int, - splice_actor *); -extern ssize_t __splice_from_pipe(struct pipe_inode_info *, - struct splice_desc *, splice_actor *); -extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, - splice_direct_actor *); - #endif diff --git a/include/linux/splice.h b/include/linux/splice.h new file mode 100644 index 000000000000..f8cc97f71cd0 --- /dev/null +++ b/include/linux/splice.h @@ -0,0 +1,72 @@ +/* + * Function declerations and data structures related to the splice + * implementation. + * + * Copyright (C) 2007 Jens Axboe + * + */ +#ifndef SPLICE_H +#define SPLICE_H + +#include + +/* + * splice is tied to pipes as a transport (at least for now), so we'll just + * add the splice flags here. + */ +#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ +#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */ + /* we may still block on the fd we splice */ + /* from/to, of course */ +#define SPLICE_F_MORE (0x04) /* expect more data */ +#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ + +/* + * Passed to the actors + */ +struct splice_desc { + unsigned int len, total_len; /* current and remaining length */ + unsigned int flags; /* splice flags */ + /* + * actor() private data + */ + union { + void __user *userptr; /* memory to write to */ + struct file *file; /* file to read/write */ + void *data; /* cookie */ + } u; + loff_t pos; /* file position */ +}; + +struct partial_page { + unsigned int offset; + unsigned int len; +}; + +/* + * Passed to splice_to_pipe + */ +struct splice_pipe_desc { + struct page **pages; /* page map */ + struct partial_page *partial; /* pages[] may not be contig */ + int nr_pages; /* number of pages in map */ + unsigned int flags; /* splice flags */ + const struct pipe_buf_operations *ops;/* ops associated with output pipe */ +}; + +typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, + struct splice_desc *); +typedef int (splice_direct_actor)(struct pipe_inode_info *, + struct splice_desc *); + +extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int, + splice_actor *); +extern ssize_t __splice_from_pipe(struct pipe_inode_info *, + struct splice_desc *, splice_actor *); +extern ssize_t splice_to_pipe(struct pipe_inode_info *, + struct splice_pipe_desc *); +extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, + splice_direct_actor *); + +#endif diff --git a/kernel/relay.c b/kernel/relay.c index d1d1920f2800..951f29b24e58 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include /* list of open channels, for cpu hotplug */ static DEFINE_MUTEX(relay_channels_mutex); From 497f9625c2bbd6a8525fb2eedb22a382a6a8253c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 11 Jun 2007 12:00:45 +0200 Subject: [PATCH 407/551] pipe: allow passing around of ops private pointer relay needs this for proper consumption handling, and the network receive support needs it as well to lookup the sk_buff on pipe release. Signed-off-by: Jens Axboe --- fs/splice.c | 1 + include/linux/pipe_fs_i.h | 1 + include/linux/splice.h | 1 + 3 files changed, 3 insertions(+) diff --git a/fs/splice.c b/fs/splice.c index bea9f1581ca0..00850e56280d 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -185,6 +185,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, buf->page = spd->pages[page_nr]; buf->offset = spd->partial[page_nr].offset; buf->len = spd->partial[page_nr].len; + buf->private = spd->partial[page_nr].private; buf->ops = spd->ops; if (spd->flags & SPLICE_F_GIFT) buf->flags |= PIPE_BUF_FLAG_GIFT; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 7ba228d52f58..4409167b9eb2 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -14,6 +14,7 @@ struct pipe_buffer { unsigned int offset, len; const struct pipe_buf_operations *ops; unsigned int flags; + unsigned long private; }; struct pipe_inode_info { diff --git a/include/linux/splice.h b/include/linux/splice.h index f8cc97f71cd0..33e447f98a54 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -41,6 +41,7 @@ struct splice_desc { struct partial_page { unsigned int offset; unsigned int len; + unsigned long private; }; /* From 1db60cf2056511c7c8cebcbaee308ef6c79b4728 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 08:43:46 +0200 Subject: [PATCH 408/551] relay: use splice_to_pipe() instead of open-coding the pipe loop It cleans up the relay splice implementation a lot, and gets rid of a lot of internal pipe knowledge that should not be in there. Plus fixes for padding and partial first page (and lots more) from Tom Zanussi. Signed-off-by: Jens Axboe --- kernel/relay.c | 160 +++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 98 deletions(-) diff --git a/kernel/relay.c b/kernel/relay.c index 951f29b24e58..dd3bc5b69035 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1032,19 +1032,23 @@ static ssize_t relay_file_read(struct file *filp, NULL, &desc); } +static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed) +{ + rbuf->bytes_consumed += bytes_consumed; + + if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) { + relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1); + rbuf->bytes_consumed %= rbuf->chan->subbuf_size; + } +} + static void relay_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct rchan_buf *rbuf; rbuf = (struct rchan_buf *)page_private(buf->page); - - rbuf->bytes_consumed += PAGE_SIZE; - - if (rbuf->bytes_consumed == rbuf->chan->subbuf_size) { - relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1); - rbuf->bytes_consumed = 0; - } + relay_consume_bytes(rbuf, buf->private); } static struct pipe_buf_operations relay_pipe_buf_ops = { @@ -1067,118 +1071,79 @@ static int subbuf_splice_actor(struct file *in, unsigned int flags, int *nonpad_ret) { - unsigned int pidx, poff; - unsigned int subbuf_pages; - int ret = 0; - int do_wakeup = 0; + unsigned int pidx, poff, total_len, subbuf_pages, ret; struct rchan_buf *rbuf = in->private_data; unsigned int subbuf_size = rbuf->chan->subbuf_size; size_t read_start = ((size_t)*ppos) % rbuf->chan->alloc_size; - size_t avail = subbuf_size - read_start % subbuf_size; size_t read_subbuf = read_start / subbuf_size; size_t padding = rbuf->padding[read_subbuf]; size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding; + struct page *pages[PIPE_BUFFERS]; + struct partial_page partial[PIPE_BUFFERS]; + struct splice_pipe_desc spd = { + .pages = pages, + .nr_pages = 0, + .partial = partial, + .flags = flags, + .ops = &relay_pipe_buf_ops, + }; if (rbuf->subbufs_produced == rbuf->subbufs_consumed) return 0; - if (len > avail) - len = avail; - - if (pipe->inode) - mutex_lock(&pipe->inode->i_mutex); + /* + * Adjust read len, if longer than what is available + */ + if (len > (subbuf_size - read_start % subbuf_size)) + len = subbuf_size - read_start % subbuf_size; subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT; pidx = (read_start / PAGE_SIZE) % subbuf_pages; poff = read_start & ~PAGE_MASK; - for (;;) { - unsigned int this_len; - unsigned int this_end; - int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); - struct pipe_buffer *buf = pipe->bufs + newbuf; + for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) { + unsigned int this_len, this_end, private; + unsigned int cur_pos = read_start + total_len; - if (!pipe->readers) { - send_sig(SIGPIPE, current, 0); - if (!ret) - ret = -EPIPE; + if (!len) + break; + + this_len = min_t(unsigned long, len, PAGE_SIZE - poff); + private = this_len; + + spd.pages[spd.nr_pages] = rbuf->page_array[pidx]; + spd.partial[spd.nr_pages].offset = poff; + + this_end = cur_pos + this_len; + if (this_end >= nonpad_end) { + this_len = nonpad_end - cur_pos; + private = this_len + padding; + } + spd.partial[spd.nr_pages].len = this_len; + spd.partial[spd.nr_pages].private = private; + + len -= this_len; + total_len += this_len; + poff = 0; + pidx = (pidx + 1) % subbuf_pages; + + if (this_end >= nonpad_end) { + spd.nr_pages++; break; } - - if (pipe->nrbufs < PIPE_BUFFERS) { - this_len = PAGE_SIZE - poff; - if (this_len > avail) - this_len = avail; - - buf->page = rbuf->page_array[pidx]; - buf->offset = poff; - this_end = read_start + ret + this_len; - if (this_end > nonpad_end) { - if (read_start + ret >= nonpad_end) - buf->len = 0; - else - buf->len = nonpad_end - (read_start + ret); - } else - buf->len = this_len; - - *nonpad_ret += buf->len; - - buf->ops = &relay_pipe_buf_ops; - pipe->nrbufs++; - - avail -= this_len; - ret += this_len; - poff = 0; - pidx = (pidx + 1) % subbuf_pages; - - if (pipe->inode) - do_wakeup = 1; - - if (!avail) - break; - - if (pipe->nrbufs < PIPE_BUFFERS) - continue; - - break; - } - - if (flags & SPLICE_F_NONBLOCK) { - if (!ret) - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - if (!ret) - ret = -ERESTARTSYS; - break; - } - - if (do_wakeup) { - smp_mb(); - if (waitqueue_active(&pipe->wait)) - wake_up_interruptible_sync(&pipe->wait); - kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); - do_wakeup = 0; - } - - pipe->waiting_writers++; - pipe_wait(pipe); - pipe->waiting_writers--; } - if (pipe->inode) - mutex_unlock(&pipe->inode->i_mutex); + if (!spd.nr_pages) + return 0; - if (do_wakeup) { - smp_mb(); - if (waitqueue_active(&pipe->wait)) - wake_up_interruptible(&pipe->wait); - kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); - } + ret = *nonpad_ret = splice_to_pipe(pipe, &spd); + if (ret < 0 || ret < total_len) + return ret; - return ret; + if (read_start + ret == nonpad_end) + ret += padding; + + return ret; } static ssize_t relay_file_splice_read(struct file *in, @@ -1199,7 +1164,6 @@ static ssize_t relay_file_splice_read(struct file *in, if (ret < 0) break; else if (!ret) { - break; if (spliced) break; if (flags & SPLICE_F_NONBLOCK) { From ae976416464b741913a13eea62eb6953ee065733 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 4 Jun 2007 10:00:39 +0200 Subject: [PATCH 409/551] shmem: convert to using splice instead of sendfile() Remove shmem_file_sendfile and resurrect shmem_readpage, as used by tmpfs to support loop and sendfile in 2.4 and 2.5. Now tmpfs can support splice, loop and sendfile in the simplest way, using generic_file_splice_read and generic_file_splice_write (with the aid of shmem_prepare_write). We could make some efficiency tweaks later, if there's a real need; but this is stable and works well as is. Signed-off-by: Hugh Dickins Signed-off-by: Jens Axboe --- mm/shmem.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index b6aae2b33393..0493e4d0bcaa 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1100,9 +1100,9 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, * Normally, filepage is NULL on entry, and either found * uptodate immediately, or allocated and zeroed, or read * in under swappage, which is then assigned to filepage. - * But shmem_prepare_write passes in a locked filepage, - * which may be found not uptodate by other callers too, - * and may need to be copied from the swappage read in. + * But shmem_readpage and shmem_prepare_write pass in a locked + * filepage, which may be found not uptodate by other callers + * too, and may need to be copied from the swappage read in. */ repeat: if (!filepage) @@ -1485,9 +1485,18 @@ static const struct inode_operations shmem_symlink_inode_operations; static const struct inode_operations shmem_symlink_inline_operations; /* - * Normally tmpfs makes no use of shmem_prepare_write, but it - * lets a tmpfs file be used read-write below the loop driver. + * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write; + * but providing them allows a tmpfs file to be used for splice, sendfile, and + * below the loop driver, in the generic fashion that many filesystems support. */ +static int shmem_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL); + unlock_page(page); + return error; +} + static int shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) { @@ -1711,25 +1720,6 @@ static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count return desc.error; } -static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) -{ - read_descriptor_t desc; - - if (!count) - return 0; - - desc.written = 0; - desc.count = count; - desc.arg.data = target; - desc.error = 0; - - do_shmem_file_read(in_file, ppos, &desc, actor); - if (desc.written) - return desc.written; - return desc.error; -} - static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) { struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); @@ -2386,6 +2376,7 @@ static const struct address_space_operations shmem_aops = { .writepage = shmem_writepage, .set_page_dirty = __set_page_dirty_no_writeback, #ifdef CONFIG_TMPFS + .readpage = shmem_readpage, .prepare_write = shmem_prepare_write, .commit_write = simple_commit_write, #endif @@ -2399,7 +2390,8 @@ static const struct file_operations shmem_file_operations = { .read = shmem_file_read, .write = shmem_file_write, .fsync = simple_sync_file, - .sendfile = shmem_file_sendfile, + .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, #endif }; From d6f517568f9f5c26e7404a336c7289d5b4b293ec Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 4 Jun 2007 10:25:05 +0200 Subject: [PATCH 410/551] sendfile: remove bad_sendfile() from bad_file_ops do_sendfile() prefers splice over sendfile, so it should not trigger (directly, at least). Signed-off-by: Jens Axboe --- fs/bad_inode.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 329ee473eede..521ff7caadbd 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -114,12 +114,6 @@ static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl) return -EIO; } -static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) -{ - return -EIO; -} - static ssize_t bad_file_sendpage(struct file *file, struct page *page, int off, size_t len, loff_t *pos, int more) { @@ -182,7 +176,6 @@ static const struct file_operations bad_file_ops = .aio_fsync = bad_file_aio_fsync, .fasync = bad_file_fasync, .lock = bad_file_lock, - .sendfile = bad_file_sendfile, .sendpage = bad_file_sendpage, .get_unmapped_area = bad_file_get_unmapped_area, .check_flags = bad_file_check_flags, From 932cc6d4f7c35bbf70bce8cc865b6033ff49c9c0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 21 Jun 2007 13:10:21 +0200 Subject: [PATCH 411/551] splice: completely document external interface with kerneldoc Also add fs/splice.c as a kerneldoc target with a smaller blurb that should be expanded to better explain the overview of splice. Signed-off-by: Jens Axboe --- Documentation/DocBook/kernel-api.tmpl | 11 +++ fs/splice.c | 109 ++++++++++++++++++++------ 2 files changed, 96 insertions(+), 24 deletions(-) diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 38f88b6ae405..8c5698a8c2e1 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -643,4 +643,15 @@ X!Idrivers/video/console/fonts.c !Edrivers/spi/spi.c + + splice API + ) + splice is a method for moving blocks of data around inside the + kernel, without continually transferring it between the kernel + and user space. + +!Iinclude/linux/splice.h +!Ffs/splice.c + + diff --git a/fs/splice.c b/fs/splice.c index 00850e56280d..d257d666358b 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -153,9 +153,16 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = { .get = generic_pipe_buf_get, }; -/* - * Pipe output worker. This fills a pipe with the information contained - * from splice_pipe_desc(). +/** + * splice_to_pipe - fill passed data into a pipe + * @pipe: pipe to fill + * @spd: data to fill + * + * Description: + * @spd contains a map of pages and len/offset tupples, a long with + * the struct pipe_buf_operations associated with these pages. This + * function will link that data to the pipe. + * */ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) @@ -280,11 +287,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, */ page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages); - /* - * Now fill in the holes: - */ - error = 0; - /* * Lookup the (hopefully) full range of pages we need. */ @@ -292,8 +294,9 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, /* * If find_get_pages_contig() returned fewer pages than we needed, - * allocate the rest. + * allocate the rest and fill in the holes. */ + error = 0; index += spd.nr_pages; while (spd.nr_pages < nr_pages) { /* @@ -455,11 +458,16 @@ fill_it: /** * generic_file_splice_read - splice data from file to a pipe * @in: file to splice from + * @ppos: position in @in * @pipe: pipe to splice to * @len: number of bytes to splice * @flags: splice modifier flags * - * Will read pages from given file and fill them into a pipe. + * Description: + * Will read pages from given file and fill them into a pipe. Can be + * used as long as the address_space operations for the source implements + * a readpage() hook. + * */ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, @@ -648,10 +656,18 @@ out_ret: return ret; } -/* - * Pipe input worker. Most of this logic works like a regular pipe, the - * key here is the 'actor' worker passed in that actually moves the data - * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. +/** + * __splice_from_pipe - splice data from a pipe to given actor + * @pipe: pipe to splice from + * @sd: information to @actor + * @actor: handler that splices the data + * + * Description: + * This function does little more than loop over the pipe and call + * @actor to do the actual moving of a single struct pipe_buffer to + * the desired destination. See pipe_to_file, pipe_to_sendpage, or + * pipe_to_user. + * */ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, splice_actor *actor) @@ -744,6 +760,20 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, } EXPORT_SYMBOL(__splice_from_pipe); +/** + * splice_from_pipe - splice data from a pipe to a file + * @pipe: pipe to splice from + * @out: file to splice to + * @ppos: position in @out + * @len: how many bytes to splice + * @flags: splice modifier flags + * @actor: handler that splices the data + * + * Description: + * See __splice_from_pipe. This function locks the input and output inodes, + * otherwise it's identical to __splice_from_pipe(). + * + */ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags, splice_actor *actor) @@ -774,12 +804,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, * generic_file_splice_write_nolock - generic_file_splice_write without mutexes * @pipe: pipe info * @out: file to write to + * @ppos: position in @out * @len: number of bytes to splice * @flags: splice modifier flags * - * Will either move or copy pages (determined by @flags options) from - * the given pipe inode to the given file. The caller is responsible - * for acquiring i_mutex on both inodes. + * Description: + * Will either move or copy pages (determined by @flags options) from + * the given pipe inode to the given file. The caller is responsible + * for acquiring i_mutex on both inodes. * */ ssize_t @@ -831,11 +863,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock); * generic_file_splice_write - splice data from a pipe to a file * @pipe: pipe info * @out: file to write to + * @ppos: position in @out * @len: number of bytes to splice * @flags: splice modifier flags * - * Will either move or copy pages (determined by @flags options) from - * the given pipe inode to the given file. + * Description: + * Will either move or copy pages (determined by @flags options) from + * the given pipe inode to the given file. * */ ssize_t @@ -886,13 +920,15 @@ EXPORT_SYMBOL(generic_file_splice_write); /** * generic_splice_sendpage - splice data from a pipe to a socket - * @inode: pipe inode + * @pipe: pipe to splice from * @out: socket to write to + * @ppos: position in @out * @len: number of bytes to splice * @flags: splice modifier flags * - * Will send @len bytes from the pipe to a network socket. No data copying - * is involved. + * Description: + * Will send @len bytes from the pipe to a network socket. No data copying + * is involved. * */ ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, @@ -946,8 +982,18 @@ static long do_splice_to(struct file *in, loff_t *ppos, return in->f_op->splice_read(in, ppos, pipe, len, flags); } -/* - * Splices from an input file to an actor, using a 'direct' pipe. +/** + * splice_direct_to_actor - splices data directly between two non-pipes + * @in: file to splice from + * @sd: actor information on where to splice to + * @actor: handles the data splicing + * + * Description: + * This is a special case helper to splice directly between two + * points, without requiring an explicit pipe. Internally an allocated + * pipe is cached in the process, and reused during the life time of + * that process. + * */ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, splice_direct_actor *actor) @@ -1077,6 +1123,21 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags); } +/** + * do_splice_direct - splices data directly between two files + * @in: file to splice from + * @ppos: input file offset + * @out: file to splice to + * @len: number of bytes to splice + * @flags: splice modifier flags + * + * Description: + * For use by do_sendfile(). splice can easily emulate sendfile, but + * doing it in the application would incur an extra system call + * (splice in + splice out, as compared to just sendfile()). So this helper + * can splice directly through a process-private pipe. + * + */ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, size_t len, unsigned int flags) { From d054fe3d10cc1f9aec01378c38caa32dffdd0090 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Fri, 15 Jun 2007 08:16:22 +0200 Subject: [PATCH 412/551] xip sendfile removal This patch removes xip_file_sendfile, the sendfile implementation for xip without replacement. Those customers that use xip on s390 are not using sendfile() as far as we know, and so far s390 is the only platform this could potentially be used on so far. Having sendfile is not a popular feature for execute in place file systems, however we have a working implementation of splice_read() based on fs/splice.c if anyone asks for it. At this point in time, it does not seem preferable to merge splice_read() for xip because it causes extra maintenence effort due to code duplication and it requires struct page behind the xip memory segment. We'd like to get rid of that in favor of supporting flash based embedded platforms (Monta Vista work) soon. Signed-off-by: Carsten Otte Signed-off-by: Jens Axboe --- fs/ext2/file.c | 1 - include/linux/fs.h | 3 --- mm/filemap_xip.c | 22 ---------------------- 3 files changed, 26 deletions(-) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 072a1909b2bc..04afeecaaef3 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -70,7 +70,6 @@ const struct file_operations ext2_xip_file_operations = { .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .sendfile = xip_file_sendfile, }; #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 87c1d3e9d6cb..894620e9402c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1791,9 +1791,6 @@ extern int nonseekable_open(struct inode * inode, struct file * filp); #ifdef CONFIG_FS_XIP extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); -extern ssize_t xip_file_sendfile(struct file *in_file, loff_t *ppos, - size_t count, read_actor_t actor, - void *target); extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma); extern ssize_t xip_file_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index fa360e566d88..65ffc321f0c0 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c @@ -159,28 +159,6 @@ xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) } EXPORT_SYMBOL_GPL(xip_file_read); -ssize_t -xip_file_sendfile(struct file *in_file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) -{ - read_descriptor_t desc; - - if (!count) - return 0; - - desc.written = 0; - desc.count = count; - desc.arg.data = target; - desc.error = 0; - - do_xip_mapping_read(in_file->f_mapping, &in_file->f_ra, in_file, - ppos, &desc, actor); - if (desc.written) - return desc.written; - return desc.error; -} -EXPORT_SYMBOL_GPL(xip_file_sendfile); - /* * __xip_unmap is invoked from xip_unmap and * xip_write From d96e6e71647846e0dab097efd9b8bf3a3a556dca Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 11 Jun 2007 12:18:52 +0200 Subject: [PATCH 413/551] Remove remnants of sendfile() There are now zero users of .sendfile() in the kernel, so kill it from the file_operations structure and in do_sendfile(). Signed-off-by: Jens Axboe --- fs/read_write.c | 26 +++++++++++--------------- include/linux/fs.h | 3 +-- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 2527cf035b0e..507ddff48a9a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -724,8 +724,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, in_inode = in_file->f_path.dentry->d_inode; if (!in_inode) goto fput_in; - if (!in_file->f_op || (!in_file->f_op->sendfile && - !in_file->f_op->splice_read)) + if (!in_file->f_op || !in_file->f_op->splice_read) goto fput_in; retval = -ESPIPE; if (!ppos) @@ -778,21 +777,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, count = max - pos; } - if (in_file->f_op->splice_read) { - fl = 0; + fl = 0; #if 0 - /* - * We need to debate whether we can enable this or not. The - * man page documents EAGAIN return for the output at least, - * and the application is arguably buggy if it doesn't expect - * EAGAIN on a non-blocking file descriptor. - */ - if (in_file->f_flags & O_NONBLOCK) - fl = SPLICE_F_NONBLOCK; + /* + * We need to debate whether we can enable this or not. The + * man page documents EAGAIN return for the output at least, + * and the application is arguably buggy if it doesn't expect + * EAGAIN on a non-blocking file descriptor. + */ + if (in_file->f_flags & O_NONBLOCK) + fl = SPLICE_F_NONBLOCK; #endif - retval = do_splice_direct(in_file, ppos, out_file, count, fl); - } else - retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); + retval = do_splice_direct(in_file, ppos, out_file, count, fl); if (retval > 0) { add_rchar(current, retval); diff --git a/include/linux/fs.h b/include/linux/fs.h index 894620e9402c..4f0b3bf5983c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1054,7 +1054,7 @@ struct block_device_operations { }; /* - * "descriptor" for what we're up to with a read for sendfile(). + * "descriptor" for what we're up to with a read. * This allows us to use the same read code yet * have multiple different users of the data that * we read from a file. @@ -1105,7 +1105,6 @@ struct file_operations { int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); - ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); From cac36bb06efe4880234524e117e0e712b10b1f16 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 14 Jun 2007 13:10:48 +0200 Subject: [PATCH 414/551] pipe: change the ->pin() operation to ->confirm() The name 'pin' was badly chosen, it doesn't pin a pipe buffer in the most commonly used sense in the kernel. So change the name to 'confirm', after debating this issue with Hugh Dickins a bit. A good return from ->confirm() means that the buffer is really there, and that the contents are good. Signed-off-by: Jens Axboe --- drivers/block/loop.c | 2 +- fs/nfsd/vfs.c | 2 +- fs/ocfs2/file.c | 4 ++-- fs/pipe.c | 9 +++++---- fs/splice.c | 14 +++++++------- include/linux/pipe_fs_i.h | 9 +++++---- kernel/relay.c | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 08f53df03e8c..4503290da407 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -412,7 +412,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, size_t size; int ret; - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (unlikely(ret)) return ret; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8176fbf5c006..8604e35bd48e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -815,7 +815,7 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, size_t size; int ret; - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (unlikely(ret)) return ret; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 44c2e2afa465..4979b6675717 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1583,7 +1583,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe, ssize_t copied = 0; struct ocfs2_splice_write_priv sp; - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (ret) goto out; @@ -1604,7 +1604,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe, * might enter ocfs2_buffered_write_cluster() more * than once, so keep track of our progress here. */ - copied = ocfs2_buffered_write_cluster(sd->file, + copied = ocfs2_buffered_write_cluster(sd->u.file, (loff_t)sd->pos + total, count, ocfs2_map_and_write_splice_data, diff --git a/fs/pipe.c b/fs/pipe.c index 3a89592bdf57..3694af10dd2c 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -203,7 +203,8 @@ void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf) page_cache_get(buf->page); } -int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) +int generic_pipe_buf_confirm(struct pipe_inode_info *info, + struct pipe_buffer *buf) { return 0; } @@ -212,7 +213,7 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = { .can_merge = 1, .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, - .pin = generic_pipe_buf_pin, + .confirm = generic_pipe_buf_confirm, .release = anon_pipe_buf_release, .steal = generic_pipe_buf_steal, .get = generic_pipe_buf_get, @@ -252,7 +253,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, if (chars > total_len) chars = total_len; - error = ops->pin(pipe, buf); + error = ops->confirm(pipe, buf); if (error) { if (!ret) error = ret; @@ -373,7 +374,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, int error, atomic = 1; void *addr; - error = ops->pin(pipe, buf); + error = ops->confirm(pipe, buf); if (error) goto out; diff --git a/fs/splice.c b/fs/splice.c index d257d666358b..c804121601b0 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -85,8 +85,8 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, buf->flags &= ~PIPE_BUF_FLAG_LRU; } -static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe, - struct pipe_buffer *buf) +static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) { struct page *page = buf->page; int err; @@ -127,7 +127,7 @@ static const struct pipe_buf_operations page_cache_pipe_buf_ops = { .can_merge = 0, .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, - .pin = page_cache_pipe_buf_pin, + .confirm = page_cache_pipe_buf_confirm, .release = page_cache_pipe_buf_release, .steal = page_cache_pipe_buf_steal, .get = generic_pipe_buf_get, @@ -147,7 +147,7 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = { .can_merge = 0, .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, - .pin = generic_pipe_buf_pin, + .confirm = generic_pipe_buf_confirm, .release = page_cache_pipe_buf_release, .steal = user_page_pipe_buf_steal, .get = generic_pipe_buf_get, @@ -525,7 +525,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, loff_t pos = sd->pos; int ret, more; - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (!ret) { more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; @@ -569,7 +569,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, /* * make sure the data in this buffer is uptodate */ - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (unlikely(ret)) return ret; @@ -1341,7 +1341,7 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf, char *src; int ret; - ret = buf->ops->pin(pipe, buf); + ret = buf->ops->confirm(pipe, buf); if (unlikely(ret)) return ret; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 4409167b9eb2..cc09fe89bf07 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -35,20 +35,21 @@ struct pipe_inode_info { /* * Note on the nesting of these functions: * - * ->pin() + * ->confirm() * ->steal() * ... * ->map() * ... * ->unmap() * - * That is, ->map() must be called on a pinned buffer, same goes for ->steal(). + * That is, ->map() must be called on a confirmed buffer, + * same goes for ->steal(). */ struct pipe_buf_operations { int can_merge; void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); - int (*pin)(struct pipe_inode_info *, struct pipe_buffer *); + int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *); void (*release)(struct pipe_inode_info *, struct pipe_buffer *); int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); void (*get)(struct pipe_inode_info *, struct pipe_buffer *); @@ -69,7 +70,7 @@ void __free_pipe_info(struct pipe_inode_info *); void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); -int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); +int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); #endif diff --git a/kernel/relay.c b/kernel/relay.c index dd3bc5b69035..3b299fb3855c 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1055,7 +1055,7 @@ static struct pipe_buf_operations relay_pipe_buf_ops = { .can_merge = 0, .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, - .pin = generic_pipe_buf_pin, + .confirm = generic_pipe_buf_confirm, .release = relay_pipe_buf_release, .steal = generic_pipe_buf_steal, .get = generic_pipe_buf_get, From 0845718dafea3e16041d270c256e8516acf4e13d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Jun 2007 20:51:32 +0200 Subject: [PATCH 415/551] pipe: add documentation and comments As per Andrew Mortons request, here's a set of documentation for the generic pipe_buf_operations hooks, the pipe, and pipe_buffer structures. Signed-off-by: Jens Axboe --- fs/pipe.c | 61 ++++++++++++++++++++++++++++++- fs/splice.c | 4 ++ include/linux/pipe_fs_i.h | 77 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 3694af10dd2c..d007830d9c87 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -164,6 +164,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, page_cache_release(page); } +/** + * generic_pipe_buf_map - virtually map a pipe buffer + * @pipe: the pipe that the buffer belongs to + * @buf: the buffer that should be mapped + * @atomic: whether to use an atomic map + * + * Description: + * This function returns a kernel virtual address mapping for the + * passed in @pipe_buffer. If @atomic is set, an atomic map is provided + * and the caller has to be careful not to fault before calling + * the unmap function. + * + * Note that this function occupies KM_USER0 if @atomic != 0. + */ void *generic_pipe_buf_map(struct pipe_inode_info *pipe, struct pipe_buffer *buf, int atomic) { @@ -175,6 +189,15 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe, return kmap(buf->page); } +/** + * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer + * @pipe: the pipe that the buffer belongs to + * @buf: the buffer that should be unmapped + * @map_data: the data that the mapping function returned + * + * Description: + * This function undoes the mapping that ->map() provided. + */ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf, void *map_data) { @@ -185,11 +208,28 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, kunmap(buf->page); } +/** + * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer + * @pipe: the pipe that the buffer belongs to + * @buf: the buffer to attempt to steal + * + * Description: + * This function attempts to steal the @struct page attached to + * @buf. If successful, this function returns 0 and returns with + * the page locked. The caller may then reuse the page for whatever + * he wishes, the typical use is insertion into a different file + * page cache. + */ int generic_pipe_buf_steal(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct page *page = buf->page; + /* + * A reference of one is golden, that means that the owner of this + * page is the only one holding a reference to it. lock the page + * and return OK. + */ if (page_count(page) == 1) { lock_page(page); return 0; @@ -198,11 +238,30 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe, return 1; } -void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf) +/** + * generic_pipe_buf_get - get a reference to a @struct pipe_buffer + * @pipe: the pipe that the buffer belongs to + * @buf: the buffer to get a reference to + * + * Description: + * This function grabs an extra reference to @buf. It's used in + * in the tee() system call, when we duplicate the buffers in one + * pipe into another. + */ +void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { page_cache_get(buf->page); } +/** + * generic_pipe_buf_confirm - verify contents of the pipe buffer + * @pipe: the pipe that the buffer belongs to + * @buf: the buffer to confirm + * + * Description: + * This function does nothing, because the generic pipe code uses + * pages that are always good when inserted into the pipe. + */ int generic_pipe_buf_confirm(struct pipe_inode_info *info, struct pipe_buffer *buf) { diff --git a/fs/splice.c b/fs/splice.c index c804121601b0..ed2ce995475c 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -85,6 +85,10 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, buf->flags &= ~PIPE_BUF_FLAG_LRU; } +/* + * Check whether the contents of buf is OK to access. Since the content + * is a page cache page, IO may be in flight. + */ static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index cc09fe89bf07..8e4120285f72 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -9,6 +9,15 @@ #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ +/** + * struct pipe_buffer - a linux kernel pipe buffer + * @page: the page containing the data for the pipe buffer + * @offset: offset of data inside the @page + * @len: length of data inside the @page + * @ops: operations associated with this buffer. See @pipe_buf_operations. + * @flags: pipe buffer flags. See above. + * @private: private data owned by the ops. + **/ struct pipe_buffer { struct page *page; unsigned int offset, len; @@ -17,6 +26,22 @@ struct pipe_buffer { unsigned long private; }; +/** + * struct pipe_inode_info - a linux kernel pipe + * @wait: reader/writer wait point in case of empty/full pipe + * @nrbufs: the number of non-empty pipe buffers in this pipe + * @curbuf: the current pipe buffer entry + * @tmp_page: cached released page + * @readers: number of current readers of this pipe + * @writers: number of current writers of this pipe + * @waiting_writers: number of writers blocked waiting for room + * @r_counter: reader counter + * @w_counter: writer counter + * @fasync_readers: reader side fasync + * @fasync_writers: writer side fasync + * @inode: inode this pipe is attached to + * @bufs: the circular array of pipe buffers + **/ struct pipe_inode_info { wait_queue_head_t wait; unsigned int nrbufs, curbuf; @@ -43,15 +68,65 @@ struct pipe_inode_info { * ->unmap() * * That is, ->map() must be called on a confirmed buffer, - * same goes for ->steal(). + * same goes for ->steal(). See below for the meaning of each + * operation. Also see kerneldoc in fs/pipe.c for the pipe + * and generic variants of these hooks. */ struct pipe_buf_operations { + /* + * This is set to 1, if the generic pipe read/write may coalesce + * data into an existing buffer. If this is set to 0, a new pipe + * page segment is always used for new data. + */ int can_merge; + + /* + * ->map() returns a virtual address mapping of the pipe buffer. + * The last integer flag reflects whether this should be an atomic + * mapping or not. The atomic map is faster, however you can't take + * page faults before calling ->unmap() again. So if you need to eg + * access user data through copy_to/from_user(), then you must get + * a non-atomic map. ->map() uses the KM_USER0 atomic slot for + * atomic maps, so you can't map more than one pipe_buffer at once + * and you have to be careful if mapping another page as source + * or destination for a copy (IOW, it has to use something else + * than KM_USER0). + */ void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); + + /* + * Undoes ->map(), finishes the virtual mapping of the pipe buffer. + */ void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); + + /* + * ->confirm() verifies that the data in the pipe buffer is there + * and that the contents are good. If the pages in the pipe belong + * to a file system, we may need to wait for IO completion in this + * hook. Returns 0 for good, or a negative error value in case of + * error. + */ int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *); + + /* + * When the contents of this pipe buffer has been completely + * consumed by a reader, ->release() is called. + */ void (*release)(struct pipe_inode_info *, struct pipe_buffer *); + + /* + * Attempt to take ownership of the pipe buffer and its contents. + * ->steal() returns 0 for success, in which case the contents + * of the pipe (the buf->page) is locked and now completely owned + * by the caller. The page may then be transferred to a different + * mapping, the most often used case is insertion into different + * file address space cache. + */ int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); + + /* + * Get a reference to the pipe buffer. + */ void (*get)(struct pipe_inode_info *, struct pipe_buffer *); }; From d197e6921843932b5d8ecf47d23fcac62e73b19a Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 10 Jul 2007 11:24:07 +0200 Subject: [PATCH 416/551] [S390] vmcp cleanup No need to use the "&" prefix and, since you're calling nonseekable_open(), there is no need to use no_llseek(). Signed-off-by: Robert P. J. Day Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmcp.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index fce3dac5cb3e..82e6a6b253eb 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static const struct file_operations vmcp_fops = { .owner = THIS_MODULE, - .open = &vmcp_open, - .release = &vmcp_release, - .read = &vmcp_read, - .llseek = &no_llseek, - .write = &vmcp_write, - .unlocked_ioctl = &vmcp_ioctl, - .compat_ioctl = &vmcp_ioctl + .open = vmcp_open, + .release = vmcp_release, + .read = vmcp_read, + .write = vmcp_write, + .unlocked_ioctl = vmcp_ioctl, + .compat_ioctl = vmcp_ioctl }; static struct miscdevice vmcp_dev = { From bccdbdc9bd7db3a32c14d8a47f1fb66e3de3c92f Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Tue, 10 Jul 2007 11:24:08 +0200 Subject: [PATCH 417/551] [S390] Fixed comment typo. Signed-off-by: Ralph Wuerthner Signed-off-by: Martin Schwidefsky --- arch/s390/crypto/crypt_s390.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 2775d2618332..95f5160df27f 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h @@ -24,7 +24,7 @@ #define CRYPT_S390_PRIORITY 300 #define CRYPT_S390_COMPOSITE_PRIORITY 400 -/* s930 cryptographic operations */ +/* s390 cryptographic operations */ enum crypt_s390_operations { CRYPT_S390_KM = 0x0100, CRYPT_S390_KMC = 0x0200, From 05dd25307ca67cbfa0207bbba2e6c79fa97d125b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:09 +0200 Subject: [PATCH 418/551] [S390] sclp: introduce some new interfaces. Introduce some new interfaces so that random subsystems don't have to mess around with sclp internal structures. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 44 ++++---------- arch/s390/kernel/ipl.c | 17 +++--- drivers/s390/char/sclp.h | 7 +++ drivers/s390/char/sclp_info.c | 110 ++++++++++++++++++++++++---------- include/asm-s390/sclp.h | 46 +++++--------- 5 files changed, 122 insertions(+), 102 deletions(-) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 50538e545618..9fcf3f1f47b6 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -171,37 +171,6 @@ static inline int memory_fast_detect(void) } #endif -#define ADDR2G (1UL << 31) - -static noinline __init unsigned long sclp_memory_detect(void) -{ - struct sclp_readinfo_sccb *sccb; - unsigned long long memsize; - - sccb = &s390_readinfo_sccb; - - if (sccb->header.response_code != 0x10) - return 0; - - if (sccb->rnsize) - memsize = sccb->rnsize << 20; - else - memsize = sccb->rnsize2 << 20; - if (sccb->rnmax) - memsize *= sccb->rnmax; - else - memsize *= sccb->rnmax2; -#ifndef CONFIG_64BIT - /* - * Can't deal with more than 2G in 31 bit addressing mode, so - * limit the value in order to avoid strange side effects. - */ - if (memsize > ADDR2G) - memsize = ADDR2G; -#endif - return (unsigned long) memsize; -} - static inline __init unsigned long __tprot(unsigned long addr) { int cc = -1; @@ -218,6 +187,7 @@ static inline __init unsigned long __tprot(unsigned long addr) /* Checking memory in 128KB increments. */ #define CHUNK_INCR (1UL << 17) +#define ADDR2G (1UL << 31) static noinline __init void find_memory_chunks(unsigned long memsize) { @@ -293,7 +263,7 @@ static noinline __init void setup_lowcore_early(void) */ void __init startup_init(void) { - unsigned long memsize; + unsigned long long memsize; ipl_save_parameters(); clear_bss_section(); @@ -306,7 +276,15 @@ void __init startup_init(void) setup_lowcore_early(); sclp_readinfo_early(); memsize = sclp_memory_detect(); +#ifndef CONFIG_64BIT + /* + * Can't deal with more than 2G in 31 bit addressing mode, so + * limit the value in order to avoid strange side effects. + */ + if (memsize > ADDR2G) + memsize = ADDR2G; +#endif if (memory_fast_detect() < 0) - find_memory_chunks(memsize); + find_memory_chunks((unsigned long) memsize); lockdep_on(); } diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 367caf92ea78..82b131ddd7ff 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -25,10 +25,6 @@ #define IPL_PARM_BLOCK_VERSION 0 -#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10) -#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) -#define SCCB_FLAG (s390_readinfo_sccb.flags) - #define IPL_UNKNOWN_STR "unknown" #define IPL_CCW_STR "ccw" #define IPL_FCP_STR "fcp" @@ -146,6 +142,8 @@ static struct ipl_parameter_block *dump_block_ccw; static enum shutdown_action on_panic_action = SHUTDOWN_STOP; +static struct sclp_ipl_info sclp_ipl_info; + int diag308(unsigned long subcode, void *addr) { register unsigned long _addr asm("0") = (unsigned long) addr; @@ -375,9 +373,9 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) { char loadparm[LOADPARM_LEN + 1] = {}; - if (!SCCB_VALID) + if (!sclp_ipl_info.is_valid) return sprintf(page, "#unknown#\n"); - memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); + memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN); EBCASC(loadparm, LOADPARM_LEN); strstrip(loadparm); return sprintf(page, "%s\n", loadparm); @@ -910,9 +908,9 @@ static int __init reipl_ccw_init(void) reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; /* check if read scp info worked and set loadparm */ - if (SCCB_VALID) + if (sclp_ipl_info.is_valid) memcpy(reipl_block_ccw->ipl_info.ccw.load_param, - SCCB_LOADPARM, LOADPARM_LEN); + &sclp_ipl_info.loadparm, LOADPARM_LEN); else /* read scp info failed: set empty loadparm (EBCDIC blanks) */ memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, @@ -1007,7 +1005,7 @@ static int __init dump_fcp_init(void) { int rc; - if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) + if (!sclp_ipl_info.has_dump) return 0; /* LDIPL DUMP is not installed */ if (!diag308_set_works) return 0; @@ -1088,6 +1086,7 @@ static int __init s390_ipl_init(void) { int rc; + sclp_get_ipl_info(&sclp_ipl_info); reipl_probe(); rc = ipl_init(); if (rc) diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index dbb99d1b6f57..cb5888f79007 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -72,6 +72,13 @@ typedef unsigned int sclp_cmdw_t; typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ +struct sccb_header { + u16 length; + u8 function_code; + u8 control_mask[3]; + u16 response_code; +} __attribute__((packed)); + struct gds_subvector { u8 length; u8 key; diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c index 7bcbe643b087..7d21dbb12fcd 100644 --- a/drivers/s390/char/sclp_info.c +++ b/drivers/s390/char/sclp_info.c @@ -11,47 +11,97 @@ #include #include "sclp.h" -struct sclp_readinfo_sccb s390_readinfo_sccb; +struct sclp_readinfo_sccb { + struct sccb_header header; /* 0-7 */ + u16 rnmax; /* 8-9 */ + u8 rnsize; /* 10 */ + u8 _reserved0[24 - 11]; /* 11-23 */ + u8 loadparm[8]; /* 24-31 */ + u8 _reserved1[48 - 32]; /* 32-47 */ + u64 facilities; /* 48-55 */ + u8 _reserved2[91 - 56]; /* 56-90 */ + u8 flags; /* 91 */ + u8 _reserved3[100 - 92]; /* 92-99 */ + u32 rnsize2; /* 100-103 */ + u64 rnmax2; /* 104-111 */ + u8 _reserved4[4096 - 112]; /* 112-4095 */ +} __attribute__((packed, aligned(4096))); + +static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; +static int __initdata early_readinfo_sccb_valid; void __init sclp_readinfo_early(void) { - sclp_cmdw_t command; - struct sccb_header *sccb; int ret; + int i; + struct sclp_readinfo_sccb *sccb; + sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, + SCLP_CMDW_READ_SCP_INFO}; - __ctl_set_bit(0, 9); /* enable service signal subclass mask */ - - sccb = &s390_readinfo_sccb.header; - command = SCLP_CMDW_READ_SCP_INFO_FORCED; - while (1) { - u16 response; - - memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); - sccb->length = sizeof(s390_readinfo_sccb); - sccb->control_mask[2] = 0x80; - - ret = sclp_service_call(command, &s390_readinfo_sccb); - - if (ret == -EIO) - goto out; - if (ret == -EBUSY) - continue; + /* Enable service signal subclass mask. */ + __ctl_set_bit(0, 9); + sccb = &early_readinfo_sccb; + for (i = 0; i < ARRAY_SIZE(commands); i++) { + do { + memset(sccb, 0, sizeof(*sccb)); + sccb->header.length = sizeof(*sccb); + sccb->header.control_mask[2] = 0x80; + ret = sclp_service_call(commands[i], sccb); + } while (ret == -EBUSY); + if (ret) + break; __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | PSW_MASK_WAIT | PSW_DEFAULT_KEY); local_irq_disable(); + /* + * Contents of the sccb might have changed + * therefore a barrier is needed. + */ barrier(); - - response = sccb->response_code; - - if (response == 0x10) + if (sccb->header.response_code == 0x10) { + early_readinfo_sccb_valid = 1; break; - - if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) + } + if (sccb->header.response_code != 0x1f0) break; - - command = SCLP_CMDW_READ_SCP_INFO; } -out: - __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ + /* Disable service signal subclass mask again. */ + __ctl_clear_bit(0, 9); +} + +unsigned long long __init sclp_memory_detect(void) +{ + unsigned long long memsize; + struct sclp_readinfo_sccb *sccb; + + if (!early_readinfo_sccb_valid) + return 0; + sccb = &early_readinfo_sccb; + if (sccb->rnsize) + memsize = sccb->rnsize << 20; + else + memsize = sccb->rnsize2 << 20; + if (sccb->rnmax) + memsize *= sccb->rnmax; + else + memsize *= sccb->rnmax2; + return memsize; +} + +/* + * This function will be called after sclp_memory_detect(), which gets called + * early from early.c code. Therefore the sccb should have valid contents. + */ +void __init sclp_get_ipl_info(struct sclp_ipl_info *info) +{ + struct sclp_readinfo_sccb *sccb; + + if (!early_readinfo_sccb_valid) + return; + sccb = &early_readinfo_sccb; + info->is_valid = 1; + if (sccb->flags & 0x2) + info->has_dump = 1; + memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); } diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index 21ed64773210..ddfaa8db47be 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h @@ -11,29 +11,6 @@ #include #include -struct sccb_header { - u16 length; - u8 function_code; - u8 control_mask[3]; - u16 response_code; -} __attribute__((packed)); - -#define LOADPARM_LEN 8 - -struct sclp_readinfo_sccb { - struct sccb_header header; /* 0-7 */ - u16 rnmax; /* 8-9 */ - u8 rnsize; /* 10 */ - u8 _reserved0[24 - 11]; /* 11-23 */ - u8 loadparm[LOADPARM_LEN]; /* 24-31 */ - u8 _reserved1[91 - 32]; /* 32-90 */ - u8 flags; /* 91 */ - u8 _reserved2[100 - 92]; /* 92-99 */ - u32 rnsize2; /* 100-103 */ - u64 rnmax2; /* 104-111 */ - u8 _reserved3[4096 - 112]; /* 112-4095 */ -} __attribute__((packed, aligned(4096))); - #define SCLP_CHP_INFO_MASK_SIZE 32 struct sclp_chp_info { @@ -42,12 +19,21 @@ struct sclp_chp_info { u8 configured[SCLP_CHP_INFO_MASK_SIZE]; }; -extern struct sclp_readinfo_sccb s390_readinfo_sccb; -extern void sclp_readinfo_early(void); -extern int sclp_sdias_blk_count(void); -extern int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); -extern int sclp_chp_configure(struct chp_id chpid); -extern int sclp_chp_deconfigure(struct chp_id chpid); -extern int sclp_chp_read_info(struct sclp_chp_info *info); +#define LOADPARM_LEN 8 + +struct sclp_ipl_info { + int is_valid; + int has_dump; + char loadparm[LOADPARM_LEN]; +}; + +void sclp_readinfo_early(void); +unsigned long long sclp_memory_detect(void); +int sclp_sdias_blk_count(void); +int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); +int sclp_chp_configure(struct chp_id chpid); +int sclp_chp_deconfigure(struct chp_id chpid); +int sclp_chp_read_info(struct sclp_chp_info *info); +void sclp_get_ipl_info(struct sclp_ipl_info *info); #endif /* _ASM_S390_SCLP_H */ From 83119ad4a1ceacd99f380086c2855ae2c4268afc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:10 +0200 Subject: [PATCH 419/551] [S390] sclp: Test facility list before executing a service call. Check if a command is available before executing. Saves some superfluous service calls that won't succeed anyway. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 1 + drivers/s390/char/sclp.h | 5 +++++ drivers/s390/char/sclp_chp.c | 4 ++++ drivers/s390/char/sclp_info.c | 9 +++++++++ include/asm-s390/sclp.h | 1 + 5 files changed, 20 insertions(+) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 9fcf3f1f47b6..e6289ee74ecd 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -275,6 +275,7 @@ void __init startup_init(void) sort_main_extable(); setup_lowcore_early(); sclp_readinfo_early(); + sclp_facilities_detect(); memsize = sclp_memory_detect(); #ifndef CONFIG_64BIT /* diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index cb5888f79007..c7318a125852 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -79,6 +79,11 @@ struct sccb_header { u16 response_code; } __attribute__((packed)); +extern u64 sclp_facilities; + +#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) +#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) + struct gds_subvector { u8 length; u8 key; diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c index a66b914519b5..c68f5e7e63a0 100644 --- a/drivers/s390/char/sclp_chp.c +++ b/drivers/s390/char/sclp_chp.c @@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd) struct chp_cfg_data *data; int rc; + if (!SCLP_HAS_CHP_RECONFIG) + return -EOPNOTSUPP; /* Prepare sccb. */ data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!data) @@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info) struct chp_info_data *data; int rc; + if (!SCLP_HAS_CHP_INFO) + return -EOPNOTSUPP; /* Prepare sccb. */ data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!data) diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c index 7d21dbb12fcd..a1136e052750 100644 --- a/drivers/s390/char/sclp_info.c +++ b/drivers/s390/char/sclp_info.c @@ -30,6 +30,8 @@ struct sclp_readinfo_sccb { static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; static int __initdata early_readinfo_sccb_valid; +u64 sclp_facilities; + void __init sclp_readinfo_early(void) { int ret; @@ -70,6 +72,13 @@ void __init sclp_readinfo_early(void) __ctl_clear_bit(0, 9); } +void __init sclp_facilities_detect(void) +{ + if (!early_readinfo_sccb_valid) + return; + sclp_facilities = early_readinfo_sccb.facilities; +} + unsigned long long __init sclp_memory_detect(void) { unsigned long long memsize; diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index ddfaa8db47be..cb9faf1ea5cf 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h @@ -28,6 +28,7 @@ struct sclp_ipl_info { }; void sclp_readinfo_early(void); +void sclp_facilities_detect(void); unsigned long long sclp_memory_detect(void); int sclp_sdias_blk_count(void); int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); From bf1a95a225c1349846274caebdca1bb8d20d5853 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Tue, 10 Jul 2007 11:24:11 +0200 Subject: [PATCH 420/551] [S390] fixed cdl-format detection. CDL formated DASDs are now detected correctly even if no VOL1 label is on the disk. This prevents possible loss of data. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- fs/partitions/ibm.c | 159 ++++++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 66 deletions(-) diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 9f7ad4244f63..1e064c4a4f86 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c @@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { int blocksize, offset, size,res; loff_t i_size; - dasd_information_t *info; + dasd_information2_t *info; struct hd_geometry *geo; char type[5] = {0,}; char name[7] = {0,}; @@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) if (i_size == 0) goto out_exit; - if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) + info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); + if (info == NULL) goto out_exit; - if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) + geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); + if (geo == NULL) goto out_nogeo; - if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) + label = kmalloc(sizeof(union label_t), GFP_KERNEL); + if (label == NULL) goto out_nolab; - if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || + if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) goto out_freeall; @@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) res = 1; /* - * Three different types: CMS1, VOL1 and LNX1/unlabeled + * Three different formats: LDL, CDL and unformated disk + * + * identified by info->format + * + * unformated disks we do not have to care about */ - if (strncmp(type, "CMS1", 4) == 0) { - /* - * VM style CMS1 labeled disk - */ - if (label->cms.disk_offset != 0) { - printk("CMS1/%8s(MDSK):", name); - /* disk is reserved minidisk */ - blocksize = label->cms.block_size; - offset = label->cms.disk_offset; - size = (label->cms.block_count - 1) * (blocksize >> 9); + if (info->format == DASD_FORMAT_LDL) { + if (strncmp(type, "CMS1", 4) == 0) { + /* + * VM style CMS1 labeled disk + */ + if (label->cms.disk_offset != 0) { + printk("CMS1/%8s(MDSK):", name); + /* disk is reserved minidisk */ + blocksize = label->cms.block_size; + offset = label->cms.disk_offset; + size = (label->cms.block_count - 1) + * (blocksize >> 9); + } else { + printk("CMS1/%8s:", name); + offset = (info->label_block + 1); + size = i_size >> 9; + } } else { - printk("CMS1/%8s:", name); + /* + * Old style LNX1 or unlabeled disk + */ + if (strncmp(type, "LNX1", 4) == 0) + printk ("LNX1/%8s:", name); + else + printk("(nonl)"); offset = (info->label_block + 1); size = i_size >> 9; } put_partition(state, 1, offset*(blocksize >> 9), - size-offset*(blocksize >> 9)); - } else if ((strncmp(type, "VOL1", 4) == 0) && - (!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) { + size-offset*(blocksize >> 9)); + } else if (info->format == DASD_FORMAT_CDL) { /* - * New style VOL1 labeled disk + * New style CDL formatted disk */ unsigned int blk; int counter; - printk("VOL1/%8s:", name); + /* + * check if VOL1 label is available + * if not, something is wrong, skipping partition detection + */ + if (strncmp(type, "VOL1", 4) == 0) { + printk("VOL1/%8s:", name); + /* + * get block number and read then go through format1 + * labels + */ + blk = cchhb2blk(&label->vol.vtoc, geo) + 1; + counter = 0; + data = read_dev_sector(bdev, blk * (blocksize/512), + §); + while (data != NULL) { + struct vtoc_format1_label f1; - /* get block number and read then go through format1 labels */ - blk = cchhb2blk(&label->vol.vtoc, geo) + 1; - counter = 0; - while ((data = read_dev_sector(bdev, blk*(blocksize/512), - §)) != NULL) { - struct vtoc_format1_label f1; + memcpy(&f1, data, + sizeof(struct vtoc_format1_label)); + put_dev_sector(sect); - memcpy(&f1, data, sizeof(struct vtoc_format1_label)); - put_dev_sector(sect); + /* skip FMT4 / FMT5 / FMT7 labels */ + if (f1.DS1FMTID == _ascebc['4'] + || f1.DS1FMTID == _ascebc['5'] + || f1.DS1FMTID == _ascebc['7']) { + blk++; + data = read_dev_sector(bdev, blk * + (blocksize/512), + §); + continue; + } - /* skip FMT4 / FMT5 / FMT7 labels */ - if (f1.DS1FMTID == _ascebc['4'] - || f1.DS1FMTID == _ascebc['5'] - || f1.DS1FMTID == _ascebc['7']) { - blk++; - continue; + /* only FMT1 valid at this point */ + if (f1.DS1FMTID != _ascebc['1']) + break; + + /* OK, we got valid partition data */ + offset = cchh2blk(&f1.DS1EXT1.llimit, geo); + size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - + offset + geo->sectors; + if (counter >= state->limit) + break; + put_partition(state, counter + 1, + offset * (blocksize >> 9), + size * (blocksize >> 9)); + counter++; + blk++; + data = read_dev_sector(bdev, + blk * (blocksize/512), + §); } - /* only FMT1 valid at this point */ - if (f1.DS1FMTID != _ascebc['1']) - break; + if (!data) + /* Are we not supposed to report this ? */ + goto out_readerr; + } else + printk(KERN_WARNING "Warning, expected Label VOL1 not " + "found, treating as CDL formated Disk"); - /* OK, we got valid partition data */ - offset = cchh2blk(&f1.DS1EXT1.llimit, geo); - size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - - offset + geo->sectors; - if (counter >= state->limit) - break; - put_partition(state, counter + 1, - offset * (blocksize >> 9), - size * (blocksize >> 9)); - counter++; - blk++; - } - if (!data) - /* Are we not supposed to report this ? */ - goto out_readerr; - } else { - /* - * Old style LNX1 or unlabeled disk - */ - if (strncmp(type, "LNX1", 4) == 0) - printk ("LNX1/%8s:", name); - else - printk("(nonl)/%8s:", name); - offset = (info->label_block + 1); - size = i_size >> 9; - put_partition(state, 1, offset*(blocksize >> 9), - size-offset*(blocksize >> 9)); } printk("\n"); From d9f774d439cda5b46324221a47e6aaf7dc2f77cc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:12 +0200 Subject: [PATCH 421/551] [S390] zcore: Fix __user annotation. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/zcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 4e711a985d59..3712ede16723 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count) return rc; } -static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) +static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) { static char buf[4096]; int offs = 0, size; From 285f67227b63309d699f5bda25ba34962503398f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:13 +0200 Subject: [PATCH 422/551] [S390] smp: Merge smp_count_cpus() and smp_get_save_areas(). Merge smp_count_cpus() and smp_get_save_areas() so we save a loop over all potentially present cpus. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 63 ++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 42 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8ff2feaf9b00..182c085ae4dd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ __attribute__((__section__(".data"))); -static void __init smp_get_save_areas(void) +static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { - unsigned int cpu, cpu_num, rc; - __u16 boot_cpu_addr; - if (ipl_info.type != IPL_TYPE_FCP_DUMP) return; - boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; - cpu_num = 1; - for (cpu = 0; cpu <= 65535; cpu++) { - if ((u16) cpu == boot_cpu_addr) - continue; - __cpu_logical_map[1] = (__u16) cpu; - if (signal_processor(1, sigp_sense) == sigp_not_operational) - continue; - if (cpu_num >= NR_CPUS) { - printk("WARNING: Registers for cpu %i are not " - "saved, since dump kernel was compiled with" - "NR_CPUS=%i!\n", cpu_num, NR_CPUS); - continue; - } - zfcpdump_save_areas[cpu_num] = - alloc_bootmem(sizeof(union save_area)); - while (1) { - rc = signal_processor(1, sigp_stop_and_store_status); - if (rc != sigp_busy) - break; - cpu_relax(); - } - memcpy(zfcpdump_save_areas[cpu_num], - (void *)(unsigned long) store_prefix() + - SAVE_AREA_BASE, SAVE_AREA_SIZE); -#ifdef __s390x__ - /* copy original prefix register */ - zfcpdump_save_areas[cpu_num]->s390x.pref_reg = - zfcpdump_prefix_array[cpu_num]; -#endif - cpu_num++; + if (cpu >= NR_CPUS) { + printk(KERN_WARNING "Registers for cpu %i not saved since dump " + "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); + return; } + zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); + __cpu_logical_map[1] = (__u16) phy_cpu; + while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy) + cpu_relax(); + memcpy(zfcpdump_save_areas[cpu], + (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, + SAVE_AREA_SIZE); +#ifdef CONFIG_64BIT + /* copy original prefix register */ + zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu]; +#endif } union save_area *zfcpdump_save_areas[NR_CPUS + 1]; EXPORT_SYMBOL_GPL(zfcpdump_save_areas); #else -#define smp_get_save_areas() do { } while (0) -#endif + +static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } + +#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ /* * Lets check how many CPUs we have. */ - static unsigned int __init smp_count_cpus(void) { unsigned int cpu, num_cpus; @@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void) /* * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. */ - boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; current_thread_info()->cpu = 0; num_cpus = 1; @@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void) __cpu_logical_map[1] = (__u16) cpu; if (signal_processor(1, sigp_sense) == sigp_not_operational) continue; + smp_get_save_area(num_cpus, cpu); num_cpus++; } - printk("Detected %d CPU's\n", (int) num_cpus); printk("Boot cpu address %2X\n", boot_cpu_addr); - return num_cpus; } @@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void) { unsigned int phy_cpus, pos_cpus, cpu; - smp_get_save_areas(); phy_cpus = smp_count_cpus(); pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); From 8a88367088a6b9964d99694b30d80720f019bea2 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 10 Jul 2007 11:24:14 +0200 Subject: [PATCH 423/551] [S390] Bogomips calculation for 64 bit. The bogomips calculation triggered via reading from /proc/cpuinfo can return incorrect values if the qrnnd assembly is called with a pointer in %r2 with any of the upper 32 bits set. Fix this by using 64 bit division / remainder operation provided by gcc instead of calling the assembly. Signed-off-by: Martin Schwidefsky --- arch/s390/lib/Makefile | 4 ++-- include/asm-s390/sfp-machine.h | 6 +++--- include/asm-s390/sfp-util.h | 11 +++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 59aea65ce99f..52084436ab69 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -4,7 +4,7 @@ EXTRA_AFLAGS := -traditional -lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o -obj-$(CONFIG_32BIT) += div64.o +lib-y += delay.o string.o uaccess_std.o uaccess_pt.o +obj-$(CONFIG_32BIT) += div64.o qrnnd.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h index 8ca8c77b2d04..4e16aede4b06 100644 --- a/include/asm-s390/sfp-machine.h +++ b/include/asm-s390/sfp-machine.h @@ -27,9 +27,9 @@ #define _FP_W_TYPE_SIZE 32 -#define _FP_W_TYPE unsigned long -#define _FP_WS_TYPE signed long -#define _FP_I_TYPE long +#define _FP_W_TYPE unsigned int +#define _FP_WS_TYPE signed int +#define _FP_I_TYPE int #define _FP_MUL_MEAT_S(R,X,Y) \ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) diff --git a/include/asm-s390/sfp-util.h b/include/asm-s390/sfp-util.h index 8cabcd23d976..0addc6466d95 100644 --- a/include/asm-s390/sfp-util.h +++ b/include/asm-s390/sfp-util.h @@ -51,6 +51,16 @@ wl = __wl; \ }) +#ifdef __s390x__ +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { unsigned long __n; \ + unsigned int __r, __d; \ + __n = ((unsigned long)(n1) << 32) + n0; \ + __d = (d); \ + (q) = __n / __d; \ + (r) = __n % __d; \ + } while (0) +#else #define udiv_qrnnd(q, r, n1, n0, d) \ do { unsigned int __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ @@ -58,6 +68,7 @@ } while (0) extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, unsigned int , unsigned int); +#endif #define UDIV_NEEDS_NORMALIZATION 0 From dc4123303b54657389c952049bf5738dd753d004 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Tue, 10 Jul 2007 11:24:15 +0200 Subject: [PATCH 424/551] [S390] Program check in diag 210 under 31 bit If a virtual address is passed to the diag210 function under 31 bit, we get a programming exception, since diag 210 only works with physical addresses. To fix this, the content of the diag210 data structure is copied to a local structure and the physical address of that structure is passed to diagnose 210. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device_id.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 997f46874537..60b9347f7c92 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -27,7 +27,6 @@ /* * diag210 is used under VM to get information about a virtual device */ -#ifdef CONFIG_64BIT int diag210(struct diag210 * addr) { @@ -43,6 +42,7 @@ diag210(struct diag210 * addr) spin_lock_irqsave(&diag210_lock, flags); diag210_tmp = *addr; +#ifdef CONFIG_64BIT asm volatile( " lhi %0,-1\n" " sam31\n" @@ -51,19 +51,8 @@ diag210(struct diag210 * addr) " srl %0,28\n" "1: sam64\n" EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); #else -int -diag210(struct diag210 * addr) -{ - int ccode; - asm volatile( " lhi %0,-1\n" " diag %1,0,0x210\n" @@ -71,11 +60,14 @@ diag210(struct diag210 * addr) " srl %0,28\n" "1:\n" EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#endif + + *addr = diag210_tmp; + spin_unlock_irqrestore(&diag210_lock, flags); return ccode; } -#endif /* * Input : From 048d5ce6828b9071e241254c7dba13d67bfef2c3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:16 +0200 Subject: [PATCH 425/551] [S390] Remove volatile from atomic_t Follow i386/x86_64 and remove 'volatile' from atomic_t. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- include/asm-s390/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index c17bdbf22067..ea486952f778 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h @@ -24,7 +24,7 @@ */ typedef struct { - volatile int counter; + int counter; } __attribute__ ((aligned (4))) atomic_t; #define ATOMIC_INIT(i) { (i) } @@ -141,7 +141,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #ifdef __s390x__ typedef struct { - volatile long long counter; + long long counter; } __attribute__ ((aligned (8))) atomic64_t; #define ATOMIC64_INIT(i) { (i) } From 3d62149f025134cd69c2fef2a2ccfac3c3c2054f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:17 +0200 Subject: [PATCH 426/551] [S390] dasd: Avoid compile warnings on !CONFIG_DASD_PROFILE drivers/s390/block/dasd_proc.c:33: warning: 'dasd_get_user_string' defined but not used drivers/s390/block/dasd_proc.c:172: warning: 'dasd_statistics_array' defined but not used Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_proc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 8b3b0f4a157c..ac7e8ef504cb 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL; static struct proc_dir_entry *dasd_devices_entry = NULL; static struct proc_dir_entry *dasd_statistics_entry = NULL; +#ifdef CONFIG_DASD_PROFILE static char * dasd_get_user_string(const char __user *user_buf, size_t user_len) { @@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len) buffer[user_len] = 0; return buffer; } +#endif /* CONFIG_DASD_PROFILE */ static int dasd_devices_show(struct seq_file *m, void *v) @@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off, return len; } +#ifdef CONFIG_DASD_PROFILE static char * dasd_statistics_array(char *str, unsigned int *array, int shift) { @@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift) str += sprintf(str,"\n"); return str; } +#endif /* CONFIG_DASD_PROFILE */ static int dasd_statistics_read(char *page, char **start, off_t off, From 987ad70a4d90cf0e70dba43ece02c2e2219e092c Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 10 Jul 2007 11:24:18 +0200 Subject: [PATCH 427/551] [S390] system call optimization. After the in-kernel system call has been remove the system call path can be optimized. The problem state bit of the old psw is always set between system_call and sysc_do_svc. SAVE_ALL_SVC uses this information to avoid two instructions. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry.S | 7 ++++++- arch/s390/kernel/entry64.S | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 6234c6978a1f..bc7ff3658c3d 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -107,6 +107,11 @@ STACK_SIZE = 1 << STACK_SHIFT l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 .endm + .macro SAVE_ALL_SVC psworg,savearea + la %r12,\psworg + l %r15,__LC_KERNEL_STACK # problem state -> load ksp + .endm + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg tm \psworg+1,0x01 # test problem state bit @@ -218,7 +223,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lh %r7,0x8a # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 685f11faa4bc..2a7b1304418b 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -99,6 +99,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ larl %r13,system_call .endm + .macro SAVE_ALL_SVC psworg,savearea + la %r12,\psworg + lg %r15,__LC_KERNEL_STACK # problem state -> load ksp + .endm + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg tm \psworg+1,0x01 # test problem state bit @@ -207,7 +212,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING From af512ed0f8a7e6a3c6fd93b2b5882c8e837a6939 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Tue, 10 Jul 2007 11:24:19 +0200 Subject: [PATCH 428/551] [S390] zcrypt: fix request timeout handling Under very high load zcrypt requests may timeout while waiting on the request queue. Modify zcrypt that timeouts are based on crypto adapter responses. A timeout occurs only if a crypto adapter does not respond within a given time frame to sumitted requests. Signed-off-by: Ralph Wuerthner Signed-off-by: Martin Schwidefsky --- drivers/s390/crypto/ap_bus.c | 98 ++++++++++++++++++++++++++--- drivers/s390/crypto/ap_bus.h | 11 ++++ drivers/s390/crypto/zcrypt_cex2a.c | 27 +++----- drivers/s390/crypto/zcrypt_pcica.c | 27 +++----- drivers/s390/crypto/zcrypt_pcicc.c | 27 +++----- drivers/s390/crypto/zcrypt_pcixcc.c | 40 ++++-------- 6 files changed, 140 insertions(+), 90 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5aac0ec36368..90bd22014513 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long); static void ap_poll_timeout(unsigned long); static int ap_poll_thread_start(void); static void ap_poll_thread_stop(void); +static void ap_request_timeout(unsigned long); /** * Module description. @@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) case AP_RESPONSE_NORMAL: return 0; case AP_RESPONSE_Q_FULL: + case AP_RESPONSE_RESET_IN_PROGRESS: return -EBUSY; default: /* Device is gone. */ return -ENODEV; @@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) if (status.queue_empty) return -ENOENT; return -EBUSY; + case AP_RESPONSE_RESET_IN_PROGRESS: + return -EBUSY; default: return -ENODEV; } @@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid) i = AP_MAX_RESET; /* return with -ENODEV */ break; case AP_RESPONSE_RESET_IN_PROGRESS: + rc = -EBUSY; case AP_RESPONSE_BUSY: default: break; } - if (rc != -ENODEV) + if (rc != -ENODEV && rc != -EBUSY) break; if (i < AP_MAX_RESET - 1) { udelay(5); @@ -340,6 +345,40 @@ static int ap_init_queue(ap_qid_t qid) return rc; } +/** + * Arm request timeout if a AP device was idle and a new request is submitted. + */ +static void ap_increase_queue_count(struct ap_device *ap_dev) +{ + int timeout = ap_dev->drv->request_timeout; + + ap_dev->queue_count++; + if (ap_dev->queue_count == 1) { + mod_timer(&ap_dev->timeout, jiffies + timeout); + ap_dev->reset = AP_RESET_ARMED; + } +} + +/** + * AP device is still alive, re-schedule request timeout if there are still + * pending requests. + */ +static void ap_decrease_queue_count(struct ap_device *ap_dev) +{ + int timeout = ap_dev->drv->request_timeout; + + ap_dev->queue_count--; + if (ap_dev->queue_count > 0) + mod_timer(&ap_dev->timeout, jiffies + timeout); + else + /** + * The timeout timer should to be disabled now - since + * del_timer_sync() is very expensive, we just tell via the + * reset flag to ignore the pending timeout timer. + */ + ap_dev->reset = AP_RESET_IGNORE; +} + /** * AP device related attributes. */ @@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev) struct ap_driver *ap_drv = ap_dev->drv; ap_flush_queue(ap_dev); + del_timer_sync(&ap_dev->timeout); if (ap_drv->remove) ap_drv->remove(ap_dev); spin_lock_bh(&ap_device_lock); @@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused) __ap_scan_bus); rc = ap_query_queue(qid, &queue_depth, &device_type); if (dev) { + if (rc == -EBUSY) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(AP_RESET_TIMEOUT); + rc = ap_query_queue(qid, &queue_depth, + &device_type); + } ap_dev = to_ap_dev(dev); spin_lock_bh(&ap_dev->lock); if (rc || ap_dev->unregistered) { spin_unlock_bh(&ap_dev->lock); - put_device(dev); device_unregister(dev); + put_device(dev); continue; - } else - spin_unlock_bh(&ap_dev->lock); - } - if (dev) { + } + spin_unlock_bh(&ap_dev->lock); put_device(dev); continue; } @@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused) INIT_LIST_HEAD(&ap_dev->pendingq); INIT_LIST_HEAD(&ap_dev->requestq); INIT_LIST_HEAD(&ap_dev->list); + setup_timer(&ap_dev->timeout, ap_request_timeout, + (unsigned long) ap_dev); if (device_type == 0) ap_probe_device_type(ap_dev); else @@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) switch (status.response_code) { case AP_RESPONSE_NORMAL: atomic_dec(&ap_poll_requests); - ap_dev->queue_count--; + ap_decrease_queue_count(ap_dev); list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { if (ap_msg->psmid != ap_dev->reply->psmid) continue; @@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) switch (status.response_code) { case AP_RESPONSE_NORMAL: atomic_inc(&ap_poll_requests); - ap_dev->queue_count++; + ap_increase_queue_count(ap_dev); list_move_tail(&ap_msg->list, &ap_dev->pendingq); ap_dev->requestq_count--; ap_dev->pendingq_count++; @@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) *flags |= 2; break; case AP_RESPONSE_Q_FULL: + case AP_RESPONSE_RESET_IN_PROGRESS: *flags |= 2; break; case AP_RESPONSE_MESSAGE_TOO_BIG: @@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms list_add_tail(&ap_msg->list, &ap_dev->pendingq); atomic_inc(&ap_poll_requests); ap_dev->pendingq_count++; - ap_dev->queue_count++; + ap_increase_queue_count(ap_dev); ap_dev->total_request_count++; break; case AP_RESPONSE_Q_FULL: + case AP_RESPONSE_RESET_IN_PROGRESS: list_add_tail(&ap_msg->list, &ap_dev->requestq); ap_dev->requestq_count++; ap_dev->total_request_count++; @@ -1045,6 +1093,25 @@ static void ap_poll_timeout(unsigned long unused) tasklet_schedule(&ap_tasklet); } +/** + * Reset a not responding AP device and move all requests from the + * pending queue to the request queue. + */ +static void ap_reset(struct ap_device *ap_dev) +{ + int rc; + + ap_dev->reset = AP_RESET_IGNORE; + atomic_sub(ap_dev->queue_count, &ap_poll_requests); + ap_dev->queue_count = 0; + list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); + ap_dev->requestq_count += ap_dev->pendingq_count; + ap_dev->pendingq_count = 0; + rc = ap_init_queue(ap_dev->qid); + if (rc == -ENODEV) + ap_dev->unregistered = 1; +} + /** * Poll all AP devices on the bus in a round robin fashion. Continue * polling until bit 2^0 of the control flags is not set. If bit 2^1 @@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) if (!ap_dev->unregistered) { if (ap_poll_queue(ap_dev, flags)) ap_dev->unregistered = 1; + if (ap_dev->reset == AP_RESET_DO) + ap_reset(ap_dev); } spin_unlock(&ap_dev->lock); return 0; @@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void) mutex_unlock(&ap_poll_thread_mutex); } +/** + * Handling of request timeouts + */ +static void ap_request_timeout(unsigned long data) +{ + struct ap_device *ap_dev = (struct ap_device *) data; + + if (ap_dev->reset == AP_RESET_ARMED) + ap_dev->reset = AP_RESET_DO; +} + static void ap_reset_domain(void) { int i; diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 008559ea742b..87c2d6442875 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -33,6 +33,7 @@ #define AP_DEVICES 64 /* Number of AP devices. */ #define AP_DOMAINS 16 /* Number of AP domains. */ #define AP_MAX_RESET 90 /* Maximum number of resets. */ +#define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */ #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ @@ -83,6 +84,13 @@ struct ap_queue_status { #define AP_DEVICE_TYPE_CEX2A 6 #define AP_DEVICE_TYPE_CEX2C 7 +/** + * AP reset flag states + */ +#define AP_RESET_IGNORE 0 /* request timeout will be ignored */ +#define AP_RESET_ARMED 1 /* request timeout timer is active */ +#define AP_RESET_DO 2 /* AP reset required */ + struct ap_device; struct ap_message; @@ -95,6 +103,7 @@ struct ap_driver { /* receive is called from tasklet context */ void (*receive)(struct ap_device *, struct ap_message *, struct ap_message *); + int request_timeout; /* request timeout in jiffies */ }; #define to_ap_drv(x) container_of((x), struct ap_driver, driver) @@ -112,6 +121,8 @@ struct ap_device { int queue_depth; /* AP queue depth.*/ int device_type; /* AP device type. */ int unregistered; /* marks AP device as unregistered */ + struct timer_list timeout; /* Timer for request timeouts. */ + int reset; /* Reset required after req. timeout. */ int queue_count; /* # messages currently on AP queue. */ diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 5bb13a9d0898..08657f604b8c 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c @@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = { .remove = zcrypt_cex2a_remove, .receive = zcrypt_cex2a_receive, .ids = zcrypt_cex2a_ids, + .request_timeout = CEX2A_CLEANUP_TIME, }; /** @@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, CEX2A_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, mex->outputdata, mex->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; @@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, CEX2A_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, crt->outputdata, crt->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 818ffe05ac00..6e93b4751782 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c @@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = { .remove = zcrypt_pcica_remove, .receive = zcrypt_pcica_receive, .ids = zcrypt_pcica_ids, + .request_timeout = PCICA_CLEANUP_TIME, }; /** @@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICA_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, mex->outputdata, mex->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; @@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICA_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, crt->outputdata, crt->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f295a403b29a..d6d59bf9ac38 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c @@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = { .remove = zcrypt_pcicc_remove, .receive = zcrypt_pcicc_receive, .ids = zcrypt_pcicc_ids, + .request_timeout = PCICC_CLEANUP_TIME, }; /** @@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICC_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, mex->outputdata, mex->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: free_page((unsigned long) ap_msg.message); return rc; @@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICC_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, crt->outputdata, crt->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: free_page((unsigned long) ap_msg.message); return rc; diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 252443b6bd1b..64948788d301 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c @@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = { .remove = zcrypt_pcixcc_remove, .receive = zcrypt_pcixcc_receive, .ids = zcrypt_pcixcc_ids, + .request_timeout = PCIXCC_CLEANUP_TIME, }; /** @@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, goto out_free; init_completion(&resp_type.work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &resp_type.work, PCIXCC_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&resp_type.work); + if (rc == 0) rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, mex->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: free_page((unsigned long) ap_msg.message); return rc; @@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, goto out_free; init_completion(&resp_type.work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &resp_type.work, PCIXCC_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&resp_type.work); + if (rc == 0) rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, crt->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: free_page((unsigned long) ap_msg.message); return rc; @@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, goto out_free; init_completion(&resp_type.work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &resp_type.work, PCIXCC_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&resp_type.work); + if (rc == 0) rc = convert_response_xcrb(zdev, &ap_msg, xcRB); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: memset(ap_msg.message, 0x0, ap_msg.length); kfree(ap_msg.message); From 736f563373804e75f9f3b4abb9e480451bfef8d3 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 10 Jul 2007 11:24:20 +0200 Subject: [PATCH 429/551] [S390] cio: Remove prototype for non-existing function cmf_reset(). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- include/asm-s390/cmb.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h index 241756f80df3..021e7c3223ec 100644 --- a/include/asm-s390/cmb.h +++ b/include/asm-s390/cmb.h @@ -88,7 +88,6 @@ extern u64 cmf_read(struct ccw_device *cdev, int index); * any **/ extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); -extern void cmf_reset(struct ccw_device *cdev); #endif /* __KERNEL__ */ #endif /* S390_CMB_H */ From dce554708cdb02a1053ca3a68997b9facbfde5ce Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 10 Jul 2007 11:24:21 +0200 Subject: [PATCH 430/551] [S390] s390: rename CPU_IDLE to S390_CPU_IDLE sched-cfs-v2.6.22-git-v18.patch introduces CPU_IDLE in sched.h. This conflict with the already existing define in include/asm-s390/processor.h Just rename the s390 defines, since they will go away as soon as we support CONFIG_NO_HZ instead of our own CONFIG_NO_IDLE_HZ. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/process.c | 6 +++--- arch/s390/kernel/time.c | 4 ++-- arch/s390/kernel/vtime.c | 4 ++-- include/asm-s390/processor.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index eb43c3b31269..441975b796fb 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -93,8 +93,8 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) /* disable monitor call class 0 */ __ctl_clear_bit(8, 15); - atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE, - (void *)(long) smp_processor_id()); + atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, + (void *)(long) smp_processor_id()); } extern void s390_handle_mcck(void); @@ -115,7 +115,7 @@ static void default_idle(void) } rc = atomic_notifier_call_chain(&idle_chain, - CPU_IDLE, (void *)(long) cpu); + S390_CPU_IDLE, (void *)(long) cpu); if (rc != NOTIFY_OK && rc != NOTIFY_DONE) BUG(); if (rc != NOTIFY_OK) { diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9c2872a7cca7..48dae49bc1ec 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -226,10 +226,10 @@ static int nohz_idle_notify(struct notifier_block *self, unsigned long action, void *hcpu) { switch (action) { - case CPU_IDLE: + case S390_CPU_IDLE: stop_hz_timer(); break; - case CPU_NOT_IDLE: + case S390_CPU_NOT_IDLE: start_hz_timer(); break; } diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 1e1a6ee2cac1..b6ed143e8597 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -545,10 +545,10 @@ static int vtimer_idle_notify(struct notifier_block *self, unsigned long action, void *hcpu) { switch (action) { - case CPU_IDLE: + case S390_CPU_IDLE: stop_cpu_timer(); break; - case CPU_NOT_IDLE: + case S390_CPU_NOT_IDLE: start_cpu_timer(); break; } diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 5cb480af65d5..3b972d4c6b29 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -357,8 +357,8 @@ extern void (*s390_base_ext_handler_fn)(void); /* * CPU idle notifier chain. */ -#define CPU_IDLE 0 -#define CPU_NOT_IDLE 1 +#define S390_CPU_IDLE 0 +#define S390_CPU_NOT_IDLE 1 struct notifier_block; int register_idle_notifier(struct notifier_block *nb); From f60d89108f3481ca11672b82cf7e67171e050ce4 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 10 Jul 2007 11:24:22 +0200 Subject: [PATCH 431/551] [S390] vmlogrdr function annotation. Use __init and __exit for vmlogrdr. Both functions are only referenced by the module_init exit macros, so this change should be fine. Acked-by: Stefan Weinhuber Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmlogrdr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a5a00e9ae4d0..12f7a4ce82c1 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void) } -static int vmlogrdr_init(void) +static int __init vmlogrdr_init(void) { int rc; int i; @@ -885,7 +885,7 @@ cleanup: } -static void vmlogrdr_exit(void) +static void __exit vmlogrdr_exit(void) { vmlogrdr_cleanup(); printk (KERN_INFO "vmlogrdr: driver unloaded\n"); From 4a11b59d8283662193a9c6a9c14c58d1b9bf0617 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 4 May 2007 00:27:45 +0400 Subject: [PATCH 432/551] [BATTERY] Universal power supply class (was: battery class) This class is result of "external power" and "battery" classes merge, as suggested by David Woodhouse. He also implemented uevent support. Here how userspace seeing it now: # ls /sys/class/power\ supply/ ac main-battery usb # cat /sys/class/power\ supply/ac/type AC # cat /sys/class/power\ supply/usb/type USB # cat /sys/class/power\ supply/main-battery/type Battery # cat /sys/class/power\ supply/ac/online 1 # cat /sys/class/power\ supply/usb/online 0 # cat /sys/class/power\ supply/main-battery/status Charging # cat /sys/class/leds/h5400\:red-left/trigger none h5400-radio timer hwtimer ac-online usb-online main-battery-charging-or-full [main-battery-charging] main-battery-full Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse Signed-off-by: Andrew Morton --- Documentation/power_supply_class.txt | 167 +++++++++++++++ drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/power/Kconfig | 17 ++ drivers/power/Makefile | 15 ++ drivers/power/power_supply.h | 42 ++++ drivers/power/power_supply_core.c | 168 +++++++++++++++ drivers/power/power_supply_leds.c | 176 ++++++++++++++++ drivers/power/power_supply_sysfs.c | 299 +++++++++++++++++++++++++++ include/linux/power_supply.h | 180 ++++++++++++++++ 10 files changed, 1067 insertions(+) create mode 100644 Documentation/power_supply_class.txt create mode 100644 drivers/power/Kconfig create mode 100644 drivers/power/Makefile create mode 100644 drivers/power/power_supply.h create mode 100644 drivers/power/power_supply_core.c create mode 100644 drivers/power/power_supply_leds.c create mode 100644 drivers/power/power_supply_sysfs.c create mode 100644 include/linux/power_supply.h diff --git a/Documentation/power_supply_class.txt b/Documentation/power_supply_class.txt new file mode 100644 index 000000000000..9758cf433c06 --- /dev/null +++ b/Documentation/power_supply_class.txt @@ -0,0 +1,167 @@ +Linux power supply class +======================== + +Synopsis +~~~~~~~~ +Power supply class used to represent battery, UPS, AC or DC power supply +properties to user-space. + +It defines core set of attributes, which should be applicable to (almost) +every power supply out there. Attributes are available via sysfs and uevent +interfaces. + +Each attribute has well defined meaning, up to unit of measure used. While +the attributes provided are believed to be universally applicable to any +power supply, specific monitoring hardware may not be able to provide them +all, so any of them may be skipped. + +Power supply class is extensible, and allows to define drivers own attributes. +The core attribute set is subject to the standard Linux evolution (i.e. +if it will be found that some attribute is applicable to many power supply +types or their drivers, it can be added to the core set). + +It also integrates with LED framework, for the purpose of providing +typically expected feedback of battery charging/fully charged status and +AC/USB power supply online status. (Note that specific details of the +indication (including whether to use it at all) are fully controllable by +user and/or specific machine defaults, per design principles of LED +framework). + + +Attributes/properties +~~~~~~~~~~~~~~~~~~~~~ +Power supply class has predefined set of attributes, this eliminates code +duplication across drivers. Power supply class insist on reusing its +predefined attributes *and* their units. + +So, userspace gets predictable set of attributes and their units for any +kind of power supply, and can process/present them to a user in consistent +manner. Results for different power supplies and machines are also directly +comparable. + +See drivers/power/ds2760_battery.c and drivers/power/pda_power.c for the +example how to declare and handle attributes. + + +Units +~~~~~ +Quoting include/linux/power_supply.h: + + All voltages, currents, charges, energies, time and temperatures in µV, + µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise + stated. It's driver's job to convert its raw values to units in which + this class operates. + + +Attributes/properties detailed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +~ ~ ~ ~ ~ ~ ~ Charge/Energy/Capacity - how to not confuse ~ ~ ~ ~ ~ ~ ~ +~ ~ +~ Because both "charge" (µAh) and "energy" (µWh) represents "capacity" ~ +~ of battery, this class distinguish these terms. Don't mix them! ~ +~ ~ +~ CHARGE_* attributes represents capacity in µAh only. ~ +~ ENERGY_* attributes represents capacity in µWh only. ~ +~ CAPACITY attribute represents capacity in *percents*, from 0 to 100. ~ +~ ~ +~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + +Postfixes: +_AVG - *hardware* averaged value, use it if your hardware is really able to +report averaged values. +_NOW - momentary/instantaneous values. + +STATUS - this attribute represents operating status (charging, full, +discharging (i.e. powering a load), etc.). This corresponds to +BATTERY_STATUS_* values, as defined in battery.h. + +HEALTH - represents health of the battery, values corresponds to +POWER_SUPPLY_HEALTH_*, defined in battery.h. + +VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and +minimal power supply voltages. Maximal/minimal means values of voltages +when battery considered "full"/"empty" at normal conditions. Yes, there is +no direct relation between voltage and battery capacity, but some dumb +batteries use voltage for very approximated calculation of capacity. +Battery driver also can use this attribute just to inform userspace +about maximal and minimal voltage thresholds of a given battery. + +CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when +battery considered full/empty. + +ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN - same as above but for energy. + +CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value +of charge when battery became full/empty". It also could mean "value of +charge when battery considered full/empty at given conditions (temperature, +age)". I.e. these attributes represents real thresholds, not design values. + +ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. + +CAPACITY - capacity in percents. +CAPACITY_LEVEL - capacity level. This corresponds to +POWER_SUPPLY_CAPACITY_LEVEL_*. + +TEMP - temperature of the power supply. +TEMP_AMBIENT - ambient temperature. + +TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e. +while battery powers a load) +TIME_TO_FULL - seconds left for battery to be considered full (i.e. +while battery is charging) + + +Battery <-> external power supply interaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Often power supplies are acting as supplies and supplicants at the same +time. Batteries are good example. So, batteries usually care if they're +externally powered or not. + +For that case, power supply class implements notification mechanism for +batteries. + +External power supply (AC) lists supplicants (batteries) names in +"supplied_to" struct member, and each power_supply_changed() call +issued by external power supply will notify supplicants via +external_power_changed callback. + + +QA +~~ +Q: Where is POWER_SUPPLY_PROP_XYZ attribute? +A: If you cannot find attribute suitable for your driver needs, feel free + to add it and send patch along with your driver. + + The attributes available currently are the ones currently provided by the + drivers written. + + Good candidates to add in future: model/part#, cycle_time, manufacturer, + etc. + + +Q: I have some very specific attribute (e.g. battery color), should I add + this attribute to standard ones? +A: Most likely, no. Such attribute can be placed in the driver itself, if + it is useful. Of course, if the attribute in question applicable to + large set of batteries, provided by many drivers, and/or comes from + some general battery specification/standard, it may be a candidate to + be added to the core attribute set. + + +Q: Suppose, my battery monitoring chip/firmware does not provides capacity + in percents, but provides charge_{now,full,empty}. Should I calculate + percentage capacity manually, inside the driver, and register CAPACITY + attribute? The same question about time_to_empty/time_to_full. +A: Most likely, no. This class is designed to export properties which are + directly measurable by the specific hardware available. + + Inferring not available properties using some heuristics or mathematical + model is not subject of work for a battery driver. Such functionality + should be factored out, and in fact, apm_power, the driver to serve + legacy APM API on top of power supply class, uses a simple heuristic of + approximating remaining battery capacity based on its charge, current, + voltage and so on. But full-fledged battery model is likely not subject + for kernel at all, as it would require floating point calculation to deal + with things like differential equations and Kalman filters. This is + better be handled by batteryd/libbattery, yet to be written. diff --git a/drivers/Kconfig b/drivers/Kconfig index 050323fd79e9..c546de307caf 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -54,6 +54,8 @@ source "drivers/spi/Kconfig" source "drivers/w1/Kconfig" +source "drivers/power/Kconfig" + source "drivers/hwmon/Kconfig" source "drivers/mfd/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index adad2f3d438a..503d82569449 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ obj-y += i2c/ obj-$(CONFIG_W1) += w1/ +obj-$(CONFIG_POWER_SUPPLY) += power/ obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_MD) += md/ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig new file mode 100644 index 000000000000..7811fa627412 --- /dev/null +++ b/drivers/power/Kconfig @@ -0,0 +1,17 @@ +menuconfig POWER_SUPPLY + tristate "Power supply class support" + help + Say Y here to enable power supply class support. This allows + power supply (batteries, AC, USB) monitoring by userspace + via sysfs and uevent (if available) and/or APM kernel interface + (if selected below). + +if POWER_SUPPLY + +config POWER_SUPPLY_DEBUG + bool "Power supply debug" + help + Say Y here to enable debugging messages for power supply class + and drivers. + +endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile new file mode 100644 index 000000000000..3c88148983a2 --- /dev/null +++ b/drivers/power/Makefile @@ -0,0 +1,15 @@ +power_supply-objs := power_supply_core.o + +ifeq ($(CONFIG_SYSFS),y) +power_supply-objs += power_supply_sysfs.o +endif + +ifeq ($(CONFIG_LEDS_TRIGGERS),y) +power_supply-objs += power_supply_leds.o +endif + +ifeq ($(CONFIG_POWER_SUPPLY_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif + +obj-$(CONFIG_POWER_SUPPLY) += power_supply.o diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h new file mode 100644 index 000000000000..a9880d468ee4 --- /dev/null +++ b/drivers/power/power_supply.h @@ -0,0 +1,42 @@ +/* + * Functions private to power supply class + * + * Copyright © 2007 Anton Vorontsov + * Copyright © 2004 Szabolcs Gyurko + * Copyright © 2003 Ian Molton + * + * Modified: 2004, Oct Szabolcs Gyurko + * + * You may use this code as per GPL version 2 + */ + +#ifdef CONFIG_SYSFS + +extern int power_supply_create_attrs(struct power_supply *psy); +extern void power_supply_remove_attrs(struct power_supply *psy); +extern int power_supply_uevent(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size); + +#else + +static inline int power_supply_create_attrs(struct power_supply *psy) +{ return 0; } +static inline void power_supply_remove_attrs(struct power_supply *psy) {} +#define power_supply_uevent NULL + +#endif /* CONFIG_SYSFS */ + +#ifdef CONFIG_LEDS_TRIGGERS + +extern void power_supply_update_leds(struct power_supply *psy); +extern int power_supply_create_triggers(struct power_supply *psy); +extern void power_supply_remove_triggers(struct power_supply *psy); + +#else + +static inline void power_supply_update_leds(struct power_supply *psy) {} +static inline int power_supply_create_triggers(struct power_supply *psy) +{ return 0; } +static inline void power_supply_remove_triggers(struct power_supply *psy) {} + +#endif /* CONFIG_LEDS_TRIGGERS */ diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c new file mode 100644 index 000000000000..e87ea5156755 --- /dev/null +++ b/drivers/power/power_supply_core.c @@ -0,0 +1,168 @@ +/* + * Universal power supply monitor class + * + * Copyright © 2007 Anton Vorontsov + * Copyright © 2004 Szabolcs Gyurko + * Copyright © 2003 Ian Molton + * + * Modified: 2004, Oct Szabolcs Gyurko + * + * You may use this code as per GPL version 2 + */ + +#include +#include +#include +#include +#include +#include +#include "power_supply.h" + +struct class *power_supply_class; + +static void power_supply_changed_work(struct work_struct *work) +{ + struct power_supply *psy = container_of(work, struct power_supply, + changed_work); + int i; + + dev_dbg(psy->dev, "%s\n", __FUNCTION__); + + for (i = 0; i < psy->num_supplicants; i++) { + struct device *dev; + + down(&power_supply_class->sem); + list_for_each_entry(dev, &power_supply_class->devices, node) { + struct power_supply *pst = dev_get_drvdata(dev); + + if (!strcmp(psy->supplied_to[i], pst->name)) { + if (pst->external_power_changed) + pst->external_power_changed(pst); + } + } + up(&power_supply_class->sem); + } + + power_supply_update_leds(psy); + + kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); + + return; +} + +void power_supply_changed(struct power_supply *psy) +{ + dev_dbg(psy->dev, "%s\n", __FUNCTION__); + + schedule_work(&psy->changed_work); + + return; +} + +int power_supply_am_i_supplied(struct power_supply *psy) +{ + union power_supply_propval ret = {0,}; + struct device *dev; + + down(&power_supply_class->sem); + list_for_each_entry(dev, &power_supply_class->devices, node) { + struct power_supply *epsy = dev_get_drvdata(dev); + int i; + + for (i = 0; i < epsy->num_supplicants; i++) { + if (!strcmp(epsy->supplied_to[i], psy->name)) { + if (epsy->get_property(epsy, + POWER_SUPPLY_PROP_ONLINE, &ret)) + continue; + if (ret.intval) + goto out; + } + } + } +out: + up(&power_supply_class->sem); + + dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, ret.intval); + + return ret.intval; +} + +int power_supply_register(struct device *parent, struct power_supply *psy) +{ + int rc = 0; + + psy->dev = device_create(power_supply_class, parent, 0, + "%s", psy->name); + if (IS_ERR(psy->dev)) { + rc = PTR_ERR(psy->dev); + goto dev_create_failed; + } + + dev_set_drvdata(psy->dev, psy); + + INIT_WORK(&psy->changed_work, power_supply_changed_work); + + rc = power_supply_create_attrs(psy); + if (rc) + goto create_attrs_failed; + + rc = power_supply_create_triggers(psy); + if (rc) + goto create_triggers_failed; + + power_supply_changed(psy); + + goto success; + +create_triggers_failed: + power_supply_remove_attrs(psy); +create_attrs_failed: + device_unregister(psy->dev); +dev_create_failed: +success: + return rc; +} + +void power_supply_unregister(struct power_supply *psy) +{ + flush_scheduled_work(); + power_supply_remove_triggers(psy); + power_supply_remove_attrs(psy); + device_unregister(psy->dev); + return; +} + +static int __init power_supply_class_init(void) +{ + power_supply_class = class_create(THIS_MODULE, "power_supply"); + + if (IS_ERR(power_supply_class)) + return PTR_ERR(power_supply_class); + + power_supply_class->dev_uevent = power_supply_uevent; + + return 0; +} + +static void __exit power_supply_class_exit(void) +{ + class_destroy(power_supply_class); + return; +} + +EXPORT_SYMBOL_GPL(power_supply_changed); +EXPORT_SYMBOL_GPL(power_supply_am_i_supplied); +EXPORT_SYMBOL_GPL(power_supply_register); +EXPORT_SYMBOL_GPL(power_supply_unregister); + +/* exported for the APM Power driver, APM emulation */ +EXPORT_SYMBOL_GPL(power_supply_class); + +subsys_initcall(power_supply_class_init); +module_exit(power_supply_class_exit); + +MODULE_DESCRIPTION("Universal power supply monitor class"); +MODULE_AUTHOR("Ian Molton , " + "Szabolcs Gyurko, " + "Anton Vorontsov "); +MODULE_LICENSE("GPL"); diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c new file mode 100644 index 000000000000..7232490bb595 --- /dev/null +++ b/drivers/power/power_supply_leds.c @@ -0,0 +1,176 @@ +/* + * LEDs triggers for power supply class + * + * Copyright © 2007 Anton Vorontsov + * Copyright © 2004 Szabolcs Gyurko + * Copyright © 2003 Ian Molton + * + * Modified: 2004, Oct Szabolcs Gyurko + * + * You may use this code as per GPL version 2 + */ + +#include + +/* Battery specific LEDs triggers. */ + +static void power_supply_update_bat_leds(struct power_supply *psy) +{ + union power_supply_propval status; + + if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) + return; + + dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, status.intval); + + switch (status.intval) { + case POWER_SUPPLY_STATUS_FULL: + led_trigger_event(psy->charging_full_trig, LED_FULL); + led_trigger_event(psy->charging_trig, LED_OFF); + led_trigger_event(psy->full_trig, LED_FULL); + break; + case POWER_SUPPLY_STATUS_CHARGING: + led_trigger_event(psy->charging_full_trig, LED_FULL); + led_trigger_event(psy->charging_trig, LED_FULL); + led_trigger_event(psy->full_trig, LED_OFF); + break; + default: + led_trigger_event(psy->charging_full_trig, LED_OFF); + led_trigger_event(psy->charging_trig, LED_OFF); + led_trigger_event(psy->full_trig, LED_OFF); + break; + } + + return; +} + +static int power_supply_create_bat_triggers(struct power_supply *psy) +{ + int rc = 0; + + psy->charging_full_trig_name = kmalloc(strlen(psy->name) + + sizeof("-charging-or-full"), GFP_KERNEL); + if (!psy->charging_full_trig_name) + goto charging_full_failed; + + psy->charging_trig_name = kmalloc(strlen(psy->name) + + sizeof("-charging"), GFP_KERNEL); + if (!psy->charging_trig_name) + goto charging_failed; + + psy->full_trig_name = kmalloc(strlen(psy->name) + + sizeof("-full"), GFP_KERNEL); + if (!psy->full_trig_name) + goto full_failed; + + strcpy(psy->charging_full_trig_name, psy->name); + strcat(psy->charging_full_trig_name, "-charging-or-full"); + strcpy(psy->charging_trig_name, psy->name); + strcat(psy->charging_trig_name, "-charging"); + strcpy(psy->full_trig_name, psy->name); + strcat(psy->full_trig_name, "-full"); + + led_trigger_register_simple(psy->charging_full_trig_name, + &psy->charging_full_trig); + led_trigger_register_simple(psy->charging_trig_name, + &psy->charging_trig); + led_trigger_register_simple(psy->full_trig_name, + &psy->full_trig); + + goto success; + +full_failed: + kfree(psy->charging_trig_name); +charging_failed: + kfree(psy->charging_full_trig_name); +charging_full_failed: + rc = -ENOMEM; +success: + return rc; +} + +static void power_supply_remove_bat_triggers(struct power_supply *psy) +{ + led_trigger_unregister_simple(psy->charging_full_trig); + led_trigger_unregister_simple(psy->charging_trig); + led_trigger_unregister_simple(psy->full_trig); + kfree(psy->full_trig_name); + kfree(psy->charging_trig_name); + kfree(psy->charging_full_trig_name); + return; +} + +/* Generated power specific LEDs triggers. */ + +static void power_supply_update_gen_leds(struct power_supply *psy) +{ + union power_supply_propval online; + + if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online)) + return; + + dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, online.intval); + + if (online.intval) + led_trigger_event(psy->online_trig, LED_FULL); + else + led_trigger_event(psy->online_trig, LED_OFF); + + return; +} + +static int power_supply_create_gen_triggers(struct power_supply *psy) +{ + int rc = 0; + + psy->online_trig_name = kmalloc(strlen(psy->name) + sizeof("-online"), + GFP_KERNEL); + if (!psy->online_trig_name) + goto online_failed; + + strcpy(psy->online_trig_name, psy->name); + strcat(psy->online_trig_name, "-online"); + + led_trigger_register_simple(psy->online_trig_name, &psy->online_trig); + + goto success; + +online_failed: + rc = -ENOMEM; +success: + return rc; +} + +static void power_supply_remove_gen_triggers(struct power_supply *psy) +{ + led_trigger_unregister_simple(psy->online_trig); + kfree(psy->online_trig_name); + return; +} + +/* Choice what triggers to create&update. */ + +void power_supply_update_leds(struct power_supply *psy) +{ + if (psy->type == POWER_SUPPLY_TYPE_BATTERY) + power_supply_update_bat_leds(psy); + else + power_supply_update_gen_leds(psy); + return; +} + +int power_supply_create_triggers(struct power_supply *psy) +{ + if (psy->type == POWER_SUPPLY_TYPE_BATTERY) + return power_supply_create_bat_triggers(psy); + return power_supply_create_gen_triggers(psy); +} + +void power_supply_remove_triggers(struct power_supply *psy) +{ + if (psy->type == POWER_SUPPLY_TYPE_BATTERY) + power_supply_remove_bat_triggers(psy); + else + power_supply_remove_gen_triggers(psy); + return; +} diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c new file mode 100644 index 000000000000..c07d4258d347 --- /dev/null +++ b/drivers/power/power_supply_sysfs.c @@ -0,0 +1,299 @@ +/* + * Sysfs interface for the universal power supply monitor class + * + * Copyright © 2007 David Woodhouse + * Copyright © 2007 Anton Vorontsov + * Copyright © 2004 Szabolcs Gyurko + * Copyright © 2003 Ian Molton + * + * Modified: 2004, Oct Szabolcs Gyurko + * + * You may use this code as per GPL version 2 + */ + +#include +#include + +/* + * This is because the name "current" breaks the device attr macro. + * The "current" word resolves to "(get_current())" so instead of + * "current" "(get_current())" appears in the sysfs. + * + * The source of this definition is the device.h which calls __ATTR + * macro in sysfs.h which calls the __stringify macro. + * + * Only modification that the name is not tried to be resolved + * (as a macro let's say). + */ + +#define POWER_SUPPLY_ATTR(_name) \ +{ \ + .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \ + .show = power_supply_show_property, \ + .store = NULL, \ +} + +static struct device_attribute power_supply_attrs[]; + +static ssize_t power_supply_show_property(struct device *dev, + struct device_attribute *attr, + char *buf) { + static char *status_text[] = { + "Unknown", "Charging", "Discharging", "Not charging", "Full" + }; + static char *health_text[] = { + "Unknown", "Good", "Overheat", "Dead", "Over voltage", + "Unspecified failure" + }; + static char *technology_text[] = { + "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd" + }; + static char *capacity_level_text[] = { + "Unknown", "Critical", "Low", "Normal", "High", "Full" + }; + ssize_t ret; + struct power_supply *psy = dev_get_drvdata(dev); + const ptrdiff_t off = attr - power_supply_attrs; + union power_supply_propval value; + + ret = psy->get_property(psy, off, &value); + + if (ret < 0) { + if (ret != -ENODEV) + dev_err(dev, "driver failed to report `%s' property\n", + attr->attr.name); + return ret; + } + + if (off == POWER_SUPPLY_PROP_STATUS) + return sprintf(buf, "%s\n", status_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_HEALTH) + return sprintf(buf, "%s\n", health_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_TECHNOLOGY) + return sprintf(buf, "%s\n", technology_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) + return sprintf(buf, "%s\n", + capacity_level_text[value.intval]); + else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) + return sprintf(buf, "%s\n", value.strval); + + return sprintf(buf, "%d\n", value.intval); +} + +/* Must be in the same order as POWER_SUPPLY_PROP_* */ +static struct device_attribute power_supply_attrs[] = { + /* Properties of type `int' */ + POWER_SUPPLY_ATTR(status), + POWER_SUPPLY_ATTR(health), + POWER_SUPPLY_ATTR(present), + POWER_SUPPLY_ATTR(online), + POWER_SUPPLY_ATTR(technology), + POWER_SUPPLY_ATTR(voltage_max_design), + POWER_SUPPLY_ATTR(voltage_min_design), + POWER_SUPPLY_ATTR(voltage_now), + POWER_SUPPLY_ATTR(voltage_avg), + POWER_SUPPLY_ATTR(current_now), + POWER_SUPPLY_ATTR(current_avg), + POWER_SUPPLY_ATTR(charge_full_design), + POWER_SUPPLY_ATTR(charge_empty_design), + POWER_SUPPLY_ATTR(charge_full), + POWER_SUPPLY_ATTR(charge_empty), + POWER_SUPPLY_ATTR(charge_now), + POWER_SUPPLY_ATTR(charge_avg), + POWER_SUPPLY_ATTR(energy_full_design), + POWER_SUPPLY_ATTR(energy_empty_design), + POWER_SUPPLY_ATTR(energy_full), + POWER_SUPPLY_ATTR(energy_empty), + POWER_SUPPLY_ATTR(energy_now), + POWER_SUPPLY_ATTR(energy_avg), + POWER_SUPPLY_ATTR(capacity), + POWER_SUPPLY_ATTR(capacity_level), + POWER_SUPPLY_ATTR(temp), + POWER_SUPPLY_ATTR(temp_ambient), + POWER_SUPPLY_ATTR(time_to_empty_now), + POWER_SUPPLY_ATTR(time_to_empty_avg), + POWER_SUPPLY_ATTR(time_to_full_now), + POWER_SUPPLY_ATTR(time_to_full_avg), + /* Properties of type `const char *' */ + POWER_SUPPLY_ATTR(model_name), + POWER_SUPPLY_ATTR(manufacturer), +}; + +static ssize_t power_supply_show_static_attrs(struct device *dev, + struct device_attribute *attr, + char *buf) { + static char *type_text[] = { "Battery", "UPS", "Mains", "USB" }; + struct power_supply *psy = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", type_text[psy->type]); +} + +static struct device_attribute power_supply_static_attrs[] = { + __ATTR(type, 0444, power_supply_show_static_attrs, NULL), +}; + +int power_supply_create_attrs(struct power_supply *psy) +{ + int rc = 0; + int i, j; + + for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) { + rc = device_create_file(psy->dev, + &power_supply_static_attrs[i]); + if (rc) + goto statics_failed; + } + + for (j = 0; j < psy->num_properties; j++) { + rc = device_create_file(psy->dev, + &power_supply_attrs[psy->properties[j]]); + if (rc) + goto dynamics_failed; + } + + goto succeed; + +dynamics_failed: + while (j--) + device_remove_file(psy->dev, + &power_supply_attrs[psy->properties[j]]); +statics_failed: + while (i--) + device_remove_file(psy->dev, + &power_supply_static_attrs[psy->properties[i]]); +succeed: + return rc; +} + +void power_supply_remove_attrs(struct power_supply *psy) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) + device_remove_file(psy->dev, + &power_supply_static_attrs[i]); + + for (i = 0; i < psy->num_properties; i++) + device_remove_file(psy->dev, + &power_supply_attrs[psy->properties[i]]); + + return; +} + +static char *kstruprdup(const char *str, gfp_t gfp) +{ + char *ret, *ustr; + + ustr = ret = kmalloc(strlen(str) + 1, gfp); + + if (!ret) + return NULL; + + while (*str) + *ustr++ = toupper(*str++); + + *ustr = 0; + + return ret; +} + +int power_supply_uevent(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + struct power_supply *psy = dev_get_drvdata(dev); + int i = 0, length = 0, ret = 0, j; + char *prop_buf; + char *attrname; + + dev_dbg(dev, "uevent\n"); + + if (!psy) { + dev_dbg(dev, "No power supply yet\n"); + return ret; + } + + dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); + + ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "POWER_SUPPLY_NAME=%s", psy->name); + if (ret) + return ret; + + prop_buf = (char *)get_zeroed_page(GFP_KERNEL); + if (!prop_buf) + return -ENOMEM; + + for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) { + struct device_attribute *attr; + char *line; + + attr = &power_supply_static_attrs[j]; + + ret = power_supply_show_static_attrs(dev, attr, prop_buf); + if (ret < 0) + goto out; + + line = strchr(prop_buf, '\n'); + if (line) + *line = 0; + + attrname = kstruprdup(attr->attr.name, GFP_KERNEL); + if (!attrname) { + ret = -ENOMEM; + goto out; + } + + dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); + + ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "POWER_SUPPLY_%s=%s", + attrname, prop_buf); + kfree(attrname); + if (ret) + goto out; + } + + dev_dbg(dev, "%zd dynamic props\n", psy->num_properties); + + for (j = 0; j < psy->num_properties; j++) { + struct device_attribute *attr; + char *line; + + attr = &power_supply_attrs[psy->properties[j]]; + + ret = power_supply_show_property(dev, attr, prop_buf); + if (ret == -ENODEV) { + /* When a battery is absent, we expect -ENODEV. Don't abort; + send the uevent with at least the the PRESENT=0 property */ + ret = 0; + continue; + } + + if (ret < 0) + goto out; + + line = strchr(prop_buf, '\n'); + if (line) + *line = 0; + + attrname = kstruprdup(attr->attr.name, GFP_KERNEL); + if (!attrname) { + ret = -ENOMEM; + goto out; + } + + dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf); + + ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "POWER_SUPPLY_%s=%s", + attrname, prop_buf); + kfree(attrname); + if (ret) + goto out; + } + +out: + free_page((unsigned long)prop_buf); + + return ret; +} diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h new file mode 100644 index 000000000000..606c0957997f --- /dev/null +++ b/include/linux/power_supply.h @@ -0,0 +1,180 @@ +/* + * Universal power supply monitor class + * + * Copyright © 2007 Anton Vorontsov + * Copyright © 2004 Szabolcs Gyurko + * Copyright © 2003 Ian Molton + * + * Modified: 2004, Oct Szabolcs Gyurko + * + * You may use this code as per GPL version 2 + */ + +#ifndef __LINUX_POWER_SUPPLY_H__ +#define __LINUX_POWER_SUPPLY_H__ + +#include +#include +#include + +/* + * All voltages, currents, charges, energies, time and temperatures in uV, + * µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise + * stated. It's driver's job to convert its raw values to units in which + * this class operates. + */ + +/* + * For systems where the charger determines the maximum battery capacity + * the min and max fields should be used to present these values to user + * space. Unused/unknown fields will not appear in sysfs. + */ + +enum { + POWER_SUPPLY_STATUS_UNKNOWN = 0, + POWER_SUPPLY_STATUS_CHARGING, + POWER_SUPPLY_STATUS_DISCHARGING, + POWER_SUPPLY_STATUS_NOT_CHARGING, + POWER_SUPPLY_STATUS_FULL, +}; + +enum { + POWER_SUPPLY_HEALTH_UNKNOWN = 0, + POWER_SUPPLY_HEALTH_GOOD, + POWER_SUPPLY_HEALTH_OVERHEAT, + POWER_SUPPLY_HEALTH_DEAD, + POWER_SUPPLY_HEALTH_OVERVOLTAGE, + POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, +}; + +enum { + POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0, + POWER_SUPPLY_TECHNOLOGY_NiMH, + POWER_SUPPLY_TECHNOLOGY_LION, + POWER_SUPPLY_TECHNOLOGY_LIPO, + POWER_SUPPLY_TECHNOLOGY_LiFe, + POWER_SUPPLY_TECHNOLOGY_NiCd, +}; + +enum { + POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0, + POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL, + POWER_SUPPLY_CAPACITY_LEVEL_LOW, + POWER_SUPPLY_CAPACITY_LEVEL_NORMAL, + POWER_SUPPLY_CAPACITY_LEVEL_HIGH, + POWER_SUPPLY_CAPACITY_LEVEL_FULL, +}; + +enum power_supply_property { + /* Properties of type `int' */ + POWER_SUPPLY_PROP_STATUS = 0, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_EMPTY, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_AVG, + POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, + POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN, + POWER_SUPPLY_PROP_ENERGY_FULL, + POWER_SUPPLY_PROP_ENERGY_EMPTY, + POWER_SUPPLY_PROP_ENERGY_NOW, + POWER_SUPPLY_PROP_ENERGY_AVG, + POWER_SUPPLY_PROP_CAPACITY, /* in percents! */ + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TEMP_AMBIENT, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, + /* Properties of type `const char *' */ + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, +}; + +enum power_supply_type { + POWER_SUPPLY_TYPE_BATTERY = 0, + POWER_SUPPLY_TYPE_UPS, + POWER_SUPPLY_TYPE_MAINS, + POWER_SUPPLY_TYPE_USB, +}; + +union power_supply_propval { + int intval; + const char *strval; +}; + +struct power_supply { + const char *name; + enum power_supply_type type; + enum power_supply_property *properties; + size_t num_properties; + + char **supplied_to; + size_t num_supplicants; + + int (*get_property)(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val); + void (*external_power_changed)(struct power_supply *psy); + + /* For APM emulation, think legacy userspace. */ + int use_for_apm; + + /* private */ + struct device *dev; + struct work_struct changed_work; + +#ifdef CONFIG_LEDS_TRIGGERS + struct led_trigger *charging_full_trig; + char *charging_full_trig_name; + struct led_trigger *charging_trig; + char *charging_trig_name; + struct led_trigger *full_trig; + char *full_trig_name; + struct led_trigger *online_trig; + char *online_trig_name; +#endif +}; + +/* + * This is recommended structure to specify static power supply parameters. + * Generic one, parametrizable for different power supplies. Power supply + * class itself does not use it, but that's what implementing most platform + * drivers, should try reuse for consistency. + */ + +struct power_supply_info { + const char *name; + int technology; + int voltage_max_design; + int voltage_min_design; + int charge_full_design; + int charge_empty_design; + int energy_full_design; + int energy_empty_design; + int use_for_apm; +}; + +extern void power_supply_changed(struct power_supply *psy); +extern int power_supply_am_i_supplied(struct power_supply *psy); + +extern int power_supply_register(struct device *parent, + struct power_supply *psy); +extern void power_supply_unregister(struct power_supply *psy); + +/* For APM emulation, think legacy userspace. */ +extern struct class *power_supply_class; + +#endif /* __LINUX_POWER_SUPPLY_H__ */ From b2998049cfae4f4a81c4bb048814d34912017bb9 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 4 May 2007 00:32:17 +0400 Subject: [PATCH 433/551] [BATTERY] pda_power platform driver Common power driver for PDAs and phones with one or two external power supplies (AC/USB) connected to main and backup batteries, and optional builtin charger. It's used to stop logic duplication through different embedded devices. So, power supply *logic* is here. pda_power register power supplies, and will take care about notifying batteries about power changes through external power interface. Currently, power consumption legal limits (including USB power consumption) should be handled by platform code, inside set_charge function. Signed-off-by: Anton Vorontsov Signed-off-by: Roman Moravcik Signed-off-by: David Woodhouse --- drivers/power/Kconfig | 7 + drivers/power/Makefile | 2 + drivers/power/pda_power.c | 261 ++++++++++++++++++++++++++++++++++++++ include/linux/pda_power.h | 31 +++++ 4 files changed, 301 insertions(+) create mode 100644 drivers/power/pda_power.c create mode 100644 include/linux/pda_power.h diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 7811fa627412..cc70644db947 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -14,4 +14,11 @@ config POWER_SUPPLY_DEBUG Say Y here to enable debugging messages for power supply class and drivers. +config PDA_POWER + tristate "Generic PDA/phone power driver" + help + Say Y here to enable generic power driver for PDAs and phones with + one or two external power supplies (AC/USB) connected to main and + backup batteries, and optional builtin charger. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 3c88148983a2..1ff4b6806381 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -13,3 +13,5 @@ EXTRA_CFLAGS += -DDEBUG endif obj-$(CONFIG_POWER_SUPPLY) += power_supply.o + +obj-$(CONFIG_PDA_POWER) += pda_power.o diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c new file mode 100644 index 000000000000..4e1eb040e148 --- /dev/null +++ b/drivers/power/pda_power.c @@ -0,0 +1,261 @@ +/* + * Common power driver for PDAs and phones with one or two external + * power supplies (AC/USB) connected to main and backup batteries, + * and optional builtin charger. + * + * Copyright © 2007 Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +static inline unsigned int get_irq_flags(struct resource *res) +{ + unsigned int flags = IRQF_DISABLED | IRQF_SHARED; + + flags |= res->flags & IRQF_TRIGGER_MASK; + + return flags; +} + +static struct device *dev; +static struct pda_power_pdata *pdata; +static struct resource *ac_irq, *usb_irq; +static struct timer_list charger_timer; +static struct timer_list supply_timer; + +static int pda_power_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + if (psy->type == POWER_SUPPLY_TYPE_MAINS) + val->intval = pdata->is_ac_online ? + pdata->is_ac_online() : 0; + else + val->intval = pdata->is_usb_online ? + pdata->is_usb_online() : 0; + break; + default: + return -EINVAL; + } + return 0; +} + +static enum power_supply_property pda_power_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static char *pda_power_supplied_to[] = { + "main-battery", + "backup-battery", +}; + +static struct power_supply pda_power_supplies[] = { + { + .name = "ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .supplied_to = pda_power_supplied_to, + .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), + .properties = pda_power_props, + .num_properties = ARRAY_SIZE(pda_power_props), + .get_property = pda_power_get_property, + }, + { + .name = "usb", + .type = POWER_SUPPLY_TYPE_USB, + .supplied_to = pda_power_supplied_to, + .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), + .properties = pda_power_props, + .num_properties = ARRAY_SIZE(pda_power_props), + .get_property = pda_power_get_property, + }, +}; + +static void update_charger(void) +{ + if (!pdata->set_charge) + return; + + if (pdata->is_ac_online && pdata->is_ac_online()) { + dev_dbg(dev, "charger on (AC)\n"); + pdata->set_charge(PDA_POWER_CHARGE_AC); + } else if (pdata->is_usb_online && pdata->is_usb_online()) { + dev_dbg(dev, "charger on (USB)\n"); + pdata->set_charge(PDA_POWER_CHARGE_USB); + } else { + dev_dbg(dev, "charger off\n"); + pdata->set_charge(0); + } + + return; +} + +static void supply_timer_func(unsigned long irq) +{ + if (ac_irq && irq == ac_irq->start) + power_supply_changed(&pda_power_supplies[0]); + else if (usb_irq && irq == usb_irq->start) + power_supply_changed(&pda_power_supplies[1]); + return; +} + +static void charger_timer_func(unsigned long irq) +{ + update_charger(); + + /* Okay, charger set. Now wait a bit before notifying supplicants, + * charge power should stabilize. */ + supply_timer.data = irq; + mod_timer(&supply_timer, + jiffies + msecs_to_jiffies(pdata->wait_for_charger)); + return; +} + +static irqreturn_t power_changed_isr(int irq, void *unused) +{ + /* Wait a bit before reading ac/usb line status and setting charger, + * because ac/usb status readings may lag from irq. */ + charger_timer.data = irq; + mod_timer(&charger_timer, + jiffies + msecs_to_jiffies(pdata->wait_for_status)); + return IRQ_HANDLED; +} + +static int pda_power_probe(struct platform_device *pdev) +{ + int ret = 0; + + dev = &pdev->dev; + + if (pdev->id != -1) { + dev_err(dev, "it's meaningless to register several " + "pda_powers; use id = -1\n"); + ret = -EINVAL; + goto wrongid; + } + + pdata = pdev->dev.platform_data; + + update_charger(); + + if (!pdata->wait_for_status) + pdata->wait_for_status = 500; + + if (!pdata->wait_for_charger) + pdata->wait_for_charger = 500; + + setup_timer(&charger_timer, charger_timer_func, 0); + setup_timer(&supply_timer, supply_timer_func, 0); + + ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); + usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); + if (!ac_irq && !usb_irq) { + dev_err(dev, "no ac/usb irq specified\n"); + ret = -ENODEV; + goto noirqs; + } + + if (pdata->supplied_to) { + pda_power_supplies[0].supplied_to = pdata->supplied_to; + pda_power_supplies[1].supplied_to = pdata->supplied_to; + pda_power_supplies[0].num_supplicants = pdata->num_supplicants; + pda_power_supplies[1].num_supplicants = pdata->num_supplicants; + } + + ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); + if (ret) { + dev_err(dev, "failed to register %s power supply\n", + pda_power_supplies[0].name); + goto supply0_failed; + } + + ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); + if (ret) { + dev_err(dev, "failed to register %s power supply\n", + pda_power_supplies[1].name); + goto supply1_failed; + } + + if (ac_irq) { + ret = request_irq(ac_irq->start, power_changed_isr, + get_irq_flags(ac_irq), ac_irq->name, + &pda_power_supplies[0]); + if (ret) { + dev_err(dev, "request ac irq failed\n"); + goto ac_irq_failed; + } + } + + if (usb_irq) { + ret = request_irq(usb_irq->start, power_changed_isr, + get_irq_flags(usb_irq), usb_irq->name, + &pda_power_supplies[1]); + if (ret) { + dev_err(dev, "request usb irq failed\n"); + goto usb_irq_failed; + } + } + + goto success; + +usb_irq_failed: + if (ac_irq) + free_irq(ac_irq->start, &pda_power_supplies[0]); +ac_irq_failed: + power_supply_unregister(&pda_power_supplies[1]); +supply1_failed: + power_supply_unregister(&pda_power_supplies[0]); +supply0_failed: +noirqs: +wrongid: +success: + return ret; +} + +static int pda_power_remove(struct platform_device *pdev) +{ + if (usb_irq) + free_irq(usb_irq->start, &pda_power_supplies[1]); + if (ac_irq) + free_irq(ac_irq->start, &pda_power_supplies[0]); + del_timer_sync(&charger_timer); + del_timer_sync(&supply_timer); + power_supply_unregister(&pda_power_supplies[1]); + power_supply_unregister(&pda_power_supplies[0]); + return 0; +} + +static struct platform_driver pda_power_pdrv = { + .driver = { + .name = "pda-power", + }, + .probe = pda_power_probe, + .remove = pda_power_remove, +}; + +static int __init pda_power_init(void) +{ + return platform_driver_register(&pda_power_pdrv); +} + +static void __exit pda_power_exit(void) +{ + platform_driver_unregister(&pda_power_pdrv); + return; +} + +module_init(pda_power_init); +module_exit(pda_power_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Anton Vorontsov "); diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h new file mode 100644 index 000000000000..1375f15797e7 --- /dev/null +++ b/include/linux/pda_power.h @@ -0,0 +1,31 @@ +/* + * Common power driver for PDAs and phones with one or two external + * power supplies (AC/USB) connected to main and backup batteries, + * and optional builtin charger. + * + * Copyright © 2007 Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __PDA_POWER_H__ +#define __PDA_POWER_H__ + +#define PDA_POWER_CHARGE_AC (1 << 0) +#define PDA_POWER_CHARGE_USB (1 << 1) + +struct pda_power_pdata { + int (*is_ac_online)(void); + int (*is_usb_online)(void); + void (*set_charge)(int flags); + + char **supplied_to; + size_t num_supplicants; + + unsigned int wait_for_status; /* msecs, default is 500 */ + unsigned int wait_for_charger; /* msecs, default is 500 */ +}; + +#endif /* __PDA_POWER_H__ */ From 3788ec932bfd4942831e9a5034191509a2e11924 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 4 May 2007 00:43:24 +0400 Subject: [PATCH 434/551] [BATTERY] APM emulation driver for class batteries Signed-off-by: Eugeny Boger Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse --- drivers/power/Kconfig | 7 ++ drivers/power/Makefile | 1 + drivers/power/apm_power.c | 243 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/power/apm_power.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index cc70644db947..791fa0cc45fe 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -21,4 +21,11 @@ config PDA_POWER one or two external power supplies (AC/USB) connected to main and backup batteries, and optional builtin charger. +config APM_POWER + tristate "APM emulation for class batteries" + depends on APM_EMULATION + help + Say Y here to enable support APM status emulation using + battery class devices. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 1ff4b6806381..7779cebcb3ae 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -15,3 +15,4 @@ endif obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_PDA_POWER) += pda_power.o +obj-$(CONFIG_APM_POWER) += apm_power.o diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c new file mode 100644 index 000000000000..042bd950d036 --- /dev/null +++ b/drivers/power/apm_power.c @@ -0,0 +1,243 @@ +/* + * Copyright © 2007 Anton Vorontsov + * Copyright © 2007 Eugeny Boger + * + * Author: Eugeny Boger + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + */ + +#include +#include +#include + +#define PSY_PROP(psy, prop, val) psy->get_property(psy, \ + POWER_SUPPLY_PROP_##prop, val) + +#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \ + prop, val) + +#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) + +static struct power_supply *main_battery; + +static void find_main_battery(void) +{ + struct device *dev; + struct power_supply *bat, *batm; + union power_supply_propval full; + int max_charge = 0; + + main_battery = NULL; + batm = NULL; + list_for_each_entry(dev, &power_supply_class->devices, node) { + bat = dev_get_drvdata(dev); + /* If none of battery devices cantains 'use_for_apm' flag, + choice one with maximum design charge */ + if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) { + if (full.intval > max_charge) { + batm = bat; + max_charge = full.intval; + } + } + + if (bat->use_for_apm) + main_battery = bat; + } + if (!main_battery) + main_battery = batm; + + return; +} + +static int calculate_time(int status) +{ + union power_supply_propval charge_full, charge_empty; + union power_supply_propval charge, I; + + if (MPSY_PROP(CHARGE_FULL, &charge_full)) { + /* if battery can't report this property, use design value */ + if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full)) + return -1; + } + + if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) { + /* if battery can't report this property, use design value */ + if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty)) + charge_empty.intval = 0; + } + + if (MPSY_PROP(CHARGE_AVG, &charge)) { + /* if battery can't report average value, use momentary */ + if (MPSY_PROP(CHARGE_NOW, &charge)) + return -1; + } + + if (MPSY_PROP(CURRENT_AVG, &I)) { + /* if battery can't report average value, use momentary */ + if (MPSY_PROP(CURRENT_NOW, &I)) + return -1; + } + + if (status == POWER_SUPPLY_STATUS_CHARGING) + return ((charge.intval - charge_full.intval) * 60L) / + I.intval; + else + return -((charge.intval - charge_empty.intval) * 60L) / + I.intval; +} + +static int calculate_capacity(int using_charge) +{ + enum power_supply_property full_prop, empty_prop; + enum power_supply_property full_design_prop, empty_design_prop; + enum power_supply_property now_prop, avg_prop; + union power_supply_propval empty, full, cur; + int ret; + + if (using_charge) { + full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; + empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; + full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; + empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN; + now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; + avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; + } else { + full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; + empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; + full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; + empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; + now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; + avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; + } + + if (_MPSY_PROP(full_prop, &full)) { + /* if battery can't report this property, use design value */ + if (_MPSY_PROP(full_design_prop, &full)) + return -1; + } + + if (_MPSY_PROP(avg_prop, &cur)) { + /* if battery can't report average value, use momentary */ + if (_MPSY_PROP(now_prop, &cur)) + return -1; + } + + if (_MPSY_PROP(empty_prop, &empty)) { + /* if battery can't report this property, use design value */ + if (_MPSY_PROP(empty_design_prop, &empty)) + empty.intval = 0; + } + + if (full.intval - empty.intval) + ret = ((cur.intval - empty.intval) * 100L) / + (full.intval - empty.intval); + else + return -1; + + if (ret > 100) + return 100; + else if (ret < 0) + return 0; + + return ret; +} + +static void apm_battery_apm_get_power_status(struct apm_power_info *info) +{ + union power_supply_propval status; + union power_supply_propval capacity, time_to_full, time_to_empty; + + down(&power_supply_class->sem); + find_main_battery(); + if (!main_battery) { + up(&power_supply_class->sem); + return; + } + + /* status */ + + if (MPSY_PROP(STATUS, &status)) + status.intval = POWER_SUPPLY_STATUS_UNKNOWN; + + /* ac line status */ + + if ((status.intval == POWER_SUPPLY_STATUS_CHARGING) || + (status.intval == POWER_SUPPLY_STATUS_NOT_CHARGING) || + (status.intval == POWER_SUPPLY_STATUS_FULL)) + info->ac_line_status = APM_AC_ONLINE; + else + info->ac_line_status = APM_AC_OFFLINE; + + /* battery life (i.e. capacity, in percents) */ + + if (MPSY_PROP(CAPACITY, &capacity) == 0) { + info->battery_life = capacity.intval; + } else { + /* try calculate using energy */ + info->battery_life = calculate_capacity(0); + /* if failed try calculate using charge instead */ + if (info->battery_life == -1) + info->battery_life = calculate_capacity(1); + } + + /* charging status */ + + if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { + info->battery_status = APM_BATTERY_STATUS_CHARGING; + } else { + if (info->battery_life > 50) + info->battery_status = APM_BATTERY_STATUS_HIGH; + else if (info->battery_life > 5) + info->battery_status = APM_BATTERY_STATUS_LOW; + else + info->battery_status = APM_BATTERY_STATUS_CRITICAL; + } + info->battery_flag = info->battery_status; + + /* time */ + + info->units = APM_UNITS_MINS; + + if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { + if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) { + if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) + info->time = calculate_time(status.intval); + else + info->time = time_to_full.intval / 60; + } + } else { + if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) { + if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) + info->time = calculate_time(status.intval); + else + info->time = time_to_empty.intval / 60; + } + } + + up(&power_supply_class->sem); + return; +} + +static int __init apm_battery_init(void) +{ + printk(KERN_INFO "APM Battery Driver\n"); + + apm_get_power_status = apm_battery_apm_get_power_status; + return 0; +} + +static void __exit apm_battery_exit(void) +{ + apm_get_power_status = NULL; + return; +} + +module_init(apm_battery_init); +module_exit(apm_battery_exit); + +MODULE_AUTHOR("Eugeny Boger "); +MODULE_DESCRIPTION("APM emulation driver for battery monitoring class"); +MODULE_LICENSE("GPL"); From fe0e3153acfef4864b69932cf116eb5f38f7500c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 4 May 2007 00:45:39 +0400 Subject: [PATCH 435/551] [BATTERY] 1-Wire ds2760 chip battery driver This is driver for batteries with ds2760 chip inside, found inside almost every HP iPaq and HTC PDAs/phones. Signed-off-by: Anton Vorontsov Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/power/Kconfig | 7 + drivers/power/Makefile | 2 + drivers/power/ds2760_battery.c | 470 +++++++++++++++++++++++++++++++++ 3 files changed, 479 insertions(+) create mode 100644 drivers/power/ds2760_battery.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 791fa0cc45fe..921456243e4b 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -28,4 +28,11 @@ config APM_POWER Say Y here to enable support APM status emulation using battery class devices. +config BATTERY_DS2760 + tristate "DS2760 battery driver (HP iPAQ & others)" + select W1 + select W1_SLAVE_DS2760 + help + Say Y here to enable support for batteries with ds2760 chip. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 7779cebcb3ae..a978ba15f6c5 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -16,3 +16,5 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o + +obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c new file mode 100644 index 000000000000..00e1ea6f1de2 --- /dev/null +++ b/drivers/power/ds2760_battery.c @@ -0,0 +1,470 @@ +/* + * Driver for batteries with DS2760 chips inside. + * + * Copyright © 2007 Anton Vorontsov + * 2004-2007 Matt Reimer + * 2004 Szabolcs Gyurko + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + * + * Author: Anton Vorontsov + * February 2007 + * + * Matt Reimer + * April 2004, 2005, 2007 + * + * Szabolcs Gyurko + * September 2004 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../w1/w1.h" +#include "../w1/slaves/w1_ds2760.h" + +struct ds2760_device_info { + struct device *dev; + + /* DS2760 data, valid after calling ds2760_battery_read_status() */ + unsigned long update_time; /* jiffies when data read */ + char raw[DS2760_DATA_SIZE]; /* raw DS2760 data */ + int voltage_raw; /* units of 4.88 mV */ + int voltage_uV; /* units of µV */ + int current_raw; /* units of 0.625 mA */ + int current_uA; /* units of µA */ + int accum_current_raw; /* units of 0.25 mAh */ + int accum_current_uAh; /* units of µAh */ + int temp_raw; /* units of 0.125 °C */ + int temp_C; /* units of 0.1 °C */ + int rated_capacity; /* units of µAh */ + int rem_capacity; /* percentage */ + int full_active_uAh; /* units of µAh */ + int empty_uAh; /* units of µAh */ + int life_sec; /* units of seconds */ + int charge_status; /* POWER_SUPPLY_STATUS_* */ + + int full_counter; + struct power_supply bat; + struct device *w1_dev; + struct workqueue_struct *monitor_wqueue; + struct delayed_work monitor_work; +}; + +static unsigned int cache_time = 1000; +module_param(cache_time, uint, 0644); +MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); + +/* Some batteries have their rated capacity stored a N * 10 mAh, while + * others use an index into this table. */ +static int rated_capacities[] = { + 0, + 920, /* Samsung */ + 920, /* BYD */ + 920, /* Lishen */ + 920, /* NEC */ + 1440, /* Samsung */ + 1440, /* BYD */ + 1440, /* Lishen */ + 1440, /* NEC */ + 2880, /* Samsung */ + 2880, /* BYD */ + 2880, /* Lishen */ + 2880 /* NEC */ +}; + +/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C + * temp is in Celsius */ +static int battery_interpolate(int array[], int temp) +{ + int index, dt; + + if (temp <= 0) + return array[0]; + if (temp >= 40) + return array[4]; + + index = temp / 10; + dt = temp % 10; + + return array[index] + (((array[index + 1] - array[index]) * dt) / 10); +} + +static int ds2760_battery_read_status(struct ds2760_device_info *di) +{ + int ret, i, start, count, scale[5]; + + if (di->update_time && time_before(jiffies, di->update_time + + msecs_to_jiffies(cache_time))) + return 0; + + /* The first time we read the entire contents of SRAM/EEPROM, + * but after that we just read the interesting bits that change. */ + if (di->update_time == 0) { + start = 0; + count = DS2760_DATA_SIZE; + } else { + start = DS2760_VOLTAGE_MSB; + count = DS2760_TEMP_LSB - start + 1; + } + + ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count); + if (ret != count) { + dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n", + di->w1_dev); + return 1; + } + + di->update_time = jiffies; + + /* DS2760 reports voltage in units of 4.88mV, but the battery class + * reports in units of uV, so convert by multiplying by 4880. */ + di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) | + (di->raw[DS2760_VOLTAGE_LSB] >> 5); + di->voltage_uV = di->voltage_raw * 4880; + + /* DS2760 reports current in signed units of 0.625mA, but the battery + * class reports in units of µA, so convert by multiplying by 625. */ + di->current_raw = + (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) | + (di->raw[DS2760_CURRENT_LSB] >> 3); + di->current_uA = di->current_raw * 625; + + /* DS2760 reports accumulated current in signed units of 0.25mAh. */ + di->accum_current_raw = + (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) | + di->raw[DS2760_CURRENT_ACCUM_LSB]; + di->accum_current_uAh = di->accum_current_raw * 250; + + /* DS2760 reports temperature in signed units of 0.125°C, but the + * battery class reports in units of 1/10 °C, so we convert by + * multiplying by .125 * 10 = 1.25. */ + di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) | + (di->raw[DS2760_TEMP_LSB] >> 5); + di->temp_C = di->temp_raw + (di->temp_raw / 4); + + /* At least some battery monitors (e.g. HP iPAQ) store the battery's + * maximum rated capacity. */ + if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities)) + di->rated_capacity = rated_capacities[ + (unsigned int)di->raw[DS2760_RATED_CAPACITY]]; + else + di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10; + + di->rated_capacity *= 1000; /* convert to µAh */ + + /* Calculate the full level at the present temperature. */ + di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 | + di->raw[DS2760_ACTIVE_FULL + 1]; + + scale[0] = di->raw[DS2760_ACTIVE_FULL] << 8 | + di->raw[DS2760_ACTIVE_FULL + 1]; + for (i = 1; i < 5; i++) + scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i]; + + di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); + di->full_active_uAh *= 1000; /* convert to µAh */ + + /* Calculate the empty level at the present temperature. */ + scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4]; + for (i = 3; i >= 0; i--) + scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i]; + + di->empty_uAh = battery_interpolate(scale, di->temp_C / 10); + di->empty_uAh *= 1000; /* convert to µAh */ + + /* From Maxim Application Note 131: remaining capacity = + * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ + di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / + (di->full_active_uAh - di->empty_uAh); + + if (di->rem_capacity < 0) + di->rem_capacity = 0; + if (di->rem_capacity > 100) + di->rem_capacity = 100; + + if (di->current_uA) + di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * + 3600L) / di->current_uA; + else + di->life_sec = 0; + + return 0; +} + +static void ds2760_battery_update_status(struct ds2760_device_info *di) +{ + int old_charge_status = di->charge_status; + + ds2760_battery_read_status(di); + + if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) + di->full_counter = 0; + + if (power_supply_am_i_supplied(&di->bat)) { + if (di->current_uA > 10000) { + di->charge_status = POWER_SUPPLY_STATUS_CHARGING; + di->full_counter = 0; + } else if (di->current_uA < -5000) { + if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING) + dev_notice(di->dev, "not enough power to " + "charge\n"); + di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; + di->full_counter = 0; + } else if (di->current_uA < 10000 && + di->charge_status != POWER_SUPPLY_STATUS_FULL) { + + /* Don't consider the battery to be full unless + * we've seen the current < 10 mA at least two + * consecutive times. */ + + di->full_counter++; + + if (di->full_counter < 2) { + di->charge_status = POWER_SUPPLY_STATUS_CHARGING; + } else { + unsigned char acr[2]; + int acr_val; + + /* acr is in units of 0.25 mAh */ + acr_val = di->full_active_uAh * 4L / 1000; + + acr[0] = acr_val >> 8; + acr[1] = acr_val & 0xff; + + if (w1_ds2760_write(di->w1_dev, acr, + DS2760_CURRENT_ACCUM_MSB, 2) < 2) + dev_warn(di->dev, + "ACR reset failed\n"); + + di->charge_status = POWER_SUPPLY_STATUS_FULL; + } + } + } else { + di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + di->full_counter = 0; + } + + if (di->charge_status != old_charge_status) + power_supply_changed(&di->bat); + + return; +} + +static void ds2760_battery_work(struct work_struct *work) +{ + struct ds2760_device_info *di = container_of(work, + struct ds2760_device_info, monitor_work.work); + const int interval = HZ * 60; + + dev_dbg(di->dev, "%s\n", __FUNCTION__); + + ds2760_battery_update_status(di); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); + + return; +} + +#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \ + bat); + +static void ds2760_battery_external_power_changed(struct power_supply *psy) +{ + struct ds2760_device_info *di = to_ds2760_device_info(psy); + + dev_dbg(di->dev, "%s\n", __FUNCTION__); + + cancel_delayed_work(&di->monitor_work); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10); + + return; +} + +static int ds2760_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct ds2760_device_info *di = to_ds2760_device_info(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = di->charge_status; + return 0; + default: + break; + } + + ds2760_battery_read_status(di); + + switch (psp) { + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = di->voltage_uV; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = di->current_uA; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = di->rated_capacity; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + val->intval = di->full_active_uAh; + break; + case POWER_SUPPLY_PROP_CHARGE_EMPTY: + val->intval = di->empty_uAh; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = di->accum_current_uAh; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = di->temp_C; + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property ds2760_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_EMPTY, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_TEMP, +}; + +static int ds2760_battery_probe(struct platform_device *pdev) +{ + int retval = 0; + struct ds2760_device_info *di; + struct ds2760_platform_data *pdata; + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + retval = -ENOMEM; + goto di_alloc_failed; + } + + platform_set_drvdata(pdev, di); + + pdata = pdev->dev.platform_data; + di->dev = &pdev->dev; + di->w1_dev = pdev->dev.parent; + di->bat.name = pdev->dev.bus_id; + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->bat.properties = ds2760_battery_props; + di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); + di->bat.get_property = ds2760_battery_get_property; + di->bat.external_power_changed = + ds2760_battery_external_power_changed; + + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; + + retval = power_supply_register(&pdev->dev, &di->bat); + if (retval) { + dev_err(di->dev, "failed to register battery"); + goto batt_failed; + } + + INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); + di->monitor_wqueue = create_singlethread_workqueue(pdev->dev.bus_id); + if (!di->monitor_wqueue) { + retval = -ESRCH; + goto workqueue_failed; + } + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1); + + goto success; + +workqueue_failed: + power_supply_unregister(&di->bat); +batt_failed: + kfree(di); +di_alloc_failed: +success: + return retval; +} + +static int ds2760_battery_remove(struct platform_device *pdev) +{ + struct ds2760_device_info *di = platform_get_drvdata(pdev); + + cancel_rearming_delayed_workqueue(di->monitor_wqueue, + &di->monitor_work); + destroy_workqueue(di->monitor_wqueue); + power_supply_unregister(&di->bat); + + return 0; +} + +#ifdef CONFIG_PM + +static int ds2760_battery_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct ds2760_device_info *di = platform_get_drvdata(pdev); + + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; + + return 0; +} + +static int ds2760_battery_resume(struct platform_device *pdev) +{ + struct ds2760_device_info *di = platform_get_drvdata(pdev); + + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; + power_supply_changed(&di->bat); + + cancel_delayed_work(&di->monitor_work); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); + + return 0; +} + +#else + +#define ds2760_battery_suspend NULL +#define ds2760_battery_resume NULL + +#endif /* CONFIG_PM */ + +static struct platform_driver ds2760_battery_driver = { + .driver = { + .name = "ds2760-battery", + }, + .probe = ds2760_battery_probe, + .remove = ds2760_battery_remove, + .suspend = ds2760_battery_suspend, + .resume = ds2760_battery_resume, +}; + +static int __init ds2760_battery_init(void) +{ + return platform_driver_register(&ds2760_battery_driver); +} + +static void __exit ds2760_battery_exit(void) +{ + platform_driver_unregister(&ds2760_battery_driver); + return; +} + +module_init(ds2760_battery_init); +module_exit(ds2760_battery_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Szabolcs Gyurko , " + "Matt Reimer , " + "Anton Vorontsov "); +MODULE_DESCRIPTION("ds2760 battery driver"); From efea58e397dec84e37209c98619d39a46872db4d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 4 May 2007 00:47:40 +0400 Subject: [PATCH 436/551] [BATTERY] Apple PMU driver Signed-off-by: David Woodhouse Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 7 ++ drivers/power/Makefile | 1 + drivers/power/pmu_battery.c | 215 ++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 drivers/power/pmu_battery.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 921456243e4b..051724f62fa3 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -35,4 +35,11 @@ config BATTERY_DS2760 help Say Y here to enable support for batteries with ds2760 chip. +config BATTERY_PMU + tristate "Apple PMU battery" + depends on ADB_PMU + help + Say Y here to expose battery information on Apple machines + through the generic battery class. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a978ba15f6c5..a072b0400cda 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o +obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c new file mode 100644 index 000000000000..2fea4af0e40a --- /dev/null +++ b/drivers/power/pmu_battery.c @@ -0,0 +1,215 @@ +/* + * Battery class driver for Apple PMU + * + * Copyright © 2006 David Woodhouse + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +static struct pmu_battery_dev { + struct power_supply bat; + struct pmu_battery_info *pbi; + char name[16]; + int propval; +} *pbats[PMU_MAX_BATTERIES]; + +#define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat) + +/********************************************************************* + * Power + *********************************************************************/ + +static int pmu_get_ac_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = (!!(pmu_power_flags & PMU_PWR_AC_PRESENT)) || + (pmu_battery_count == 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property pmu_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static struct power_supply pmu_ac = { + .name = "pmu-ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = pmu_ac_props, + .num_properties = ARRAY_SIZE(pmu_ac_props), + .get_property = pmu_get_ac_prop, +}; + +/********************************************************************* + * Battery properties + *********************************************************************/ + +static char *pmu_batt_types[] = { + "Smart", "Comet", "Hooper", "Unknown" +}; + +static char *pmu_bat_get_model_name(struct pmu_battery_info *pbi) +{ + switch (pbi->flags & PMU_BATT_TYPE_MASK) { + case PMU_BATT_TYPE_SMART: + return pmu_batt_types[0]; + case PMU_BATT_TYPE_COMET: + return pmu_batt_types[1]; + case PMU_BATT_TYPE_HOOPER: + return pmu_batt_types[2]; + default: break; + } + return pmu_batt_types[3]; +} + +static int pmu_bat_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct pmu_battery_dev *pbat = to_pmu_battery_dev(psy); + struct pmu_battery_info *pbi = pbat->pbi; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (pbi->flags & PMU_BATT_CHARGING) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = !!(pbi->flags & PMU_BATT_PRESENT); + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = pmu_bat_get_model_name(pbi); + break; + case POWER_SUPPLY_PROP_ENERGY_AVG: + val->intval = pbi->charge * 1000; /* mWh -> µWh */ + break; + case POWER_SUPPLY_PROP_ENERGY_FULL: + val->intval = pbi->max_charge * 1000; /* mWh -> µWh */ + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + val->intval = pbi->amperage * 1000; /* mA -> µA */ + break; + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + val->intval = pbi->voltage * 1000; /* mV -> µV */ + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: + val->intval = pbi->time_remaining; + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property pmu_bat_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_ENERGY_AVG, + POWER_SUPPLY_PROP_ENERGY_FULL, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, +}; + +/********************************************************************* + * Initialisation + *********************************************************************/ + +static struct platform_device *bat_pdev; + +static int __init pmu_bat_init(void) +{ + int ret; + int i; + + bat_pdev = platform_device_register_simple("pmu-battery", + 0, NULL, 0); + if (IS_ERR(bat_pdev)) { + ret = PTR_ERR(bat_pdev); + goto pdev_register_failed; + } + + ret = power_supply_register(&bat_pdev->dev, &pmu_ac); + if (ret) + goto ac_register_failed; + + for (i = 0; i < pmu_battery_count; i++) { + struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat), + GFP_KERNEL); + if (!pbat) + break; + + sprintf(pbat->name, "PMU battery %d", i); + pbat->bat.name = pbat->name; + pbat->bat.properties = pmu_bat_props; + pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props); + pbat->bat.get_property = pmu_bat_get_property; + pbat->pbi = &pmu_batteries[i]; + + ret = power_supply_register(&bat_pdev->dev, &pbat->bat); + if (ret) { + kfree(pbat); + goto battery_register_failed; + } + pbats[i] = pbat; + } + + goto success; + +battery_register_failed: + while (i--) { + if (!pbats[i]) + continue; + power_supply_unregister(&pbats[i]->bat); + kfree(pbats[i]); + } + power_supply_unregister(&pmu_ac); +ac_register_failed: + platform_device_unregister(bat_pdev); +pdev_register_failed: +success: + return ret; +} + +static void __exit pmu_bat_exit(void) +{ + int i; + + for (i = 0; i < PMU_MAX_BATTERIES; i++) { + if (!pbats[i]) + continue; + power_supply_unregister(&pbats[i]->bat); + kfree(pbats[i]); + } + power_supply_unregister(&pmu_ac); + platform_device_unregister(bat_pdev); + + return; +} + +module_init(pmu_bat_init); +module_exit(pmu_bat_exit); + +MODULE_AUTHOR("David Woodhouse "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PMU battery driver"); From fb972873a767220333ffb509de8d9131336e212c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 4 May 2007 00:51:18 +0400 Subject: [PATCH 437/551] [BATTERY] One Laptop Per Child power/battery driver Signed-off-by: David Woodhouse Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 6 + drivers/power/Makefile | 1 + drivers/power/olpc_battery.c | 352 +++++++++++++++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 drivers/power/olpc_battery.c diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 051724f62fa3..ab9c3e5a7c1d 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -42,4 +42,10 @@ config BATTERY_PMU Say Y here to expose battery information on Apple machines through the generic battery class. +config BATTERY_OLPC + tristate "One Laptop Per Child battery" + depends on X86_32 && OLPC + help + Say Y to enable support for the battery on the OLPC laptop. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a072b0400cda..6413ded5fe5f 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_APM_POWER) += apm_power.o obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o +obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c new file mode 100644 index 000000000000..878684df7667 --- /dev/null +++ b/drivers/power/olpc_battery.c @@ -0,0 +1,352 @@ +/* + * Battery driver for One Laptop Per Child board. + * + * Copyright © 2006 David Woodhouse + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#define EC_BAT_VOLTAGE 0x10 /* uint16_t, *9.76/32, mV */ +#define EC_BAT_CURRENT 0x11 /* int16_t, *15.625/120, mA */ +#define EC_BAT_ACR 0x12 +#define EC_BAT_TEMP 0x13 /* uint16_t, *100/256, °C */ +#define EC_AMB_TEMP 0x14 /* uint16_t, *100/256, °C */ +#define EC_BAT_STATUS 0x15 /* uint8_t, bitmask */ +#define EC_BAT_SOC 0x16 /* uint8_t, percentage */ +#define EC_BAT_SERIAL 0x17 /* uint8_t[6] */ +#define EC_BAT_EEPROM 0x18 /* uint8_t adr as input, uint8_t output */ +#define EC_BAT_ERRCODE 0x1f /* uint8_t, bitmask */ + +#define BAT_STAT_PRESENT 0x01 +#define BAT_STAT_FULL 0x02 +#define BAT_STAT_LOW 0x04 +#define BAT_STAT_DESTROY 0x08 +#define BAT_STAT_AC 0x10 +#define BAT_STAT_CHARGING 0x20 +#define BAT_STAT_DISCHARGING 0x40 + +#define BAT_ERR_INFOFAIL 0x02 +#define BAT_ERR_OVERVOLTAGE 0x04 +#define BAT_ERR_OVERTEMP 0x05 +#define BAT_ERR_GAUGESTOP 0x06 +#define BAT_ERR_OUT_OF_CONTROL 0x07 +#define BAT_ERR_ID_FAIL 0x09 +#define BAT_ERR_ACR_FAIL 0x10 + +#define BAT_ADDR_MFR_TYPE 0x5F + +/********************************************************************* + * Power + *********************************************************************/ + +static int olpc_ac_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + uint8_t status; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); + if (ret) + return ret; + + val->intval = !!(status & BAT_STAT_AC); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static enum power_supply_property olpc_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static struct power_supply olpc_ac = { + .name = "olpc-ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = olpc_ac_props, + .num_properties = ARRAY_SIZE(olpc_ac_props), + .get_property = olpc_ac_get_prop, +}; + +/********************************************************************* + * Battery properties + *********************************************************************/ +static int olpc_bat_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + int16_t ec_word; + uint8_t ec_byte; + + ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1); + if (ret) + return ret; + + /* Theoretically there's a race here -- the battery could be + removed immediately after we check whether it's present, and + then we query for some other property of the now-absent battery. + It doesn't matter though -- the EC will return the last-known + information, and it's as if we just ran that _little_ bit faster + and managed to read it out before the battery went away. */ + if (!(ec_byte & BAT_STAT_PRESENT) && psp != POWER_SUPPLY_PROP_PRESENT) + return -ENODEV; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (olpc_platform_info.ecver > 0x44) { + if (ec_byte & BAT_STAT_CHARGING) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (ec_byte & BAT_STAT_DISCHARGING) + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + else if (ec_byte & BAT_STAT_FULL) + val->intval = POWER_SUPPLY_STATUS_FULL; + else /* er,... */ + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + } else { + /* Older EC didn't report charge/discharge bits */ + if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */ + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + else if (ec_byte & BAT_STAT_FULL) + val->intval = POWER_SUPPLY_STATUS_FULL; + else /* Not _necessarily_ true but EC doesn't tell all yet */ + val->intval = POWER_SUPPLY_STATUS_CHARGING; + break; + } + case POWER_SUPPLY_PROP_PRESENT: + val->intval = !!(ec_byte & BAT_STAT_PRESENT); + break; + + case POWER_SUPPLY_PROP_HEALTH: + if (ec_byte & BAT_STAT_DESTROY) + val->intval = POWER_SUPPLY_HEALTH_DEAD; + else { + ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1); + if (ret) + return ret; + + switch (ec_byte) { + case 0: + val->intval = POWER_SUPPLY_HEALTH_GOOD; + break; + + case BAT_ERR_OVERTEMP: + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; + break; + + case BAT_ERR_OVERVOLTAGE: + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + break; + + case BAT_ERR_INFOFAIL: + case BAT_ERR_OUT_OF_CONTROL: + case BAT_ERR_ID_FAIL: + case BAT_ERR_ACR_FAIL: + val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + break; + + default: + /* Eep. We don't know this failure code */ + return -EIO; + } + } + break; + + case POWER_SUPPLY_PROP_MANUFACTURER: + ec_byte = BAT_ADDR_MFR_TYPE; + ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1); + if (ret) + return ret; + + switch (ec_byte >> 4) { + case 1: + val->strval = "Gold Peak"; + break; + case 2: + val->strval = "BYD"; + break; + default: + val->strval = "Unknown"; + break; + } + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + ec_byte = BAT_ADDR_MFR_TYPE; + ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1); + if (ret) + return ret; + + switch (ec_byte & 0xf) { + case 1: + val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH; + break; + case 2: + val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe; + break; + default: + val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; + break; + } + break; + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); + if (ret) + return ret; + + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 9760L / 32; + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); + if (ret) + return ret; + + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 15625L / 120; + break; + case POWER_SUPPLY_PROP_CAPACITY: + ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); + if (ret) + return ret; + val->intval = ec_byte; + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + if (ec_byte & BAT_STAT_FULL) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; + else if (ec_byte & BAT_STAT_LOW) + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; + else + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; + break; + case POWER_SUPPLY_PROP_TEMP: + ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); + if (ret) + return ret; + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 100 / 256; + break; + case POWER_SUPPLY_PROP_TEMP_AMBIENT: + ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); + if (ret) + return ret; + + ec_word = be16_to_cpu(ec_word); + val->intval = ec_word * 100 / 256; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static enum power_supply_property olpc_bat_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_TEMP_AMBIENT, + POWER_SUPPLY_PROP_MANUFACTURER, +}; + +/********************************************************************* + * Initialisation + *********************************************************************/ + +static struct platform_device *bat_pdev; + +static struct power_supply olpc_bat = { + .properties = olpc_bat_props, + .num_properties = ARRAY_SIZE(olpc_bat_props), + .get_property = olpc_bat_get_property, + .use_for_apm = 1, +}; + +void olpc_battery_trigger_uevent(unsigned long cause) +{ + if (cause & EC_SCI_SRC_ACPWR) + kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE); + if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY)) + kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE); +} + +static int __init olpc_bat_init(void) +{ + int ret = 0; + uint8_t status; + + if (!olpc_platform_info.ecver) + return -ENXIO; + if (olpc_platform_info.ecver < 0x43) { + printk(KERN_NOTICE "OLPC EC version 0x%02x too old for battery driver.\n", olpc_platform_info.ecver); + return -ENXIO; + } + + ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); + if (ret) + return ret; + + /* Ignore the status. It doesn't actually matter */ + + bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0); + if (IS_ERR(bat_pdev)) + return PTR_ERR(bat_pdev); + + ret = power_supply_register(&bat_pdev->dev, &olpc_ac); + if (ret) + goto ac_failed; + + olpc_bat.name = bat_pdev->name; + + ret = power_supply_register(&bat_pdev->dev, &olpc_bat); + if (ret) + goto battery_failed; + + olpc_register_battery_callback(&olpc_battery_trigger_uevent); + goto success; + +battery_failed: + power_supply_unregister(&olpc_ac); +ac_failed: + platform_device_unregister(bat_pdev); +success: + return ret; +} + +static void __exit olpc_bat_exit(void) +{ + olpc_deregister_battery_callback(); + power_supply_unregister(&olpc_bat); + power_supply_unregister(&olpc_ac); + platform_device_unregister(bat_pdev); + return; +} + +module_init(olpc_bat_init); +module_exit(olpc_bat_exit); + +MODULE_AUTHOR("David Woodhouse "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Battery driver for One Laptop Per Child 'XO' machine"); From d7ce6d1d5f6e307a2fbb69626cf120e20e793fe7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 12 Apr 2007 01:03:55 +0400 Subject: [PATCH 438/551] [BATTERY] ds2760 W1 slave This is W1 slave for ds2760 chip, found inside almost every HP iPaq and HTC PDAs/phones. Signed-off-by: Anton Vorontsov Acked-by: Evgeniy Polyakov Signed-off-by: David Woodhouse --- drivers/w1/slaves/Kconfig | 13 +++ drivers/w1/slaves/Makefile | 1 + drivers/w1/slaves/w1_ds2760.c | 213 ++++++++++++++++++++++++++++++++++ drivers/w1/slaves/w1_ds2760.h | 50 ++++++++ drivers/w1/w1_family.h | 1 + 5 files changed, 278 insertions(+) create mode 100644 drivers/w1/slaves/w1_ds2760.c create mode 100644 drivers/w1/slaves/w1_ds2760.h diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 904e5aeb696c..df95d6c2cefa 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig @@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC Each block has 30 bytes of data and a two byte CRC16. Full block writes are only allowed if the CRC is valid. +config W1_SLAVE_DS2760 + tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)" + depends on W1 + help + If you enable this you will have the DS2760 battery monitor + chip support. + + The battery monitor chip is used in many batteries/devices + as the one who is responsible for charging/discharging/monitoring + Li+ batteries. + + If you are unsure, say N. + endmenu diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 725dcfdfddb4..a8eb7524df1d 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o +obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c new file mode 100644 index 000000000000..88a37fbccc3f --- /dev/null +++ b/drivers/w1/slaves/w1_ds2760.c @@ -0,0 +1,213 @@ +/* + * 1-Wire implementation for the ds2760 chip + * + * Copyright © 2004-2005, Szabolcs Gyurko + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../w1.h" +#include "../w1_int.h" +#include "../w1_family.h" +#include "w1_ds2760.h" + +static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, + int io) +{ + struct w1_slave *sl = container_of(dev, struct w1_slave, dev); + + if (!dev) + return 0; + + mutex_lock(&sl->master->mutex); + + if (addr > DS2760_DATA_SIZE || addr < 0) { + count = 0; + goto out; + } + if (addr + count > DS2760_DATA_SIZE) + count = DS2760_DATA_SIZE - addr; + + if (!w1_reset_select_slave(sl)) { + if (!io) { + w1_write_8(sl->master, W1_DS2760_READ_DATA); + w1_write_8(sl->master, addr); + count = w1_read_block(sl->master, buf, count); + } else { + w1_write_8(sl->master, W1_DS2760_WRITE_DATA); + w1_write_8(sl->master, addr); + w1_write_block(sl->master, buf, count); + /* XXX w1_write_block returns void, not n_written */ + } + } + +out: + mutex_unlock(&sl->master->mutex); + + return count; +} + +int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count) +{ + return w1_ds2760_io(dev, buf, addr, count, 0); +} + +int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count) +{ + return w1_ds2760_io(dev, buf, addr, count, 1); +} + +static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off, + size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + return w1_ds2760_read(dev, buf, off, count); +} + +static struct bin_attribute w1_ds2760_bin_attr = { + .attr = { + .name = "w1_slave", + .mode = S_IRUGO, + .owner = THIS_MODULE, + }, + .size = DS2760_DATA_SIZE, + .read = w1_ds2760_read_bin, +}; + +static DEFINE_IDR(bat_idr); +static DEFINE_MUTEX(bat_idr_lock); + +static int new_bat_id(void) +{ + int ret; + + while (1) { + int id; + + ret = idr_pre_get(&bat_idr, GFP_KERNEL); + if (ret == 0) + return -ENOMEM; + + mutex_lock(&bat_idr_lock); + ret = idr_get_new(&bat_idr, NULL, &id); + mutex_unlock(&bat_idr_lock); + + if (ret == 0) { + ret = id & MAX_ID_MASK; + break; + } else if (ret == -EAGAIN) { + continue; + } else { + break; + } + } + + return ret; +} + +static void release_bat_id(int id) +{ + mutex_lock(&bat_idr_lock); + idr_remove(&bat_idr, id); + mutex_unlock(&bat_idr_lock); + + return; +} + +static int w1_ds2760_add_slave(struct w1_slave *sl) +{ + int ret; + int id; + struct platform_device *pdev; + + id = new_bat_id(); + if (id < 0) { + ret = id; + goto noid; + } + + pdev = platform_device_alloc("ds2760-battery", id); + if (!pdev) { + ret = -ENOMEM; + goto pdev_alloc_failed; + } + pdev->dev.parent = &sl->dev; + + ret = platform_device_add(pdev); + if (ret) + goto pdev_add_failed; + + ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); + if (ret) + goto bin_attr_failed; + + dev_set_drvdata(&sl->dev, pdev); + + goto success; + +bin_attr_failed: +pdev_add_failed: + platform_device_unregister(pdev); +pdev_alloc_failed: + release_bat_id(id); +noid: +success: + return ret; +} + +static void w1_ds2760_remove_slave(struct w1_slave *sl) +{ + struct platform_device *pdev = dev_get_drvdata(&sl->dev); + int id = pdev->id; + + platform_device_unregister(pdev); + release_bat_id(id); + sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); + + return; +} + +static struct w1_family_ops w1_ds2760_fops = { + .add_slave = w1_ds2760_add_slave, + .remove_slave = w1_ds2760_remove_slave, +}; + +static struct w1_family w1_ds2760_family = { + .fid = W1_FAMILY_DS2760, + .fops = &w1_ds2760_fops, +}; + +static int __init w1_ds2760_init(void) +{ + printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor " + " chip - (c) 2004-2005, Szabolcs Gyurko\n"); + idr_init(&bat_idr); + return w1_register_family(&w1_ds2760_family); +} + +static void __exit w1_ds2760_exit(void) +{ + w1_unregister_family(&w1_ds2760_family); + idr_destroy(&bat_idr); +} + +EXPORT_SYMBOL(w1_ds2760_read); +EXPORT_SYMBOL(w1_ds2760_write); + +module_init(w1_ds2760_init); +module_exit(w1_ds2760_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Szabolcs Gyurko "); +MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h new file mode 100644 index 000000000000..f1302429cb02 --- /dev/null +++ b/drivers/w1/slaves/w1_ds2760.h @@ -0,0 +1,50 @@ +/* + * 1-Wire implementation for the ds2760 chip + * + * Copyright © 2004-2005, Szabolcs Gyurko + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + * + */ + +#ifndef __w1_ds2760_h__ +#define __w1_ds2760_h__ + +/* Known commands to the DS2760 chip */ +#define W1_DS2760_SWAP 0xAA +#define W1_DS2760_READ_DATA 0x69 +#define W1_DS2760_WRITE_DATA 0x6C +#define W1_DS2760_COPY_DATA 0x48 +#define W1_DS2760_RECALL_DATA 0xB8 +#define W1_DS2760_LOCK 0x6A + +/* Number of valid register addresses */ +#define DS2760_DATA_SIZE 0x40 + +#define DS2760_PROTECTION_REG 0x00 +#define DS2760_STATUS_REG 0x01 +#define DS2760_EEPROM_REG 0x07 +#define DS2760_SPECIAL_FEATURE_REG 0x08 +#define DS2760_VOLTAGE_MSB 0x0c +#define DS2760_VOLTAGE_LSB 0x0d +#define DS2760_CURRENT_MSB 0x0e +#define DS2760_CURRENT_LSB 0x0f +#define DS2760_CURRENT_ACCUM_MSB 0x10 +#define DS2760_CURRENT_ACCUM_LSB 0x11 +#define DS2760_TEMP_MSB 0x18 +#define DS2760_TEMP_LSB 0x19 +#define DS2760_EEPROM_BLOCK0 0x20 +#define DS2760_ACTIVE_FULL 0x20 +#define DS2760_EEPROM_BLOCK1 0x30 +#define DS2760_RATED_CAPACITY 0x32 +#define DS2760_CURRENT_OFFSET_BIAS 0x33 +#define DS2760_ACTIVE_EMPTY 0x3b + +extern int w1_ds2760_read(struct device *dev, char *buf, int addr, + size_t count); +extern int w1_ds2760_write(struct device *dev, char *buf, int addr, + size_t count); + +#endif /* !__w1_ds2760_h__ */ diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 1e2ac40c2c14..ef1e1dafa19a 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h @@ -33,6 +33,7 @@ #define W1_THERM_DS1822 0x22 #define W1_EEPROM_DS2433 0x23 #define W1_THERM_DS18B20 0x28 +#define W1_FAMILY_DS2760 0x30 #define MAXNAMELEN 32 From 3ebf44902f77537b5784eb5059c2b78d8b5a920a Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 10 Jul 2007 12:28:27 +0100 Subject: [PATCH 439/551] [GFS2] Accept old format NFS filehandles On Tue, 2007-07-10 at 10:06 +0100, Christoph Hellwig wrote: > > -#define GFS2_LARGE_FH_SIZE 10 > > - > > -struct gfs2_fh_obj { > > - struct gfs2_inum_host this; > > - u32 imode; > > -}; > > +#define GFS2_LARGE_FH_SIZE 8 > > Because gfs2_decode_fh only accepts file handles with GFS2_LARGE_FH_SIZE > or GFS2_LARGE_FH_SIZE you don't accept filehandles sent out by and older > gfs version anymore. Stale filehandles because of a new kernel version > are a big no-no, so please add back code to handle the old filehandles > on the decode side. > This should fix that problem I think since its only relating to end of the fh we can just ignore that field in order to accept the older format. Signed-off-by: Steven Whitehouse Cc: Christoph Hellwig Cc: Wendy Cheng --- fs/gfs2/ops_export.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index e317db2a5548..99ea5659bc2c 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c @@ -28,6 +28,7 @@ #define GFS2_SMALL_FH_SIZE 4 #define GFS2_LARGE_FH_SIZE 8 +#define GFS2_OLD_FH_SIZE 10 static struct dentry *gfs2_decode_fh(struct super_block *sb, __u32 *p, @@ -44,6 +45,7 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, switch (fh_len) { case GFS2_LARGE_FH_SIZE: + case GFS2_OLD_FH_SIZE: parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; parent.no_formal_ino |= be32_to_cpu(fh[5]); parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; From 15c31be4d5bd2402c6f5a288d56a24edc9252b71 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 10 Jul 2007 13:43:25 +0200 Subject: [PATCH 440/551] cfq-iosched: fix async queue behaviour With the cfq_queue hash removal, we inadvertently got rid of the async queue sharing. This was not intentional, in fact CFQ purposely shares the async queue per priority level to get good merging for async writes. So put some logic in cfq_get_queue() to track the shared queues. Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 39 ++++++++++++++++++++++++++++++++++++--- include/linux/ioprio.h | 6 ++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index baef5fc7cff8..e0aa4dad6742 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -92,6 +92,8 @@ struct cfq_data { struct cfq_queue *active_queue; struct cfq_io_context *active_cic; + struct cfq_queue *async_cfqq[IOPRIO_BE_NR]; + struct timer_list idle_class_timer; sector_t last_position; @@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc) } static struct cfq_queue * -cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, - gfp_t gfp_mask) +cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, + struct task_struct *tsk, gfp_t gfp_mask) { struct cfq_queue *cfqq, *new_cfqq = NULL; struct cfq_io_context *cic; @@ -1405,12 +1407,35 @@ retry: if (new_cfqq) kmem_cache_free(cfq_pool, new_cfqq); - atomic_inc(&cfqq->ref); out: WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq); return cfqq; } +static struct cfq_queue * +cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, + gfp_t gfp_mask) +{ + const int ioprio = task_ioprio(tsk); + struct cfq_queue *cfqq = NULL; + + if (!is_sync) + cfqq = cfqd->async_cfqq[ioprio]; + if (!cfqq) + cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); + + /* + * pin the queue now that it's allocated, scheduler exit will prune it + */ + if (!is_sync && !cfqd->async_cfqq[ioprio]) { + atomic_inc(&cfqq->ref); + cfqd->async_cfqq[ioprio] = cfqq; + } + + atomic_inc(&cfqq->ref); + return cfqq; +} + /* * We drop cfq io contexts lazily, so we may find a dead one. */ @@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e) { struct cfq_data *cfqd = e->elevator_data; request_queue_t *q = cfqd->queue; + int i; cfq_shutdown_timer_wq(cfqd); @@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e) __cfq_exit_single_io_context(cfqd, cic); } + /* + * Put the async queues + */ + for (i = 0; i < IOPRIO_BE_NR; i++) + if (cfqd->async_cfqq[i]) + cfq_put_queue(cfqd->async_cfqq[i]); + spin_unlock_irq(q->queue_lock); cfq_shutdown_timer_wq(cfqd); diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h index 8e2042b9d471..2eaa142cd061 100644 --- a/include/linux/ioprio.h +++ b/include/linux/ioprio.h @@ -47,8 +47,10 @@ enum { #define IOPRIO_NORM (4) static inline int task_ioprio(struct task_struct *task) { - WARN_ON(!ioprio_valid(task->ioprio)); - return IOPRIO_PRIO_DATA(task->ioprio); + if (ioprio_valid(task->ioprio)) + return IOPRIO_PRIO_DATA(task->ioprio); + + return IOPRIO_NORM; } static inline int task_nice_ioprio(struct task_struct *task) From 16ed002f224738366c1809023ec70a71ae51421c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 10 Jul 2007 12:24:11 +0200 Subject: [PATCH 441/551] Use menuconfigs instead of menus, so the whole menu can be disabled at once instead of going through all options. Signed-off-by: Jan Engelhardt Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- block/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/Kconfig b/block/Kconfig index a50f48111647..285935134bcd 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -1,7 +1,7 @@ # # Block layer core configuration # -config BLOCK +menuconfig BLOCK bool "Enable the block layer" if EMBEDDED default y help @@ -49,6 +49,6 @@ config LSF If unsure, say Y. -endif +endif # BLOCK source block/Kconfig.iosched From 5f5c926e3cba972636b50ab872b421e992d4f401 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 10 Jul 2007 12:24:17 +0200 Subject: [PATCH 442/551] block/Kconfig already has its own "menuconfig" so remove these "menu, endmenu" that did not get cleaned up in the block patch [ http://lkml.org/lkml/2007/4/10/251 ] Signed-off-by: Jan Engelhardt Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- init/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index a9e99f8328ff..d9d878a3bb46 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -686,6 +686,4 @@ config STOP_MACHINE Need stop_machine() primitive. endmenu -menu "Block layer" source "block/Kconfig" -endmenu From fd11d171e51a5b81c176d856d5df5612117e1a45 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 10 Jul 2007 12:26:06 +0200 Subject: [PATCH 443/551] Make a "menuconfig" out of the Kconfig objects "menu, ..., endmenu", so that the user can disable all the options in that menu at once instead of having to disable each option separately. Signed-off-by: Jan Engelhardt Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index d6ad7b3ea0dc..6e23af1ecbdb 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -2,9 +2,12 @@ # Block device driver configuration # -if BLOCK +menuconfig BLK_DEV + bool "Block devices" + depends on BLOCK + default y -menu "Block devices" +if BLK_DEV config BLK_DEV_FD tristate "Normal floppy disk support" @@ -422,6 +425,4 @@ config ATA_OVER_ETH source "drivers/s390/block/Kconfig" -endmenu - -endif +endif # BLK_DEV From 70cee26e020c1d74ff559c991b96c7b19fa4173b Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Tue, 10 Jul 2007 12:26:24 +0200 Subject: [PATCH 444/551] Use list_for_each_entry() instead of list_for_each() in the block device elevator Signed-off-by: Matthias Kaehlcke Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- block/elevator.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/block/elevator.c b/block/elevator.c index ce866eb75f6a..4769a25d7037 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -112,12 +112,8 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio) static struct elevator_type *elevator_find(const char *name) { struct elevator_type *e; - struct list_head *entry; - - list_for_each(entry, &elv_list) { - - e = list_entry(entry, struct elevator_type, list); + list_for_each_entry(e, &elv_list, list) { if (!strcmp(e->elevator_name, name)) return e; } @@ -1116,14 +1112,11 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) { elevator_t *e = q->elevator; struct elevator_type *elv = e->elevator_type; - struct list_head *entry; + struct elevator_type *__e; int len = 0; spin_lock(&elv_list_lock); - list_for_each(entry, &elv_list) { - struct elevator_type *__e; - - __e = list_entry(entry, struct elevator_type, list); + list_for_each_entry(__e, &elv_list, list) { if (!strcmp(elv->elevator_name, __e->elevator_name)) len += sprintf(name+len, "[%s] ", elv->elevator_name); else From c0613c1c940dac991b9e54db75dc9976491d9f0a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Jul 2007 12:26:29 +0200 Subject: [PATCH 445/551] Documentation/block/barrier.txt is not in sync with the actual code: - blk_queue_ordered() no longer has a gfp_mask parameter - blk_queue_ordered_locked() no longer exists - sd_prepare_flush() looks slightly different Signed-off-by: Geert Uytterhoeven Acked-by: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- Documentation/block/barrier.txt | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Documentation/block/barrier.txt b/Documentation/block/barrier.txt index a272c3db8094..7d279f2f5bb2 100644 --- a/Documentation/block/barrier.txt +++ b/Documentation/block/barrier.txt @@ -82,23 +82,12 @@ including draining and flushing. typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq); int blk_queue_ordered(request_queue_t *q, unsigned ordered, - prepare_flush_fn *prepare_flush_fn, - unsigned gfp_mask); - -int blk_queue_ordered_locked(request_queue_t *q, unsigned ordered, - prepare_flush_fn *prepare_flush_fn, - unsigned gfp_mask); - -The only difference between the two functions is whether or not the -caller is holding q->queue_lock on entry. The latter expects the -caller is holding the lock. + prepare_flush_fn *prepare_flush_fn); @q : the queue in question @ordered : the ordered mode the driver/device supports @prepare_flush_fn : this function should prepare @rq such that it flushes cache to physical medium when executed -@gfp_mask : gfp_mask used when allocating data structures - for ordered processing For example, SCSI disk driver's prepare_flush_fn looks like the following. @@ -106,9 +95,10 @@ following. static void sd_prepare_flush(request_queue_t *q, struct request *rq) { memset(rq->cmd, 0, sizeof(rq->cmd)); - rq->flags |= REQ_BLOCK_PC; + rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->timeout = SD_TIMEOUT; rq->cmd[0] = SYNCHRONIZE_CACHE; + rq->cmd_len = 10; } The following seven ordered modes are supported. The following table From c59697e06058fc2361da8cefcfa3de85ac107582 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:33 -0700 Subject: [PATCH 446/551] sky2: restore workarounds for lost interrupts This patch restores a couple of workarounds from 2.6.16: * restart transmit moderation timer in case it expires during IRQ routine * default to having 10 HZ watchdog timer. At this point it more important not to hang than to worry about the power cost. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b51d73c8f817..77abf892e4f3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -96,7 +96,7 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 0; +static int idle_timeout = 100; module_param(idle_timeout, int, 0); MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); @@ -2490,6 +2490,13 @@ static int sky2_poll(struct net_device *dev0, int *budget) work_done = sky2_status_intr(hw, work_limit); if (work_done < work_limit) { + /* Bug/Errata workaround? + * Need to kick the TX irq moderation timer. + */ + if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); + } netif_rx_complete(dev0); /* end of interrupt, re-enables also acts as I/O synchronization */ From 55d7b4e6ed6ad3ec5e5e30b3b4515a0a6a53e344 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:34 -0700 Subject: [PATCH 447/551] sky2: carrier management Make sky2 handle carrier similar to other drivers, eliminate some possible races in carrier state transistions. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 77abf892e4f3..f6fe2861cc4c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1265,6 +1265,8 @@ static int sky2_up(struct net_device *dev) if (netif_msg_ifup(sky2)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); + netif_carrier_off(dev); + /* must be power of 2 */ sky2->tx_le = pci_alloc_consistent(hw->pdev, TX_RING_SIZE * @@ -1616,7 +1618,6 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); - netif_carrier_off(dev); /* Disable port IRQ */ imask = sky2_read32(hw, B0_IMSK); @@ -1668,6 +1669,8 @@ static int sky2_down(struct net_device *dev) sky2_phy_power(hw, port, 0); + netif_carrier_off(dev); + /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); @@ -1732,7 +1735,6 @@ static void sky2_link_up(struct sky2_port *sky2) gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); netif_carrier_on(sky2->netdev); - netif_wake_queue(sky2->netdev); /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), @@ -1784,7 +1786,6 @@ static void sky2_link_down(struct sky2_port *sky2) gma_write16(hw, port, GM_GP_CTRL, reg); netif_carrier_off(sky2->netdev); - netif_stop_queue(sky2->netdev); /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); @@ -3543,10 +3544,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - /* device is off until link detection */ - netif_carrier_off(dev); - netif_stop_queue(dev); - return dev; } From 3cf267539f1f133eb6ba63d074da18cb58cdf89a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:35 -0700 Subject: [PATCH 448/551] sky2: debug interface Add an optional debug interface for displaying state of transmit/receive rings. Creates a file debugfs/sky2/ethX for each device that is up. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 10 +++ drivers/net/sky2.c | 196 +++++++++++++++++++++++++++++++++++++++++++- drivers/net/sky2.h | 4 + 3 files changed, 208 insertions(+), 2 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5cc3d517e39b..58c6aa28baff 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2133,6 +2133,16 @@ config SKY2 To compile this driver as a module, choose M here: the module will be called sky2. This is recommended. +config SKY2_DEBUG + bool "Debugging interface" + depends on SKY2 && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file debugfs/sky2/ethX displays the state of the internal + transmit and receive rings. + + If unsure, say N. + config SK98LIN tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" depends on PCI diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f6fe2861cc4c..90b1b9708178 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -1574,13 +1575,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) if (unlikely(netif_msg_tx_done(sky2))) printk(KERN_DEBUG "%s: tx done %u\n", dev->name, idx); + sky2->net_stats.tx_packets++; sky2->net_stats.tx_bytes += re->skb->len; dev_kfree_skb_any(re->skb); + sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); } - - le->opcode = 0; /* paranoia */ } sky2->tx_cons = idx; @@ -3470,6 +3471,195 @@ static const struct ethtool_ops sky2_ethtool_ops = { .get_perm_addr = ethtool_op_get_perm_addr, }; +#ifdef CONFIG_SKY2_DEBUG + +static struct dentry *sky2_debug; + +static int sky2_debug_show(struct seq_file *seq, void *v) +{ + struct net_device *dev = seq->private; + const struct sky2_port *sky2 = netdev_priv(dev); + const struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + unsigned idx, last; + int sop; + + if (!netif_running(dev)) + return -ENETDOWN; + + seq_printf(seq, "IRQ src=%x mask=%x control=%x\n", + sky2_read32(hw, B0_ISRC), + sky2_read32(hw, B0_IMSK), + sky2_read32(hw, B0_Y2_SP_ICR)); + + netif_poll_disable(hw->dev[0]); + last = sky2_read16(hw, STAT_PUT_IDX); + + if (hw->st_idx == last) + seq_puts(seq, "Status ring (empty)\n"); + else { + seq_puts(seq, "Status ring\n"); + for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE; + idx = RING_NEXT(idx, STATUS_RING_SIZE)) { + const struct sky2_status_le *le = hw->st_le + idx; + seq_printf(seq, "[%d] %#x %d %#x\n", + idx, le->opcode, le->length, le->status); + } + seq_puts(seq, "\n"); + } + + seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n", + sky2->tx_cons, sky2->tx_prod, + sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX), + sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE))); + + /* Dump contents of tx ring */ + sop = 1; + for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE; + idx = RING_NEXT(idx, TX_RING_SIZE)) { + const struct sky2_tx_le *le = sky2->tx_le + idx; + u32 a = le32_to_cpu(le->addr); + + if (sop) + seq_printf(seq, "%u:", idx); + sop = 0; + + switch(le->opcode & ~HW_OWNER) { + case OP_ADDR64: + seq_printf(seq, " %#x:", a); + break; + case OP_LRGLEN: + seq_printf(seq, " mtu=%d", a); + break; + case OP_VLAN: + seq_printf(seq, " vlan=%d", be16_to_cpu(le->length)); + break; + case OP_TCPLISW: + seq_printf(seq, " csum=%#x", a); + break; + case OP_LARGESEND: + seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length)); + break; + case OP_PACKET: + seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length)); + break; + case OP_BUFFER: + seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length)); + break; + default: + seq_printf(seq, " op=%#x,%#x(%d)", le->opcode, + a, le16_to_cpu(le->length)); + } + + if (le->ctrl & EOP) { + seq_putc(seq, '\n'); + sop = 1; + } + } + + seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n", + sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)), + last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), + sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); + + netif_poll_enable(hw->dev[0]); + return 0; +} + +static int sky2_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, sky2_debug_show, inode->i_private); +} + +static const struct file_operations sky2_debug_fops = { + .owner = THIS_MODULE, + .open = sky2_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Use network device events to create/remove/rename + * debugfs file entries + */ +static int sky2_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + + if (dev->open == sky2_up) { + struct sky2_port *sky2 = netdev_priv(dev); + + switch(event) { + case NETDEV_CHANGENAME: + if (!netif_running(dev)) + break; + /* fallthrough */ + case NETDEV_DOWN: + case NETDEV_GOING_DOWN: + if (sky2->debugfs) { + printk(KERN_DEBUG PFX "%s: remove debugfs\n", + dev->name); + debugfs_remove(sky2->debugfs); + sky2->debugfs = NULL; + } + + if (event != NETDEV_CHANGENAME) + break; + /* fallthrough for changename */ + case NETDEV_UP: + if (sky2_debug) { + struct dentry *d; + d = debugfs_create_file(dev->name, S_IRUGO, + sky2_debug, dev, + &sky2_debug_fops); + if (d == NULL || IS_ERR(d)) + printk(KERN_INFO PFX + "%s: debugfs create failed\n", + dev->name); + else + sky2->debugfs = d; + } + break; + } + } + + return NOTIFY_DONE; +} + +static struct notifier_block sky2_notifier = { + .notifier_call = sky2_device_event, +}; + + +static __init void sky2_debug_init(void) +{ + struct dentry *ent; + + ent = debugfs_create_dir("sky2", NULL); + if (!ent || IS_ERR(ent)) + return; + + sky2_debug = ent; + register_netdevice_notifier(&sky2_notifier); +} + +static __exit void sky2_debug_cleanup(void) +{ + if (sky2_debug) { + unregister_netdevice_notifier(&sky2_notifier); + debugfs_remove(sky2_debug); + sky2_debug = NULL; + } +} + +#else +#define sky2_debug_init() +#define sky2_debug_cleanup() +#endif + + /* Initialize network device */ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, @@ -3960,12 +4150,14 @@ static struct pci_driver sky2_driver = { static int __init sky2_init_module(void) { + sky2_debug_init(); return pci_register_driver(&sky2_driver); } static void __exit sky2_cleanup_module(void) { pci_unregister_driver(&sky2_driver); + sky2_debug_cleanup(); } module_init(sky2_init_module); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 8df4643493d1..dce4d276d443 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1998,6 +1998,7 @@ struct sky2_port { struct sky2_tx_le *tx_le; u16 tx_cons; /* next le to check */ u16 tx_prod; /* next le to use */ + u16 tx_next; /* debug only */ u32 tx_addr64; u16 tx_pending; u16 tx_last_mss; @@ -2028,6 +2029,9 @@ struct sky2_port { enum flow_control flow_mode; enum flow_control flow_status; +#ifdef CONFIG_SKY2_DEBUG + struct dentry *debugfs; +#endif struct net_device_stats net_stats; }; From 5c11ce700f77fada15b6264417d72462da4bbb1c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:36 -0700 Subject: [PATCH 449/551] sky2: check for more work before leaving NAPI This patch avoids generating another IRQ if more packets arrive while in the NAPI poll routine. Before marking device as finished, it rechecks that the status ring is empty. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 90b1b9708178..c8e51cf5af71 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2477,8 +2477,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status) static int sky2_poll(struct net_device *dev0, int *budget) { struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; - int work_limit = min(dev0->quota, *budget); - int work_done = 0; + int work_done; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); if (unlikely(status & Y2_IS_ERROR)) @@ -2490,25 +2489,25 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (status & Y2_IS_IRQ_PHY2) sky2_phy_intr(hw, 1); - work_done = sky2_status_intr(hw, work_limit); - if (work_done < work_limit) { - /* Bug/Errata workaround? - * Need to kick the TX irq moderation timer. - */ - if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); - } - netif_rx_complete(dev0); + work_done = sky2_status_intr(hw, min(dev0->quota, *budget)); + *budget -= work_done; + dev0->quota -= work_done; - /* end of interrupt, re-enables also acts as I/O synchronization */ - sky2_read32(hw, B0_Y2_SP_LISR); - return 0; - } else { - *budget -= work_done; - dev0->quota -= work_done; + /* More work? */ + if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)) return 1; + + /* Bug/Errata workaround? + * Need to kick the TX irq moderation timer. + */ + if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); } + netif_rx_complete(dev0); + + sky2_read32(hw, B0_Y2_SP_LISR); + return 0; } static irqreturn_t sky2_intr(int irq, void *dev_id) From 55c9dd35d3299dbd6e437c1a0bd86fffcb17080b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:37 -0700 Subject: [PATCH 450/551] sky2: receive fill Simplify receive buffer refill logic. Rather than trying to update incrementally; do receive ring refill at end of receive processing. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c8e51cf5af71..b0950e1c4b68 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -65,7 +65,6 @@ #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) #define RX_DEF_PENDING RX_MAX_PENDING #define RX_SKB_ALIGN 8 -#define RX_BUF_WRITE 16 #define TX_RING_SIZE 512 #define TX_DEF_PENDING (TX_RING_SIZE - 1) @@ -1138,6 +1137,11 @@ nomem: return NULL; } +static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq) +{ + sky2_put_idx(sky2->hw, rxq, sky2->rx_put); +} + /* * Allocate and setup receiver buffer pool. * Normal case this ends up creating one list element for skb @@ -1229,7 +1233,7 @@ static int sky2_rx_start(struct sky2_port *sky2) } /* Tell chip about available buffers */ - sky2_put_idx(hw, rxq, sky2->rx_put); + sky2_rx_update(sky2, rxq); return 0; nomem: sky2_rx_clean(sky2); @@ -2147,14 +2151,14 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) /* Process status response ring */ static int sky2_status_intr(struct sky2_hw *hw, int to_do) { - struct sky2_port *sky2; int work_done = 0; - unsigned buf_write[2] = { 0, 0 }; + unsigned rx[2] = { 0, 0 }; u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); rmb(); while (hw->st_idx != hwidx) { + struct sky2_port *sky2; struct sky2_status_le *le = hw->st_le + hw->st_idx; unsigned port = le->css & CSS_LINK_BIT; struct net_device *dev; @@ -2171,10 +2175,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) switch (le->opcode & ~HW_OWNER) { case OP_RXSTAT: + ++rx[port]; skb = sky2_receive(dev, length, status); if (unlikely(!skb)) { sky2->net_stats.rx_dropped++; - goto force_update; + break; } /* This chip reports checksum status differently */ @@ -2201,13 +2206,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) #endif netif_receive_skb(skb); - /* Update receiver after 16 frames */ - if (++buf_write[port] == RX_BUF_WRITE) { -force_update: - sky2_put_idx(hw, rxqaddr[port], sky2->rx_put); - buf_write[port] = 0; - } - /* Stop after net poll weight */ if (++work_done >= to_do) goto exit_loop; @@ -2263,24 +2261,18 @@ force_update: if (net_ratelimit()) printk(KERN_WARNING PFX "unknown status opcode 0x%x\n", le->opcode); - goto exit_loop; } } /* Fully processed status ring so clear irq */ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); - mmiowb(); exit_loop: - if (buf_write[0]) { - sky2 = netdev_priv(hw->dev[0]); - sky2_put_idx(hw, Q_R1, sky2->rx_put); - } + if (rx[0]) + sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1); - if (buf_write[1]) { - sky2 = netdev_priv(hw->dev[1]); - sky2_put_idx(hw, Q_R2, sky2->rx_put); - } + if (rx[1]) + sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2); return work_done; } From 8a3e3bfdf47b82bfbd78aabf7f72df4dff12abcc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:38 -0700 Subject: [PATCH 451/551] sky2: unmark as EXPERIMENTAL Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 58c6aa28baff..4f23ad7b13c1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2118,7 +2118,7 @@ config SKGE will be called skge. This is recommended. config SKY2 - tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" + tristate "SysKonnect Yukon2 support" depends on PCI select CRC32 ---help--- From f4331a6d24f2e5524678caf4621d35f33fb934da Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:39 -0700 Subject: [PATCH 452/551] sky2: add support for read/write of EEPROM Add get/set eeprom support for sky2. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 140 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 25 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b0950e1c4b68..99a999383e9b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -77,6 +77,9 @@ #define NAPI_WEIGHT 64 #define PHY_RETRIES 1000 +#define SKY2_EEPROM_MAGIC 0x9955aabb + + #define RING_NEXT(x,s) (((x)+1) & ((s)-1)) static const u32 default_msg = @@ -3429,34 +3432,121 @@ static int sky2_set_tso(struct net_device *dev, u32 data) return ethtool_op_set_tso(dev, data); } +static int sky2_get_eeprom_len(struct net_device *dev) +{ + struct sky2_port *sky2 = netdev_priv(dev); + u16 reg2; + + reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2); + return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8); +} + +static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset) +{ + sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset); + + while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F)) + cpu_relax(); + return sky2_pci_read32(hw, cap + PCI_VPD_DATA); +} + +static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val) +{ + sky2_pci_write32(hw, cap + PCI_VPD_DATA, val); + sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F); + do { + cpu_relax(); + } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F); +} + +static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct sky2_port *sky2 = netdev_priv(dev); + int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD); + int length = eeprom->len; + u16 offset = eeprom->offset; + + if (!cap) + return -EINVAL; + + eeprom->magic = SKY2_EEPROM_MAGIC; + + while (length > 0) { + u32 val = sky2_vpd_read(sky2->hw, cap, offset); + int n = min_t(int, length, sizeof(val)); + + memcpy(data, &val, n); + length -= n; + data += n; + offset += n; + } + return 0; +} + +static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct sky2_port *sky2 = netdev_priv(dev); + int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD); + int length = eeprom->len; + u16 offset = eeprom->offset; + + if (!cap) + return -EINVAL; + + if (eeprom->magic != SKY2_EEPROM_MAGIC) + return -EINVAL; + + while (length > 0) { + u32 val; + int n = min_t(int, length, sizeof(val)); + + if (n < sizeof(val)) + val = sky2_vpd_read(sky2->hw, cap, offset); + memcpy(&val, data, n); + + sky2_vpd_write(sky2->hw, cap, offset, val); + + length -= n; + data += n; + offset += n; + } + return 0; +} + + static const struct ethtool_ops sky2_ethtool_ops = { - .get_settings = sky2_get_settings, - .set_settings = sky2_set_settings, - .get_drvinfo = sky2_get_drvinfo, - .get_wol = sky2_get_wol, - .set_wol = sky2_set_wol, - .get_msglevel = sky2_get_msglevel, - .set_msglevel = sky2_set_msglevel, - .nway_reset = sky2_nway_reset, - .get_regs_len = sky2_get_regs_len, - .get_regs = sky2_get_regs, - .get_link = ethtool_op_get_link, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = sky2_set_tx_csum, - .get_tso = ethtool_op_get_tso, - .set_tso = sky2_set_tso, - .get_rx_csum = sky2_get_rx_csum, - .set_rx_csum = sky2_set_rx_csum, - .get_strings = sky2_get_strings, - .get_coalesce = sky2_get_coalesce, - .set_coalesce = sky2_set_coalesce, - .get_ringparam = sky2_get_ringparam, - .set_ringparam = sky2_set_ringparam, + .get_settings = sky2_get_settings, + .set_settings = sky2_set_settings, + .get_drvinfo = sky2_get_drvinfo, + .get_wol = sky2_get_wol, + .set_wol = sky2_set_wol, + .get_msglevel = sky2_get_msglevel, + .set_msglevel = sky2_set_msglevel, + .nway_reset = sky2_nway_reset, + .get_regs_len = sky2_get_regs_len, + .get_regs = sky2_get_regs, + .get_link = ethtool_op_get_link, + .get_eeprom_len = sky2_get_eeprom_len, + .get_eeprom = sky2_get_eeprom, + .set_eeprom = sky2_set_eeprom, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = sky2_set_tx_csum, + .get_tso = ethtool_op_get_tso, + .set_tso = sky2_set_tso, + .get_rx_csum = sky2_get_rx_csum, + .set_rx_csum = sky2_set_rx_csum, + .get_strings = sky2_get_strings, + .get_coalesce = sky2_get_coalesce, + .set_coalesce = sky2_set_coalesce, + .get_ringparam = sky2_get_ringparam, + .set_ringparam = sky2_set_ringparam, .get_pauseparam = sky2_get_pauseparam, .set_pauseparam = sky2_set_pauseparam, - .phys_id = sky2_phys_id, + .phys_id = sky2_phys_id, .get_stats_count = sky2_get_stats_count, .get_ethtool_stats = sky2_get_ethtool_stats, .get_perm_addr = ethtool_op_get_perm_addr, From 71749531f2d1954137a1a77422ef4ff29eb102dd Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:40 -0700 Subject: [PATCH 453/551] sky2: check drop truncated packets If packet larger than MTU is received, the driver uses hardware to truncate the packet. Use the status registers to catch/drop them. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 99a999383e9b..4e0b839de7e4 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2109,6 +2109,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev, if (!(status & GMR_FS_RX_OK)) goto resubmit; + if (status >> 16 != length) + goto len_mismatch; + if (length < copybreak) skb = receive_copy(sky2, re, length); else @@ -2118,6 +2121,11 @@ resubmit: return skb; +len_mismatch: + /* Truncation of overlength packets + causes PHY length to not match MAC length */ + ++sky2->net_stats.rx_length_errors; + error: ++sky2->net_stats.rx_errors; if (status & GMR_FS_RX_FF_OV) { From f957da2aa0b7ef9659a45b0895ec4a08602b1c15 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:41 -0700 Subject: [PATCH 454/551] sky2: use roundup() macro Use roundup() macro to size receive buffer. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 4e0b839de7e4..8cc3eea727a8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1180,8 +1180,7 @@ static int sky2_rx_start(struct sky2_port *sky2) rx_set_checksum(sky2); /* Space needed for frame data + headers rounded up */ - size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8) - + 8; + size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); /* Stopping point for hardware truncation */ thresh = (size - 8) / sizeof(u32); From 36eb0c71f3ab42b116a5a7bda733230014741632 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:42 -0700 Subject: [PATCH 455/551] sky2: use upper_32_bits() macro Use upper_32_bits() inline Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 8cc3eea727a8..151d8359a1ea 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -893,24 +893,18 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) return le; } -/* Return high part of DMA address (could be 32 or 64 bit) */ -static inline u32 high32(dma_addr_t a) -{ - return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0; -} - /* Build description to hardware for one receive segment */ static void sky2_rx_add(struct sky2_port *sky2, u8 op, dma_addr_t map, unsigned len) { struct sky2_rx_le *le; - u32 hi = high32(map); + u32 hi = upper_32_bits(map); if (sky2->rx_addr64 != hi) { le = sky2_next_rx(sky2); le->addr = cpu_to_le32(hi); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->rx_addr64 = high32(map + len); + sky2->rx_addr64 = upper_32_bits(map + len); } le = sky2_next_rx(sky2); @@ -1424,14 +1418,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) len = skb_headlen(skb); mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); - addr64 = high32(mapping); + addr64 = upper_32_bits(mapping); /* Send high bits if changed or crosses boundary */ - if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) { + if (addr64 != sky2->tx_addr64 || + upper_32_bits(mapping + len) != sky2->tx_addr64) { le = get_tx_le(sky2); le->addr = cpu_to_le32(addr64); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = high32(mapping + len); + sky2->tx_addr64 = upper_32_bits(mapping + len); } /* Check for TCP Segmentation Offload */ @@ -1511,7 +1506,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - addr64 = high32(mapping); + addr64 = upper_32_bits(mapping); if (addr64 != sky2->tx_addr64) { le = get_tx_le(sky2); le->addr = cpu_to_le32(addr64); From e923d7b124d2b2218faac22714dc6e4639fab2e7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:43 -0700 Subject: [PATCH 456/551] sky2: remove some leftover debug messages Eliminate extra debug messages Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 151d8359a1ea..88f3ac2b4eab 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2058,8 +2058,6 @@ static struct sk_buff *receive_new(struct sky2_port *sky2, struct sk_buff *skb, *nskb; unsigned hdr_space = sky2->rx_data_size; - pr_debug(PFX "receive new length=%d\n", length); - /* Don't be tricky about reusing pages (yet) */ nskb = sky2_rx_alloc(sky2); if (unlikely(!nskb)) @@ -2728,8 +2726,6 @@ static void sky2_restart(struct work_struct *work) struct net_device *dev; int i, err; - dev_dbg(&hw->pdev->dev, "restarting\n"); - del_timer_sync(&hw->idle_timer); rtnl_lock(); From 0640b8dc74e938543dd8fc8c460c5f913a1b1a74 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 9 Jul 2007 15:33:44 -0700 Subject: [PATCH 457/551] sky2: 1.16 version Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 88f3ac2b4eab..a2f32151559e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.15" +#define DRV_VERSION "1.16" #define PFX DRV_NAME " " /* From de0d3dc0e8ecd80f602fac03feb8fd53d0c17a8c Mon Sep 17 00:00:00 2001 From: Yoann Padioleau Date: Mon, 9 Jul 2007 11:50:20 -0700 Subject: [PATCH 458/551] atari_pamsnet.c: old declaration ritchie style fix Use consistent function declaration style. Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/atari_pamsnet.c | 62 +++++++++++++------------------------ 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c index 54714409a09b..f7356374a2e7 100644 --- a/drivers/net/atari_pamsnet.c +++ b/drivers/net/atari_pamsnet.c @@ -295,10 +295,7 @@ int if_up = 0; /* Setup the DMA counter */ static void -setup_dma (address, rw_flag, num_blocks) - void *address; - unsigned rw_flag; - int num_blocks; +setup_dma (void *address, unsigned rw_flag, int num_blocks) { WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI | A1); @@ -317,9 +314,7 @@ setup_dma (address, rw_flag, num_blocks) /* Send the first byte of an command block */ static int -send_first (target, byte) - int target; - unsigned char byte; +send_first (int target, unsigned char byte) { rw = READ; acsi_delay_end(COMMAND_DELAY); @@ -338,10 +333,7 @@ send_first (target, byte) /* Send the rest of an command block */ static int -send_1_5 (lun, command, dma) - int lun; - unsigned char *command; - int dma; +send_1_5 (int lun, unsigned char *command, int dma) { int i, j; @@ -371,8 +363,7 @@ get_status (void) /* Calculate the number of received bytes */ static int -calc_received (start_address) - void *start_address; +calc_received (void *start_address) { return (int)( (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW) @@ -384,8 +375,7 @@ calc_received (start_address) /* start() starts the PAM's DMA adaptor */ static void -start (target) - int target; +start (int target) { send_first(target, START); } @@ -393,8 +383,7 @@ start (target) /* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */ static int -stop (target) - int target; +stop (int target) { int ret = -1; unsigned char cmd_buffer[5]; @@ -415,8 +404,7 @@ bad: /* testpkt() returns the number of received packets waiting in the queue */ static int -testpkt(target) - int target; +testpkt(int target) { int ret = -1; @@ -431,9 +419,7 @@ bad: /* Please note: The buffer is for internal use only but must be defined! */ static int -inquiry (target, buffer) - int target; - unsigned char *buffer; +inquiry (int target, unsigned char *buffer) { int ret = -1; unsigned char *vbuffer = phys_to_virt((unsigned long)buffer); @@ -468,9 +454,7 @@ bad: */ static HADDR -*read_hw_addr(target, buffer) - int target; - unsigned char *buffer; +*read_hw_addr(int target, unsigned char *buffer) { HADDR *ret = 0; unsigned char cmd_buffer[5]; @@ -491,9 +475,7 @@ bad: } static irqreturn_t -pamsnet_intr(irq, data, fp) - int irq; - void *data; +pamsnet_intr(int irq, void *data) { return IRQ_HANDLED; } @@ -501,9 +483,7 @@ pamsnet_intr(irq, data, fp) /* receivepkt() loads a packet to a given buffer and returns its length */ static int -receivepkt (target, buffer) - int target; - unsigned char *buffer; +receivepkt (int target, unsigned char *buffer) { int ret = -1; unsigned char cmd_buffer[5]; @@ -526,10 +506,7 @@ bad: successfully */ static int -sendpkt (target, buffer, length) - int target; - unsigned char *buffer; - int length; +sendpkt (int target, unsigned char *buffer, int length) { int ret = -1; unsigned char cmd_buffer[5]; @@ -665,7 +642,8 @@ struct net_device * __init pamsnet_probe (int unit) there is non-reboot way to recover if something goes wrong. */ static int -pamsnet_open(struct net_device *dev) { +pamsnet_open(struct net_device *dev) +{ struct net_local *lp = netdev_priv(dev); if (pamsnet_debug > 0) @@ -694,7 +672,8 @@ pamsnet_open(struct net_device *dev) { } static int -pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { +pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) +{ struct net_local *lp = netdev_priv(dev); unsigned long flags; @@ -741,7 +720,8 @@ pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { /* We have a good packet(s), get it/them out of the buffers. */ static void -pamsnet_poll_rx(struct net_device *dev) { +pamsnet_poll_rx(struct net_device *dev) +{ struct net_local *lp = netdev_priv(dev); int boguscount; int pkt_len; @@ -816,7 +796,8 @@ pamsnet_poll_rx(struct net_device *dev) { * passes them to the higher layers and restarts the timer. */ static void -pamsnet_tick(unsigned long data) { +pamsnet_tick(unsigned long data) +{ struct net_device *dev = (struct net_device *)data; struct net_local *lp = netdev_priv(dev); @@ -832,7 +813,8 @@ pamsnet_tick(unsigned long data) { /* The inverse routine to pamsnet_open(). */ static int -pamsnet_close(struct net_device *dev) { +pamsnet_close(struct net_device *dev) +{ struct net_local *lp = netdev_priv(dev); if (pamsnet_debug > 0) From d9da466a3ce2ac005e05bb649a0f2cfb5c3d5d45 Mon Sep 17 00:00:00 2001 From: vignesh babu Date: Mon, 9 Jul 2007 11:50:22 -0700 Subject: [PATCH 459/551] use is_power_of_2() in cxgb3/cxgb3_main.c Replace (n & (n-1)) with is_power_of_2() Signed-off-by: vignesh babu Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/cxgb3/cxgb3_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 15defe4c4f05..6fd1e5241833 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "common.h" @@ -1818,8 +1819,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) return -EBUSY; if (copy_from_user(&m, useraddr, sizeof(m))) return -EFAULT; - if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) || - !m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1))) + if (!is_power_of_2(m.rx_pg_sz) || + !is_power_of_2(m.tx_pg_sz)) return -EINVAL; /* not power of 2 */ if (!(m.rx_pg_sz & 0x14000)) return -EINVAL; /* not 16KB or 64KB */ From 199126a23a091585670fba023529b73047bb2bad Mon Sep 17 00:00:00 2001 From: vignesh babu Date: Mon, 9 Jul 2007 11:50:22 -0700 Subject: [PATCH 460/551] Use is_power_of_2() in myri10ge/myri10ge.c Replace (n & (n-1)) with is_power_of_2() Signed-off-by: vignesh babu Cc: Brice Goglin Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index d0cc122fa3f0..e1732c164a40 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -1804,7 +1805,7 @@ static int myri10ge_open(struct net_device *dev) */ big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) { - while ((big_pow2 & (big_pow2 - 1)) != 0) + while (!is_power_of_2(big_pow2)) big_pow2++; mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; } else { From b8a1fcee26126b566d9e28ba80c643a7a10543eb Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 9 Jul 2007 11:50:23 -0700 Subject: [PATCH 461/551] 3cSOHO100-TX needs EXTRA_PREAMBLE The 3cSOHO100-TX needs a mdio_sync() before mdio_read() to read the MII transceiver registers properly. Adding EXTRA_PREAMBLE to drv_flags of the 3cSOHO100-TX will force this. This problem exists already for years (I checked back to 2.6.8). Setting duplex for the 3cSOHO100-TX was more or less a random process. Till 2.6.15 it was more likely that the diver ends up in half duplex mode, after the code change in 2.6.16 it was more likely to end up in full duplex mode. I wonder why nobody noticed this earier. Hopefully addresses Bug 7454 3c59x (3cSOHO100-TX Hurricane) slow network bug http://bugzilla.kernel.org/show_bug.cgi?id=7454 and Bug 3654 3cSOHO100-TX: No MII transceiver present http://bugzilla.kernel.org/show_bug.cgi?id=3654 Cc: Jonas Sandberg Cc: Jon Sanchez Signed-off-by: Steffen Klassert Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/3c59x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index f26ca331615e..6deb20fc7a08 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -324,7 +324,7 @@ static struct vortex_chip_info { {"3c980C Python-T", PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3cSOHO100-TX Hurricane", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c555 Laptop Hurricane", PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, {"3c556 Laptop Tornado", From 7a627558214664f0e071b2652fc37e4d7d3dce32 Mon Sep 17 00:00:00 2001 From: Ishizaki Kou Date: Mon, 9 Jul 2007 18:17:42 -0500 Subject: [PATCH 462/551] spidernet: improve interrupt handling We intend this patch to improve spidernet interrupt handling to be more strict. We had following problem and this patch solves it. -when CONFIG_DEBUG_SHIRQ=y, request_irq() calls handler(). -when spider_net_open() is called, it calls request_irq() which calls spider_net_interrupt(). -if some specific interrupt bit is set at this timing, it calls netif_rx_schedule() and spider_net_poll() is scheduled. -spider_net_open() calls netif_poll_enable() which clears the bit __LINK_STATE_RX_SCHED. -when spider_net_poll() is called, it calls netif_rx_complete() which causes BUG_ON() because __LINK_STATE_RX_SCHED is not set. Signed-off-by: Kou Ishizaki Signed-off-by: Linas Vepstas Signed-off-by: Jeff Garzik --- drivers/net/spider_net.c | 59 ++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index f5abb5279d4d..590b12c7246c 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1441,11 +1441,17 @@ static void spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) { u32 error_reg1, error_reg2; + u32 mask_reg1, mask_reg2; u32 i; int show_error = 1; error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); + mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK); + mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK); + + error_reg1 &= mask_reg1; + error_reg2 &= mask_reg2; /* check GHIINT0STS ************************************/ if (status_reg) @@ -1673,9 +1679,11 @@ spider_net_interrupt(int irq, void *ptr) { struct net_device *netdev = ptr; struct spider_net_card *card = netdev_priv(netdev); - u32 status_reg; + u32 status_reg, mask_reg; status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); + mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); + status_reg &= mask_reg; if (!status_reg) return IRQ_NONE; @@ -1716,6 +1724,38 @@ spider_net_poll_controller(struct net_device *netdev) } #endif /* CONFIG_NET_POLL_CONTROLLER */ +/** + * spider_net_enable_interrupts - enable interrupts + * @card: card structure + * + * spider_net_enable_interrupt enables several interrupts + */ +static void +spider_net_enable_interrupts(struct spider_net_card *card) +{ + spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, + SPIDER_NET_INT0_MASK_VALUE); + spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, + SPIDER_NET_INT1_MASK_VALUE); + spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, + SPIDER_NET_INT2_MASK_VALUE); +} + +/** + * spider_net_disable_interrupts - disable interrupts + * @card: card structure + * + * spider_net_disable_interrupts disables all the interrupts + */ +static void +spider_net_disable_interrupts(struct spider_net_card *card) +{ + spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0); +} + /** * spider_net_init_card - initializes the card * @card: card structure @@ -1736,6 +1776,7 @@ spider_net_init_card(struct spider_net_card *card) spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4); + spider_net_disable_interrupts(card); } /** @@ -1823,14 +1864,6 @@ spider_net_enable_card(struct spider_net_card *card) spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, SPIDER_NET_OPMODE_VALUE); - /* set interrupt mask registers */ - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, - SPIDER_NET_INT0_MASK_VALUE); - spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, - SPIDER_NET_INT1_MASK_VALUE); - spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, - SPIDER_NET_INT2_MASK_VALUE); - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, SPIDER_NET_GDTBSTA); } @@ -2007,6 +2040,8 @@ spider_net_open(struct net_device *netdev) netif_carrier_on(netdev); netif_poll_enable(netdev); + spider_net_enable_interrupts(card); + return 0; register_int_failed: @@ -2179,11 +2214,7 @@ spider_net_stop(struct net_device *netdev) del_timer_sync(&card->tx_timer); del_timer_sync(&card->aneg_timer); - /* disable/mask all interrupts */ - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0); + spider_net_disable_interrupts(card); free_irq(netdev->irq, netdev); From 654e02200578799264941e5a9b533563a87f8579 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 10 Jul 2007 11:40:28 +0200 Subject: [PATCH 463/551] PCMCIA: add Socket Ethernet card into pcnet_cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One card submitted by Ã…ngström user. Signed-off-by: Marcin Juszkiewicz Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/pcnet_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index f2613c29b008..63de89e93b70 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1581,6 +1581,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103), PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121), PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941), + PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e), PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b), PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b), PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e), From 8453d43f0ee08ac6c20f390797772a08f81f999a Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Tue, 10 Jul 2007 11:58:02 +0200 Subject: [PATCH 464/551] Fix typo in drivers/net/s2io.c Introduced in d796fdb708fc5b10112934cba43e832c36ce4923. Signed-off-by: Rolf Eike Beer Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2d826fff7e2e..fa29a403a247 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -8036,7 +8036,7 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, /** * s2io_io_error_detected - called when PCI error is detected * @pdev: Pointer to PCI device - * @state: The current pci conneection state + * @state: The current pci connection state * * This function is called after a PCI bus error affecting * this device has been detected. From 4e50a8e3c564add2f621dadb752a44872e93c754 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 10 Jul 2007 14:44:35 +0200 Subject: [PATCH 465/551] sis900_mii_probe() must be __devinit This patch fixes the following section mismatch: <-- snip --> ... MODPOST vmlinux WARNING: drivers/built-in.o(.text+0x298170): Section mismatch: reference to .init.text:sis900_mii_probe (between 'sis900_probe' and 'sis900_default_phy') ... <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/sis900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 2cb2e156c758..7c6e4808399a 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -573,7 +573,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, * return error if it failed to found. */ -static int __init sis900_mii_probe(struct net_device * net_dev) +static int __devinit sis900_mii_probe(struct net_device * net_dev) { struct sis900_private * sis_priv = net_dev->priv; const char *dev_name = pci_name(sis_priv->pci_dev); From 9b5587cdd9f2a8dd4a010a93a6380051d43a3c16 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 10 Jul 2007 14:44:37 +0200 Subject: [PATCH 466/551] tokenring/3c359.c:xl_init() must be __devinit This patch fixes the following section mismatch: <-- snip --> ... MODPOST vmlinux WARNING: drivers/built-in.o(.text+0x361ef1): Section mismatch: reference to .init.text:xl_init (between 'xl_probe' and 'xl_hw_reset') ... <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/tokenring/3c359.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index e22a3f5333ef..9f1b6ab9c228 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -363,7 +363,7 @@ static int __devinit xl_probe(struct pci_dev *pdev, } -static int __init xl_init(struct net_device *dev) +static int __devinit xl_init(struct net_device *dev) { struct xl_private *xl_priv = (struct xl_private *)dev->priv ; From 4f092432bd443416b649519c3d5405aa55ad2d15 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 10 Jul 2007 14:44:47 +0200 Subject: [PATCH 467/551] rrunner.c:rr_init() must be __devinit This patch fixes the following section mismatch: <-- snip --> ... MODPOST vmlinux WARNING: drivers/built-in.o(.text+0x26e3f2): Section mismatch: reference to .init.text:rr_init (between 'rr_init_one' and 'rr_remove_one') ... <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/rrunner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 25c73d47daad..5c2e41fac6d2 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -516,7 +516,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv, } -static int __init rr_init(struct net_device *dev) +static int __devinit rr_init(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs __iomem *regs; From c6f5047b633f0605098fe47417c4e1ed87a7637a Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 10 Jul 2007 07:51:11 -0500 Subject: [PATCH 468/551] QE Ethernet driver writes to wrong register to mask interrupts The QE Ethernet driver was writing to the wrong register to mask interrupts. In ucc_geth_stop(), it was clearing UCCE instead of UCCM. Signed-off-by: Timur Tabi Signed-off-by: Jeff Garzik --- drivers/net/ucc_geth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 18b731bb4da1..e4736a3b1b7a 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2276,7 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) phy_stop(phydev); /* Mask all interrupts */ - out_be32(ugeth->uccf->p_ucce, 0x00000000); + out_be32(ugeth->uccf->p_uccm, 0x00000000); /* Clear all interrupts */ out_be32(ugeth->uccf->p_ucce, 0xffffffff); From 44e4925e4601961b9bd1982008a55fce865d318c Mon Sep 17 00:00:00 2001 From: David Graham Date: Tue, 10 Jul 2007 08:45:11 -0700 Subject: [PATCH 469/551] e100: Fix Tyan motherboard e100 not receiving IPMI commands The 82550 & 51 parts have an extended configuration block that includes a bit "GMRC", required to enable the expected TCO behavior, in config byte offset 22d. The config block sent by the failing driver does include the extension area, but this bit is not initialised, and the downlaod only specifies 0x16 bytes to be sent to the NIC (thaht's bytes 00..21d). By initializing the GMRC bit, and extending the download size for D102+ MACs, the problem is resolved. Signed-off-by: David Graham Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e100.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 763810c7f33a..74ea6373c7cd 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -159,7 +159,7 @@ #define DRV_NAME "e100" #define DRV_EXT "-NAPI" -#define DRV_VERSION "3.5.17-k4"DRV_EXT +#define DRV_VERSION "3.5.23-k4"DRV_EXT #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" #define PFX DRV_NAME ": " @@ -1024,10 +1024,16 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) config->mwi_enable = 0x1; /* 1=enable, 0=disable */ config->standard_tcb = 0x0; /* 1=standard, 0=extended */ config->rx_long_ok = 0x1; /* 1=VLANs ok, 0=standard */ - if(nic->mac >= mac_82559_D101M) + if (nic->mac >= mac_82559_D101M) { config->tno_intr = 0x1; /* TCO stats enable */ - else + /* Enable TCO in extended config */ + if (nic->mac >= mac_82551_10) { + config->byte_count = 0x20; /* extended bytes */ + config->rx_d102_mode = 0x1; /* GMRC for TCO */ + } + } else { config->standard_stat_counter = 0x0; + } } DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", From f49343a54864b98333b98706accba66aa75a0c16 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 10 Jul 2007 17:05:16 +0100 Subject: [PATCH 470/551] IOC3: Switch to pci refcounting safe APIs Convert the IOC3 driver to use ref counting pci interfaces so that we can obsolete the (usually unsafe) pci_find_{slot/device} interfaces and avoid future authors writing hotplug-unsafe device drivers. Signed-off-by: Alan Cox Build fixes: Signed-off-by: Ralf Baechle Signed-off-by: Jeff Garzik --- drivers/net/ioc3-eth.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index f749e07c6425..3ca1e8ece548 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -352,13 +352,12 @@ static u64 nic_find(struct ioc3 *ioc3, int *last) static int nic_init(struct ioc3 *ioc3) { - const char *type; + const char *unknown = "unknown"; + const char *type = unknown; u8 crc; u8 serial[6]; int save = 0, i; - type = "unknown"; - while (1) { u64 reg; reg = nic_find(ioc3, &save); @@ -392,7 +391,7 @@ static int nic_init(struct ioc3 *ioc3) } printk("Found %s NIC", type); - if (type != "unknown") { + if (type != unknown) { printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x," " CRC %02x", serial[0], serial[1], serial[2], serial[3], serial[4], serial[5], crc); @@ -1103,20 +1102,28 @@ static int ioc3_close(struct net_device *dev) * MiniDINs; all other subdevices are left swinging in the wind, leave * them disabled. */ -static inline int ioc3_is_menet(struct pci_dev *pdev) -{ - struct pci_dev *dev; - return pdev->bus->parent == NULL - && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0))) - && dev->vendor == PCI_VENDOR_ID_SGI - && dev->device == PCI_DEVICE_ID_SGI_IOC3 - && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0))) - && dev->vendor == PCI_VENDOR_ID_SGI - && dev->device == PCI_DEVICE_ID_SGI_IOC3 - && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0))) - && dev->vendor == PCI_VENDOR_ID_SGI - && dev->device == PCI_DEVICE_ID_SGI_IOC3; +static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot) +{ + struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0)); + int ret = 0; + + if (dev) { + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3) + ret = 1; + pci_dev_put(dev); + } + + return ret; +} + +static int ioc3_is_menet(struct pci_dev *pdev) +{ + return pdev->bus->parent == NULL && + ioc3_adjacent_is_ioc3(pdev, 0) && + ioc3_adjacent_is_ioc3(pdev, 1) && + ioc3_adjacent_is_ioc3(pdev, 2); } #ifdef CONFIG_SERIAL_8250 From e934c82657529a85ca48a2fc3749c514df985e79 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 21 May 2007 23:00:38 +0900 Subject: [PATCH 471/551] [MIPS] remove unused definitions for Cobalt Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- include/asm-mips/mach-cobalt/cobalt.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h index 684a501c04cf..9c9d2b998ca4 100644 --- a/include/asm-mips/mach-cobalt/cobalt.h +++ b/include/asm-mips/mach-cobalt/cobalt.h @@ -30,7 +30,6 @@ #define COBALT_CPU_IRQ MIPS_CPU_IRQ_BASE #define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2) -#define COBALT_SCC_IRQ (COBALT_CPU_IRQ + 3) /* pre-production has 85C30 */ #define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3) #define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3) #define COBALT_QUBE1_ETH0_IRQ (COBALT_CPU_IRQ + 4) @@ -71,10 +70,6 @@ extern int cobalt_board_id; -#define PCI_CFG_SET(devfn,where) \ - GT_WRITE(GT_PCI0_CFGADDR_OFS, (0x80000000 | (PCI_SLOT (devfn) << 11) | \ - (PCI_FUNC (devfn) << 8) | (where))) - #define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000)) # define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */ # define COBALT_LED_BAR_RIGHT (1 << 1) /* Qube */ From d7eb079fc8e68899fd099ad0b5b8095193a8c025 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 28 May 2007 22:56:35 +0900 Subject: [PATCH 472/551] [MIPS] Remove unused config entries Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 73455389257a..c20cd9027585 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -841,15 +841,10 @@ config MIPS_TX3927 config MIPS_RM9122 bool select SERIAL_RM9000 - select GPI_RM9000 - select WDT_RM9000 config PCI_MARVELL bool -config SERIAL_RM9000 - bool - config PNX8550 bool select SOC_PNX8550 @@ -875,12 +870,6 @@ config EMMA2RH config SERIAL_RM9000 bool -config GPI_RM9000 - bool - -config WDT_RM9000 - bool - # # Unfortunately not all GT64120 systems run the chip at the same clock. # As the user for the clock rate and try to minimize the available options. From e48ce6b8df5b51af3f38b20bb3d008dff69ff64e Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 30 May 2007 00:38:07 +0900 Subject: [PATCH 473/551] [MIPS] Simplify missing-syscalls for N32 and O32 Use standard missing-syscalls with EXTRA_CFLAGS instead of duplicating the command. And move the archprepare rule before the archclean rule. Suggested by Franck Bui-Huu. Also add "echo" to show the target ABI. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index f450066b6241..2b19605b7382 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -702,6 +702,16 @@ vmlinux.srec: $(vmlinux-32) CLEAN_FILES += vmlinux.ecoff \ vmlinux.srec +archprepare: +ifdef CONFIG_MIPS32_N32 + @echo ' Checking missing-syscalls for N32' + $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=n32" +endif +ifdef CONFIG_MIPS32_O32 + @echo ' Checking missing-syscalls for O32' + $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32" +endif + archclean: @$(MAKE) $(clean)=arch/mips/boot @$(MAKE) $(clean)=arch/mips/lasat @@ -709,25 +719,3 @@ archclean: CLEAN_FILES += vmlinux.32 \ vmlinux.64 \ vmlinux.ecoff - -quiet_cmd_syscalls_n32 = CALL-N32 $< - cmd_syscalls_n32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=n32 - -quiet_cmd_syscalls_o32 = CALL-O32 $< - cmd_syscalls_o32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=32 - -PHONY += missing-syscalls-n32 missing-syscalls-o32 - -missing-syscalls-n32: scripts/checksyscalls.sh FORCE - $(call cmd,syscalls_n32) - -missing-syscalls-o32: scripts/checksyscalls.sh FORCE - $(call cmd,syscalls_o32) - -archprepare: -ifdef CONFIG_MIPS32_N32 - $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-n32 -endif -ifdef CONFIG_MIPS32_O32 - $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-o32 -endif From 9797cae3bfd2d7190609cdce05248cabc5d9081e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 7 Jul 2007 03:03:30 +0200 Subject: [PATCH 474/551] [MIPS] "extern inline" -> "static inline" "extern inline" will have different semantics with gcc 4.3, and "static inline" is correct here. Signed-off-by: Adrian Bunk Signed-off-by: Ralf Baechle --- include/asm-mips/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 5f80ba71ab92..3a466dc7b7db 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -237,7 +237,7 @@ unsigned long get_wchan(struct task_struct *p); #define ARCH_HAS_PREFETCH -extern inline void prefetch(const void *addr) +static inline void prefetch(const void *addr) { __asm__ __volatile__( " .set mips4 \n" From 4679258d52f6d4aeeafd5c77203d97ddf48e2db0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 7 Jul 2007 03:03:27 +0200 Subject: [PATCH 475/551] [MIPS] Remove unused cpu_callout_map and num_booting_cpus() Signed-off-by: Adrian Bunk Signed-off-by: Ralf Baechle --- include/asm-mips/smp.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 1608fd71d6f7..13aef6af422c 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -49,13 +49,6 @@ extern struct call_data_struct *call_data; extern cpumask_t phys_cpu_present_map; #define cpu_possible_map phys_cpu_present_map -extern cpumask_t cpu_callout_map; -/* We don't mark CPUs online until __cpu_up(), so we need another measure */ -static inline int num_booting_cpus(void) -{ - return cpus_weight(cpu_callout_map); -} - /* * These are defined by the board-specific code. */ From 096633358c907d9b50b00caf989816c2edfefe24 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 22 May 2007 00:05:58 +0900 Subject: [PATCH 476/551] [MIPS] Add generic GPIO support Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 3 +++ include/asm-mips/gpio.h | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 include/asm-mips/gpio.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c20cd9027585..1f2f7a9eabbe 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -778,6 +778,9 @@ config GENERIC_ISA_DMA_SUPPORT_BROKEN bool select ZONE_DMA +config GENERIC_GPIO + bool + # # Endianess selection. Sufficiently obscure so many users don't know what to # answer,so we try hard to limit the available choices. Also the use of a diff --git a/include/asm-mips/gpio.h b/include/asm-mips/gpio.h new file mode 100644 index 000000000000..06e46faf862d --- /dev/null +++ b/include/asm-mips/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_MIPS_GPIO_H +#define __ASM_MIPS_GPIO_H + +#include + +#endif /* __ASM_MIPS_GPIO_H */ From 82b8d2250c4b606e190853db9505b54b9fb71aa5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 22 Jun 2007 23:20:23 +0900 Subject: [PATCH 477/551] [MIPS] Create fallback gpio.h Create fallback gpio.h which only contains prototypes for gpio API. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/mach-generic/gpio.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 include/asm-mips/mach-generic/gpio.h diff --git a/include/asm-mips/mach-generic/gpio.h b/include/asm-mips/mach-generic/gpio.h new file mode 100644 index 000000000000..6eaf5efedf3a --- /dev/null +++ b/include/asm-mips/mach-generic/gpio.h @@ -0,0 +1,15 @@ +#ifndef __ASM_MACH_GENERIC_GPIO_H +#define __ASM_MACH_GENERIC_GPIO_H + +int gpio_request(unsigned gpio, const char *label); +void gpio_free(unsigned gpio); +int gpio_direction_input(unsigned gpio); +int gpio_direction_output(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); +void gpio_set_value(unsigned gpio, int value); +int gpio_to_irq(unsigned gpio); +int irq_to_gpio(unsigned irq); + +#include /* cansleep wrappers */ + +#endif /* __ASM_MACH_GENERIC_GPIO_H */ From 4ead16819b4c61fea9bb73eb470f6bb1d3350e5c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 22 May 2007 21:44:42 +0200 Subject: [PATCH 478/551] [MIPS] Add generic GPIO to Au1x00 This patch adds support for the generic GPIO API to Au1x00 boards. It requires the generic GPIO patch for MIPS boards by Yoichi Yuasa. Now there is a MIPS target using it, can you queue these patchset for 2.6.22 ? Thank you very much in advance. Signed-off-by: Florian Fainelli Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/au1000/common/gpio.c | 132 +++++++++++++-------- include/asm-mips/mach-au1x00/au1xxx_gpio.h | 20 ---- include/asm-mips/mach-au1x00/gpio.h | 69 +++++++++++ 4 files changed, 155 insertions(+), 67 deletions(-) delete mode 100644 include/asm-mips/mach-au1x00/au1xxx_gpio.h create mode 100644 include/asm-mips/mach-au1x00/gpio.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1f2f7a9eabbe..37977db6efff 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -861,6 +861,7 @@ config SOC_PNX8550 select SYS_SUPPORTS_32BIT_KERNEL select GENERIC_HARDIRQS_NO__DO_IRQ select SYS_SUPPORTS_KGDB + select GENERIC_GPIO config SWAP_IO_SPACE bool diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c index ce55297dcb8c..7abe42099439 100644 --- a/arch/mips/au1000/common/gpio.c +++ b/arch/mips/au1000/common/gpio.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2007, OpenWrt.org, Florian Fainelli + * Architecture specific GPIO support + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -18,101 +21,136 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Notes : + * au1000 SoC have only one GPIO line : GPIO1 + * others have a second one : GPIO2 */ + +#include +#include +#include +#include #include -#include -#include + +#include + +#include +#include #define gpio1 sys #if !defined(CONFIG_SOC_AU1000) -static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE; -#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 +static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE; +#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 -int au1xxx_gpio2_read(int signal) +static int au1xxx_gpio2_read(unsigned gpio) { - signal -= 200; -/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */ - return ((gpio2->pinstate >> signal) & 0x01); + gpio -= AU1XXX_GPIO_BASE; + return ((gpio2->pinstate >> gpio) & 0x01); } -void au1xxx_gpio2_write(int signal, int value) +static void au1xxx_gpio2_write(unsigned gpio, int value) { - signal -= 200; + gpio -= AU1XXX_GPIO_BASE; - gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) | - (value << signal); + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio); } -void au1xxx_gpio2_tristate(int signal) +static int au1xxx_gpio2_direction_input(unsigned gpio) { - signal -= 200; - gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */ -} -#endif - -int au1xxx_gpio1_read(int signal) -{ -/* gpio1->trioutclr |= (0x01 << signal); */ - return ((gpio1->pinstaterd >> signal) & 0x01); + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir &= ~(0x01 << gpio); + return 0; } -void au1xxx_gpio1_write(int signal, int value) +static int au1xxx_gpio2_direction_output(unsigned gpio, int value) { - if(value) - gpio1->outputset = (0x01 << signal); + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir = (0x01 << gpio) | (value << gpio); + return 0; +} + +#endif /* !defined(CONFIG_SOC_AU1000) */ + +static int au1xxx_gpio1_read(unsigned gpio) +{ + return ((gpio1->pinstaterd >> gpio) & 0x01); +} + +static void au1xxx_gpio1_write(unsigned gpio, int value) +{ + if (value) + gpio1->outputset = (0x01 << gpio); else - gpio1->outputclr = (0x01 << signal); /* Output a Zero */ + /* Output a zero */ + gpio1->outputclr = (0x01 << gpio); } -void au1xxx_gpio1_tristate(int signal) +static int au1xxx_gpio1_direction_input(unsigned gpio) { - gpio1->trioutclr = (0x01 << signal); /* Tristate signal */ + gpio1->pininputen = (0x01 << gpio); + return 0; } - -int au1xxx_gpio_read(int signal) +static int au1xxx_gpio1_direction_output(unsigned gpio, int value) { - if(signal >= 200) + gpio1->trioutclr = (0x01 & gpio); + return 0; +} + +int au1xxx_gpio_get_value(unsigned gpio) +{ + if (gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) return 0; #else - return au1xxx_gpio2_read(signal); + return au1xxx_gpio2_read(gpio); #endif else - return au1xxx_gpio1_read(signal); + return au1xxx_gpio1_read(gpio); } -void au1xxx_gpio_write(int signal, int value) +EXPORT_SYMBOL(au1xxx_gpio_get_value); + +void au1xxx_gpio_set_value(unsigned gpio, int value) { - if(signal >= 200) + if (gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) ; #else - au1xxx_gpio2_write(signal, value); + au1xxx_gpio2_write(gpio, value); #endif else - au1xxx_gpio1_write(signal, value); + au1xxx_gpio1_write(gpio, value); } -void au1xxx_gpio_tristate(int signal) +EXPORT_SYMBOL(au1xxx_gpio_set_value); + +int au1xxx_gpio_direction_input(unsigned gpio) { - if(signal >= 200) + if (gpio >= AU1XXX_GPIO_BASE) #if defined(CONFIG_SOC_AU1000) ; #else - au1xxx_gpio2_tristate(signal); + return au1xxx_gpio2_direction_input(gpio); #endif else - au1xxx_gpio1_tristate(signal); + return au1xxx_gpio1_direction_input(gpio); } -void au1xxx_gpio1_set_inputs(void) +EXPORT_SYMBOL(au1xxx_gpio_direction_input); + +int au1xxx_gpio_direction_output(unsigned gpio, int value) { - gpio1->pininputen = 0; + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + ; +#else + return au1xxx_gpio2_direction_output(gpio, value); +#endif + else + return au1xxx_gpio1_direction_output(gpio, value); } -EXPORT_SYMBOL(au1xxx_gpio1_set_inputs); -EXPORT_SYMBOL(au1xxx_gpio_tristate); -EXPORT_SYMBOL(au1xxx_gpio_write); -EXPORT_SYMBOL(au1xxx_gpio_read); +EXPORT_SYMBOL(au1xxx_gpio_direction_output); diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h deleted file mode 100644 index 27911e054ffc..000000000000 --- a/include/asm-mips/mach-au1x00/au1xxx_gpio.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __AU1XXX_GPIO_H -#define __AU1XXX_GPIO_H - -void au1xxx_gpio1_set_inputs(void); -void au1xxx_gpio_tristate(int signal); -void au1xxx_gpio_write(int signal, int value); -int au1xxx_gpio_read(int signal); - -typedef volatile struct -{ - u32 dir; - u32 reserved; - u32 output; - u32 pinstate; - u32 inten; - u32 enable; - -} AU1X00_GPIO2; - -#endif //__AU1XXX_GPIO_H diff --git a/include/asm-mips/mach-au1x00/gpio.h b/include/asm-mips/mach-au1x00/gpio.h new file mode 100644 index 000000000000..2dc61e009a08 --- /dev/null +++ b/include/asm-mips/mach-au1x00/gpio.h @@ -0,0 +1,69 @@ +#ifndef _AU1XXX_GPIO_H_ +#define _AU1XXX_GPIO_H_ + +#include + +#define AU1XXX_GPIO_BASE 200 + +struct au1x00_gpio2 { + u32 dir; + u32 reserved; + u32 output; + u32 pinstate; + u32 inten; + u32 enable; +}; + +extern int au1xxx_gpio_get_value(unsigned gpio); +extern void au1xxx_gpio_set_value(unsigned gpio, int value); +extern int au1xxx_gpio_direction_input(unsigned gpio); +extern int au1xxx_gpio_direction_output(unsigned gpio, int value); + + +/* Wrappers for the arch-neutral GPIO API */ + +static inline int gpio_request(unsigned gpio, const char *label) +{ + /* Not yet implemented */ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ + /* Not yet implemented */ +} + +static inline int gpio_direction_input(unsigned gpio) +{ + return au1xxx_gpio_direction_input(gpio); +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return au1xxx_gpio_direction_output(gpio, value); +} + +static inline int gpio_get_value(unsigned gpio) +{ + return au1xxx_gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + au1xxx_gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq; +} + +/* For cansleep */ +#include + +#endif /* _AU1XXX_GPIO_H_ */ From 8f8771a057bff0d3911459d0bdadf03ec1dd3c89 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:32:56 +0100 Subject: [PATCH 479/551] [MIPS] SMTC: Use current_cpu_data instead of cpu_data[smp_processor_id] Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 046b03b1705a..342d873b2ecc 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1104,7 +1104,7 @@ void smtc_idle_loop_hook(void) mtflags = dmt(); pdb_msg = &id_ho_db_msg[0]; im = read_c0_status(); - vpe = cpu_data[smp_processor_id()].vpe_id; + vpe = current_cpu_data.vpe_id; for (bit = 0; bit < 8; bit++) { /* * In current prototype, I/O interrupts From b3f6df9f21c6efc4641613188204aa0742bc9e22 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Fri, 25 May 2007 14:32:28 -0400 Subject: [PATCH 480/551] [MIPS] Transform old-style macros to newer "__noreturn" Convert old/obsolete NORET_TYPE and ATTRIB_NORET macros to use the newer standard of "__noreturn" as defined in compiler-gcc.h. Signed-off-by: Robert P. J. Day Signed-off-by: Ralf Baechle --- arch/mips/dec/prom/init.c | 2 +- arch/mips/dec/reset.c | 10 +++++----- arch/mips/kernel/process.c | 4 ++-- arch/mips/kernel/smp.c | 2 +- arch/mips/kernel/traps.c | 2 +- arch/mips/sgi-ip22/ip22-reset.c | 6 +++--- arch/mips/sibyte/cfe/setup.c | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c index a217aafe59f6..4828cac4748f 100644 --- a/arch/mips/dec/prom/init.c +++ b/arch/mips/dec/prom/init.c @@ -86,7 +86,7 @@ void __init which_prom(s32 magic, s32 *prom_vec) void __init prom_init(void) { - extern void ATTRIB_NORET dec_machine_halt(void); + extern void dec_machine_halt(void); static char cpu_msg[] __initdata = "Sorry, this kernel is compiled for a wrong CPU type!\n"; s32 argc = fw_arg0; diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c index 56397227adb0..c15a879046e5 100644 --- a/arch/mips/dec/reset.c +++ b/arch/mips/dec/reset.c @@ -9,26 +9,26 @@ #include -typedef void ATTRIB_NORET (* noret_func_t)(void); +typedef void __noreturn (* noret_func_t)(void); -static inline void ATTRIB_NORET back_to_prom(void) +static inline void __noreturn back_to_prom(void) { noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000); func(); } -void ATTRIB_NORET dec_machine_restart(char *command) +void __noreturn dec_machine_restart(char *command) { back_to_prom(); } -void ATTRIB_NORET dec_machine_halt(void) +void __noreturn dec_machine_halt(void) { back_to_prom(); } -void ATTRIB_NORET dec_machine_power_off(void) +void __noreturn dec_machine_power_off(void) { /* DECstations don't have a software power switch */ back_to_prom(); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 6bdfb5a9fa1a..8f4cf27c7157 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -46,7 +46,7 @@ * power and have a low exit latency (ie sit in a loop waiting for somebody to * say that they'd like to reschedule) */ -ATTRIB_NORET void cpu_idle(void) +void __noreturn cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { @@ -213,7 +213,7 @@ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr) /* * Create a kernel thread */ -static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) +static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *)) { do_exit(fn(arg)); } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index a1b017f2dbb3..be7362bc2c9a 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -52,7 +52,7 @@ EXPORT_SYMBOL(phys_cpu_present_map); EXPORT_SYMBOL(cpu_online_map); extern void __init calibrate_delay(void); -extern ATTRIB_NORET void cpu_idle(void); +extern void cpu_idle(void); /* * First C code run on the secondary CPUs after being started up by diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3ea7863c4519..20bdbe48839b 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -311,7 +311,7 @@ void show_registers(struct pt_regs *regs) static DEFINE_SPINLOCK(die_lock); -NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) +void __noreturn die(const char * str, struct pt_regs * regs) { static int die_counter; #ifdef CONFIG_MIPS_MT_SMTC diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 66df5ac8f089..63afd7e44428 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -46,7 +46,7 @@ static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; static int machine_state; -static void ATTRIB_NORET sgi_machine_power_off(void) +static void __noreturn sgi_machine_power_off(void) { unsigned int tmp; @@ -68,7 +68,7 @@ static void ATTRIB_NORET sgi_machine_power_off(void) } } -static void ATTRIB_NORET sgi_machine_restart(char *command) +static void __noreturn sgi_machine_restart(char *command) { if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); @@ -76,7 +76,7 @@ static void ATTRIB_NORET sgi_machine_restart(char *command) while (1); } -static void ATTRIB_NORET sgi_machine_halt(void) +static void __noreturn sgi_machine_halt(void) { if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c index ae4a92c3e529..51898dd1304a 100644 --- a/arch/mips/sibyte/cfe/setup.c +++ b/arch/mips/sibyte/cfe/setup.c @@ -62,7 +62,7 @@ extern unsigned long initrd_start, initrd_end; extern int kgdb_port; #endif -static void ATTRIB_NORET cfe_linux_exit(void *arg) +static void __noreturn cfe_linux_exit(void *arg) { int warm = *(int *)arg; @@ -83,14 +83,14 @@ static void ATTRIB_NORET cfe_linux_exit(void *arg) while (1); } -static void ATTRIB_NORET cfe_linux_restart(char *command) +static void __noreturn cfe_linux_restart(char *command) { static const int zero; cfe_linux_exit((void *)&zero); } -static void ATTRIB_NORET cfe_linux_halt(void) +static void __noreturn cfe_linux_halt(void) { static const int one = 1; From 8bb809df6919f927bcb910bbc852d5724eaa1eb9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:32:56 +0100 Subject: [PATCH 481/551] [MIPS] Cleanup TO_PHYS_MASK definition No point in adding yet another #ifdef for Loongson since all this mask is being used for is converting an XKPHYS address into a physical address anyway. So replace all definitions by one with the highest architectural possible value. Signed-off-by: Ralf Baechle --- include/asm-mips/addrspace.h | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h index 964c5eddc21b..0b3ff9c48409 100644 --- a/include/asm-mips/addrspace.h +++ b/include/asm-mips/addrspace.h @@ -129,29 +129,12 @@ #define PHYS_TO_XKPHYS(cm,a) (_CONST64_(0x8000000000000000) | \ ((cm)<<59) | (a)) -#if defined (CONFIG_CPU_R4300) \ - || defined (CONFIG_CPU_R4X00) \ - || defined (CONFIG_CPU_R5000) \ - || defined (CONFIG_CPU_RM7000) \ - || defined (CONFIG_CPU_RM9000) \ - || defined (CONFIG_CPU_NEVADA) \ - || defined (CONFIG_CPU_TX49XX) \ - || defined (CONFIG_CPU_MIPS64) -#define TO_PHYS_MASK _CONST64_(0x0000000fffffffff) /* 2^^36 - 1 */ -#endif - -#if defined (CONFIG_CPU_R8000) -/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */ -#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */ -#endif - -#if defined (CONFIG_CPU_R10000) -#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */ -#endif - -#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A) -#define TO_PHYS_MASK _CONST64_(0x00000fffffffffff) /* 2^^44 - 1 */ -#endif +/* + * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting + * the region, 3 bits for the CCA mode. This leaves 59 bits of which the + * R8000 implements most with its 48-bit physical address space. + */ +#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */ #ifndef CONFIG_CPU_R8000 From 24e9d0b96dac5503c0b6f034d553030c604228a7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:32:56 +0100 Subject: [PATCH 482/551] [MIPS] Hook for platforms to define cachability of /dev/mem regions Signed-off-by: Ralf Baechle --- arch/mips/mm/cache.c | 10 ++++++++++ drivers/char/mem.c | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index abf99b1eba13..81f925a9a731 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -6,6 +6,8 @@ * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2007 MIPS Technologies, Inc. */ +#include +#include #include #include #include @@ -164,3 +166,11 @@ void __init cpu_cache_init(void) panic(cache_panic); } + +int __weak __uncached_access(struct file *file, unsigned long addr) +{ + if (file->f_flags & O_SYNC) + return 1; + + return addr >= __pa(high_memory); +} diff --git a/drivers/char/mem.c b/drivers/char/mem.c index cc9a9d0df979..7e082bceed57 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -75,6 +75,13 @@ static inline int uncached_access(struct file *file, unsigned long addr) * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. */ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); +#elif defined(CONFIG_MIPS) + { + extern int __uncached_access(struct file *file, + unsigned long addr); + + return __uncached_access(file, addr); + } #else /* * Accessing memory above the top the kernel knows about or through a file pointer From f6e2373ad6148476464fc7bb2610c6450c18cd2a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:32:56 +0100 Subject: [PATCH 483/551] [MIPS] MIPSsim: Move code away from the other MIPS Inc. BSP code. It shares no code at all. While at it also fix up the beginning bitrot. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/Makefile | 2 +- arch/mips/kernel/head.S | 7 +- .../{mips-boards/sim => mipssim}/Makefile | 0 .../sim => mipssim}/sim_cmdline.c | 0 .../sim => mipssim}/sim_console.c | 2 +- arch/mips/mipssim/sim_int.c | 88 +++++++++++++++++++ .../{mips-boards/sim => mipssim}/sim_mem.c | 2 +- .../sim => mipssim}/sim_platform.c | 0 .../{mips-boards/sim => mipssim}/sim_setup.c | 8 +- .../{mips-boards/sim => mipssim}/sim_smp.c | 18 ++-- .../{mips-boards/sim => mipssim}/sim_time.c | 30 +++---- .../cpu-feature-overrides.h | 0 13 files changed, 125 insertions(+), 33 deletions(-) rename arch/mips/{mips-boards/sim => mipssim}/Makefile (100%) rename arch/mips/{mips-boards/sim => mipssim}/sim_cmdline.c (100%) rename arch/mips/{mips-boards/sim => mipssim}/sim_console.c (98%) create mode 100644 arch/mips/mipssim/sim_int.c rename arch/mips/{mips-boards/sim => mipssim}/sim_mem.c (99%) rename arch/mips/{mips-boards/sim => mipssim}/sim_platform.c (100%) rename arch/mips/{mips-boards/sim => mipssim}/sim_setup.c (95%) rename arch/mips/{mips-boards/sim => mipssim}/sim_smp.c (89%) rename arch/mips/{mips-boards/sim => mipssim}/sim_time.c (91%) rename include/asm-mips/{mach-sim => mach-mipssim}/cpu-feature-overrides.h (100%) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 37977db6efff..734b61f663b7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -251,6 +251,7 @@ config MIPS_SIM select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_LITTLE_ENDIAN help This option enables support for MIPS Technologies MIPSsim software diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 2b19605b7382..077eb0bd1c78 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -327,7 +327,7 @@ load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000 # # MIPS SIM # -core-$(CONFIG_MIPS_SIM) += arch/mips/mips-boards/sim/ +core-$(CONFIG_MIPS_SIM) += arch/mips/mipssim/ cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim load-$(CONFIG_MIPS_SIM) += 0x80100000 diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 6f57ca44291f..1f096aa35bc0 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -138,15 +138,14 @@ EXPORT(stext) # used for profiling EXPORT(_stext) -#ifdef CONFIG_MIPS_SIM +#ifndef CONFIG_MIPS_SIM /* * Give us a fighting chance of running if execution beings at the * kernel load address. This is needed because this platform does * not have a ELF loader yet. */ - j kernel_entry -#endif __INIT +#endif NESTED(kernel_entry, 16, sp) # kernel entry point @@ -197,9 +196,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point j start_kernel END(kernel_entry) -#ifdef CONFIG_QEMU __INIT -#endif #ifdef CONFIG_SMP /* diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mipssim/Makefile similarity index 100% rename from arch/mips/mips-boards/sim/Makefile rename to arch/mips/mipssim/Makefile diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c similarity index 100% rename from arch/mips/mips-boards/sim/sim_cmdline.c rename to arch/mips/mipssim/sim_cmdline.c diff --git a/arch/mips/mips-boards/sim/sim_console.c b/arch/mips/mipssim/sim_console.c similarity index 98% rename from arch/mips/mips-boards/sim/sim_console.c rename to arch/mips/mipssim/sim_console.c index de595a9ccb27..a2f41672cd5d 100644 --- a/arch/mips/mips-boards/sim/sim_console.c +++ b/arch/mips/mipssim/sim_console.c @@ -18,8 +18,8 @@ * written by Ralf Baechle */ #include +#include #include -#include static inline unsigned int serial_in(int offset) { diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c new file mode 100644 index 000000000000..d86b37235cf6 --- /dev/null +++ b/arch/mips/mipssim/sim_int.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +static inline int clz(unsigned long x) +{ + __asm__ ( + " .set push \n" + " .set mips32 \n" + " clz %0, %1 \n" + " .set pop \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +/* + * Version of ffs that only looks at bits 12..15. + */ +static inline unsigned int irq_ffs(unsigned int pending) +{ +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + return -clz(pending) + 31 - CAUSEB_IP; +#else + unsigned int a0 = 7; + unsigned int t0; + + t0 = s0 & 0xf000; + t0 = t0 < 1; + t0 = t0 << 2; + a0 = a0 - t0; + s0 = s0 << t0; + + t0 = s0 & 0xc000; + t0 = t0 < 1; + t0 = t0 << 1; + a0 = a0 - t0; + s0 = s0 << t0; + + t0 = s0 & 0x8000; + t0 = t0 < 1; + /* t0 = t0 << 2; */ + a0 = a0 - t0; + /* s0 = s0 << t0; */ + + return a0; +#endif +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + irq = irq_ffs(pending); + + if (irq > 0) + do_IRQ(MIPSCPU_INT_BASE + irq); + else + spurious_interrupt(); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); +} diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mipssim/sim_mem.c similarity index 99% rename from arch/mips/mips-boards/sim/sim_mem.c rename to arch/mips/mipssim/sim_mem.c index e408ef0bcd6e..2312483eb838 100644 --- a/arch/mips/mips-boards/sim/sim_mem.c +++ b/arch/mips/mipssim/sim_mem.c @@ -95,7 +95,7 @@ void __init prom_meminit(void) size = p->size; add_memory_region(base, size, type); - p++; + p++; } } diff --git a/arch/mips/mips-boards/sim/sim_platform.c b/arch/mips/mipssim/sim_platform.c similarity index 100% rename from arch/mips/mips-boards/sim/sim_platform.c rename to arch/mips/mipssim/sim_platform.c diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mipssim/sim_setup.c similarity index 95% rename from arch/mips/mips-boards/sim/sim_setup.c rename to arch/mips/mipssim/sim_setup.c index b705f09e57c3..3643582bdade 100644 --- a/arch/mips/mips-boards/sim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -19,18 +19,18 @@ #include #include #include +#include +#include #include +#include #include #include #include #include #include -#include #include #include -#include -#include #include #include #include @@ -62,7 +62,7 @@ void __init plat_mem_setup(void) #endif } -void prom_init(void) +void __init prom_init(void) { set_io_port_base(0xbfd00000); diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mipssim/sim_smp.c similarity index 89% rename from arch/mips/mips-boards/sim/sim_smp.c rename to arch/mips/mipssim/sim_smp.c index cb47863ecf10..38fa807b99f9 100644 --- a/arch/mips/mips-boards/sim/sim_smp.c +++ b/arch/mips/mipssim/sim_smp.c @@ -22,13 +22,13 @@ #include #include #include +#include + #include #include #include #include -#include #include -#include #ifdef CONFIG_MIPS_MT_SMTC #include #endif /* CONFIG_MIPS_MT_SMTC */ @@ -73,11 +73,19 @@ void prom_init_secondary(void) #endif /* CONFIG_MIPS_MT_SMTC */ } +void plat_smp_setup(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + if (read_c0_config3() & (1 << 2)) + mipsmt_build_cpu_map(0); +#endif /* CONFIG_MIPS_MT_SMTC */ +} + /* * Platform SMP pre-initialization */ -void prom_prepare_cpus(unsigned int max_cpus) +void plat_prepare_cpus(unsigned int max_cpus) { #ifdef CONFIG_MIPS_MT_SMTC /* @@ -85,8 +93,8 @@ void prom_prepare_cpus(unsigned int max_cpus) * but it may be multithreaded. */ - if (read_c0_config3() & (1<<2)) { - mipsmt_prepare_cpus(max_cpus); + if (read_c0_config3() & (1 << 2)) { + mipsmt_prepare_cpus(); } #endif /* CONFIG_MIPS_MT_SMTC */ } diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mipssim/sim_time.c similarity index 91% rename from arch/mips/mips-boards/sim/sim_time.c rename to arch/mips/mipssim/sim_time.c index 7224ffe31d36..874a18e8ac24 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mipssim/sim_time.c @@ -5,10 +5,10 @@ #include #include #include +#include +#include #include -#include -#include #include #include #include @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -37,8 +36,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) #ifndef CONFIG_MIPS_MT_SMTC if (cpu == 0) { timer_interrupt(irq, dev_id); - } - else { + } else { /* Everyone else needs to reset the timer int here as ll_local_timer_interrupt doesn't */ /* @@ -76,8 +74,10 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) irq_enable_hazard(); evpe(vpflags); - if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id); - else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); + if (cpu_data[cpu].vpe_id == 0) + timer_interrupt(irq, dev_id); + else + write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); smtc_timer_broadcast(cpu_data[cpu].vpe_id); #endif /* CONFIG_MIPS_MT_SMTC */ @@ -85,7 +85,8 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) /* * every CPU should do profiling and process accounting */ - local_timer_interrupt (irq, dev_id); + local_timer_interrupt (irq, dev_id); + return IRQ_HANDLED; #else return timer_interrupt (irq, dev_id); @@ -152,17 +153,15 @@ void __init sim_time_init(void) local_irq_save(flags); - - /* Set Data mode - binary. */ + /* Set Data mode - binary. */ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); - est_freq = estimate_cpu_frequency (); - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); + printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, + (est_freq % 1000000) * 100 / 1000000); - cpu_khz = est_freq / 1000; + cpu_khz = est_freq / 1000; local_irq_restore(flags); } @@ -180,8 +179,7 @@ void __init plat_timer_setup(struct irqaction *irq) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } - else { + } else { if (cpu_has_vint) set_vi_handler(cp0_compare_irq, mips_timer_dispatch); mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-mipssim/cpu-feature-overrides.h similarity index 100% rename from include/asm-mips/mach-sim/cpu-feature-overrides.h rename to include/asm-mips/mach-mipssim/cpu-feature-overrides.h From 4becef1d85a48ea4294c962c2cbacb6074f0dd58 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 2 Jun 2007 00:21:30 +0900 Subject: [PATCH 484/551] [MIPS] Unify dump_tlb Unify lib-{32,64}/dump_tlb.c into lib/dump_tlb.c and move lib-32/r3k_dump_tlb.c to lib directory. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib-32/Makefile | 18 -- arch/mips/lib-32/dump_tlb.c | 242 ----------------------- arch/mips/lib-64/Makefile | 18 -- arch/mips/lib/Makefile | 18 ++ arch/mips/{lib-64 => lib}/dump_tlb.c | 58 ++++-- arch/mips/{lib-32 => lib}/r3k_dump_tlb.c | 0 6 files changed, 60 insertions(+), 294 deletions(-) delete mode 100644 arch/mips/lib-32/dump_tlb.c rename arch/mips/{lib-64 => lib}/dump_tlb.c (78%) rename arch/mips/{lib-32 => lib}/r3k_dump_tlb.c (100%) diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile index 8b94d4cc5a30..7bae849e544a 100644 --- a/arch/mips/lib-32/Makefile +++ b/arch/mips/lib-32/Makefile @@ -3,21 +3,3 @@ # lib-y += watch.o - -obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o -obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o -obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o -obj-$(CONFIG_CPU_R10000) += dump_tlb.o -obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o -obj-$(CONFIG_CPU_R4300) += dump_tlb.o -obj-$(CONFIG_CPU_R4X00) += dump_tlb.o -obj-$(CONFIG_CPU_R5000) += dump_tlb.o -obj-$(CONFIG_CPU_R5432) += dump_tlb.o -obj-$(CONFIG_CPU_R6000) += -obj-$(CONFIG_CPU_R8000) += -obj-$(CONFIG_CPU_RM7000) += dump_tlb.o -obj-$(CONFIG_CPU_RM9000) += dump_tlb.o -obj-$(CONFIG_CPU_SB1) += dump_tlb.o -obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o -obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o -obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c deleted file mode 100644 index 6a68deb51aae..000000000000 --- a/arch/mips/lib-32/dump_tlb.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Dump R4x00 TLB for debugging purposes. - * - * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle. - * Copyright (C) 1999 by Silicon Graphics, Inc. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static inline const char *msk2str(unsigned int mask) -{ - switch (mask) { - case PM_4K: - return "4kb"; - case PM_16K: - return "16kb"; - case PM_64K: - return "64kb"; - case PM_256K: - return "256kb"; -#ifndef CONFIG_CPU_VR41XX - case PM_1M: - return "1Mb"; - case PM_4M: - return "4Mb"; - case PM_16M: - return "16Mb"; - case PM_64M: - return "64Mb"; - case PM_256M: - return "256Mb"; -#endif - } - - return "unknown"; -} - -#define BARRIER() \ - __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - "nop;nop;nop;nop;nop;nop;nop\n\t" \ - ".set\treorder"); - -void dump_tlb(int first, int last) -{ - unsigned int pagemask, c0, c1, asid; - unsigned long long entrylo0, entrylo1; - unsigned long entryhi; - int i; - - asid = read_c0_entryhi() & 0xff; - - printk("\n"); - for (i = first; i <= last; i++) { - write_c0_index(i); - BARRIER(); - tlb_read(); - BARRIER(); - pagemask = read_c0_pagemask(); - entryhi = read_c0_entryhi(); - entrylo0 = read_c0_entrylo0(); - entrylo1 = read_c0_entrylo1(); - - /* Unused entries have a virtual address in KSEG0. */ - if ((entryhi & 0xf0000000) != 0x80000000 - && (entryhi & 0xff) == asid) { - /* - * Only print entries in use - */ - printk("Index: %2d pgmask=%s ", i, msk2str(pagemask)); - - c0 = (entrylo0 >> 3) & 7; - c1 = (entrylo1 >> 3) & 7; - - printk("va=%08lx asid=%02lx\n", - (entryhi & 0xffffe000), (entryhi & 0xff)); - printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n", - (entrylo0 << 6) & PAGE_MASK, c0, - (entrylo0 & 4) ? 1 : 0, - (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1)); - printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n", - (entrylo1 << 6) & PAGE_MASK, c1, - (entrylo1 & 4) ? 1 : 0, - (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1)); - printk("\n"); - } - } - - write_c0_entryhi(asid); -} - -void dump_tlb_all(void) -{ - dump_tlb(0, current_cpu_data.tlbsize - 1); -} - -void dump_tlb_wired(void) -{ - int wired; - - wired = read_c0_wired(); - printk("Wired: %d", wired); - dump_tlb(0, read_c0_wired()); -} - -void dump_tlb_addr(unsigned long addr) -{ - unsigned int flags, oldpid; - int index; - - local_irq_save(flags); - oldpid = read_c0_entryhi() & 0xff; - BARRIER(); - write_c0_entryhi((addr & PAGE_MASK) | oldpid); - BARRIER(); - tlb_probe(); - BARRIER(); - index = read_c0_index(); - write_c0_entryhi(oldpid); - local_irq_restore(flags); - - if (index < 0) { - printk("No entry for address 0x%08lx in TLB\n", addr); - return; - } - - printk("Entry %d maps address 0x%08lx\n", index, addr); - dump_tlb(index, index); -} - -void dump_tlb_nonwired(void) -{ - dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); -} - -void dump_list_process(struct task_struct *t, void *address) -{ - pgd_t *page_dir, *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte, page; - unsigned long addr, val; - - addr = (unsigned long) address; - - printk("Addr == %08lx\n", addr); - printk("task == %8p\n", t); - printk("task->mm == %8p\n", t->mm); - //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); - - if (addr > KSEG0) { - page_dir = pgd_offset_k(0); - pgd = pgd_offset_k(addr); - } else if (t->mm) { - page_dir = pgd_offset(t->mm, 0); - pgd = pgd_offset(t->mm, addr); - } else { - printk("Current thread has no mm\n"); - return; - } - printk("page_dir == %08x\n", (unsigned int) page_dir); - printk("pgd == %08x, ", (unsigned int) pgd); - pud = pud_offset(pgd, addr); - printk("pud == %08x, ", (unsigned int) pud); - - pmd = pmd_offset(pud, addr); - printk("pmd == %08x, ", (unsigned int) pmd); - - pte = pte_offset(pmd, addr); - printk("pte == %08x, ", (unsigned int) pte); - - page = *pte; -#ifdef CONFIG_64BIT_PHYS_ADDR - printk("page == %08Lx\n", pte_val(page)); -#else - printk("page == %08lx\n", pte_val(page)); -#endif - - val = pte_val(page); - if (val & _PAGE_PRESENT) - printk("present "); - if (val & _PAGE_READ) - printk("read "); - if (val & _PAGE_WRITE) - printk("write "); - if (val & _PAGE_ACCESSED) - printk("accessed "); - if (val & _PAGE_MODIFIED) - printk("modified "); - if (val & _PAGE_R4KBUG) - printk("r4kbug "); - if (val & _PAGE_GLOBAL) - printk("global "); - if (val & _PAGE_VALID) - printk("valid "); - printk("\n"); -} - -void dump_list_current(void *address) -{ - dump_list_process(current, address); -} - -unsigned int vtop(void *address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned int addr, paddr; - - addr = (unsigned long) address; - pgd = pgd_offset(current->mm, addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - pte = pte_offset(pmd, addr); - paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK; - paddr |= (addr & ~PAGE_MASK); - - return paddr; -} - -void dump16(unsigned long *p) -{ - int i; - - for (i = 0; i < 8; i++) { - printk("*%08lx == %08lx, ", (unsigned long) p, *p); - p++; - printk("*%08lx == %08lx\n", (unsigned long) p, *p); - p++; - } -} diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile index 8b94d4cc5a30..7bae849e544a 100644 --- a/arch/mips/lib-64/Makefile +++ b/arch/mips/lib-64/Makefile @@ -3,21 +3,3 @@ # lib-y += watch.o - -obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o -obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o -obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o -obj-$(CONFIG_CPU_R10000) += dump_tlb.o -obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o -obj-$(CONFIG_CPU_R4300) += dump_tlb.o -obj-$(CONFIG_CPU_R4X00) += dump_tlb.o -obj-$(CONFIG_CPU_R5000) += dump_tlb.o -obj-$(CONFIG_CPU_R5432) += dump_tlb.o -obj-$(CONFIG_CPU_R6000) += -obj-$(CONFIG_CPU_R8000) += -obj-$(CONFIG_CPU_RM7000) += dump_tlb.o -obj-$(CONFIG_CPU_RM9000) += dump_tlb.o -obj-$(CONFIG_CPU_SB1) += dump_tlb.o -obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o -obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o -obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 1c1aa9f92f6c..1a484e430b3c 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -8,5 +8,23 @@ lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \ obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o +obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o +obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o +obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o +obj-$(CONFIG_CPU_R10000) += dump_tlb.o +obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_R4300) += dump_tlb.o +obj-$(CONFIG_CPU_R4X00) += dump_tlb.o +obj-$(CONFIG_CPU_R5000) += dump_tlb.o +obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R6000) += +obj-$(CONFIG_CPU_R8000) += +obj-$(CONFIG_CPU_RM7000) += dump_tlb.o +obj-$(CONFIG_CPU_RM9000) += dump_tlb.o +obj-$(CONFIG_CPU_SB1) += dump_tlb.o +obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o +obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o +obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o + # libgcc-style stuff needed in the kernel obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib/dump_tlb.c similarity index 78% rename from arch/mips/lib-64/dump_tlb.c rename to arch/mips/lib/dump_tlb.c index 594df1a05ecc..fbf4b72f4306 100644 --- a/arch/mips/lib-64/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -31,8 +31,7 @@ static inline const char *msk2str(unsigned int mask) case PM_256M: return "256Mb"; #endif } - - return "unknown"; + return ""; } #define BARRIER() \ @@ -43,7 +42,8 @@ static inline const char *msk2str(unsigned int mask) void dump_tlb(int first, int last) { - unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid; + unsigned long s_entryhi, entryhi, asid; + unsigned long long entrylo0, entrylo1; unsigned int s_index, pagemask, c0, c1, i; s_entryhi = read_c0_entryhi(); @@ -63,6 +63,11 @@ void dump_tlb(int first, int last) /* Unused entries have a virtual address of CKSEG0. */ if ((entryhi & ~0x1ffffUL) != CKSEG0 && (entryhi & 0xff) == asid) { +#ifdef CONFIG_32BIT + int width = 8; +#else + int width = 11; +#endif /* * Only print entries in use */ @@ -71,19 +76,21 @@ void dump_tlb(int first, int last) c0 = (entrylo0 >> 3) & 7; c1 = (entrylo1 >> 3) & 7; - printk("va=%011lx asid=%02lx\n", - (entryhi & ~0x1fffUL), + printk("va=%0*lx asid=%02lx\n", + width, (entryhi & ~0x1fffUL), entryhi & 0xff); - printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ", + printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ", + width, (entrylo0 << 6) & PAGE_MASK, c0, (entrylo0 & 4) ? 1 : 0, (entrylo0 & 2) ? 1 : 0, - (entrylo0 & 1)); - printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n", + (entrylo0 & 1) ? 1 : 0); + printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n", + width, (entrylo1 << 6) & PAGE_MASK, c1, (entrylo1 & 4) ? 1 : 0, (entrylo1 & 2) ? 1 : 0, - (entrylo1 & 1)); + (entrylo1 & 1) ? 1 : 0); } } printk("\n"); @@ -143,29 +150,48 @@ void dump_list_process(struct task_struct *t, void *address) pmd_t *pmd; pte_t *pte, page; unsigned long addr, val; + int width = sizeof(long) * 2; addr = (unsigned long) address; printk("Addr == %08lx\n", addr); +#ifdef CONFIG_64BIT printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); +#endif +#ifdef CONFIG_64BIT page_dir = pgd_offset(t->mm, 0UL); - printk("page_dir == %016lx\n", (unsigned long) page_dir); - pgd = pgd_offset(t->mm, addr); - printk("pgd == %016lx\n", (unsigned long) pgd); +#else + if (addr > KSEG0) { + page_dir = pgd_offset_k(0); + pgd = pgd_offset_k(addr); + } else if (t->mm) { + page_dir = pgd_offset(t->mm, 0); + pgd = pgd_offset(t->mm, addr); + } else { + printk("Current thread has no mm\n"); + return; + } +#endif + printk("page_dir == %0*lx\n", width, (unsigned long) page_dir); + printk("pgd == %0*lx\n", width, (unsigned long) pgd); pud = pud_offset(pgd, addr); - printk("pud == %016lx\n", (unsigned long) pud); + printk("pud == %0*lx\n", width, (unsigned long) pud); pmd = pmd_offset(pud, addr); - printk("pmd == %016lx\n", (unsigned long) pmd); + printk("pmd == %0*lx\n", width, (unsigned long) pmd); pte = pte_offset(pmd, addr); - printk("pte == %016lx\n", (unsigned long) pte); + printk("pte == %0*lx\n", width, (unsigned long) pte); page = *pte; - printk("page == %08lx\n", pte_val(page)); +#ifdef CONFIG_64BIT_PHYS_ADDR + printk("page == %08Lx\n", pte_val(page)); +#else + printk("page == %0*lx\n", width, pte_val(page)); +#endif val = pte_val(page); if (val & _PAGE_PRESENT) printk("present "); diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c similarity index 100% rename from arch/mips/lib-32/r3k_dump_tlb.c rename to arch/mips/lib/r3k_dump_tlb.c From 69ed25b895b01216b392b60ad3b99d1274e1afa8 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 2 Jun 2007 00:30:25 +0900 Subject: [PATCH 485/551] [MIPS] Remove unused dump_tlb functions Remove unused dump_tlb functions and cleanup some includes. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib/dump_tlb.c | 144 +-------------------------------- arch/mips/lib/r3k_dump_tlb.c | 122 +--------------------------- arch/mips/sgi-ip27/ip27-berr.c | 1 - 3 files changed, 2 insertions(+), 265 deletions(-) diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index fbf4b72f4306..1a4db7dc77cb 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -6,12 +6,7 @@ */ #include #include -#include -#include -#include -#include -#include #include #include #include @@ -40,7 +35,7 @@ static inline const char *msk2str(unsigned int mask) "nop;nop;nop;nop;nop;nop;nop\n\t" \ ".set\treorder"); -void dump_tlb(int first, int last) +static void dump_tlb(int first, int last) { unsigned long s_entryhi, entryhi, asid; unsigned long long entrylo0, entrylo1; @@ -103,140 +98,3 @@ void dump_tlb_all(void) { dump_tlb(0, current_cpu_data.tlbsize - 1); } - -void dump_tlb_wired(void) -{ - int wired; - - wired = read_c0_wired(); - printk("Wired: %d", wired); - dump_tlb(0, read_c0_wired()); -} - -void dump_tlb_addr(unsigned long addr) -{ - unsigned int flags, oldpid; - int index; - - local_irq_save(flags); - oldpid = read_c0_entryhi() & 0xff; - BARRIER(); - write_c0_entryhi((addr & PAGE_MASK) | oldpid); - BARRIER(); - tlb_probe(); - BARRIER(); - index = read_c0_index(); - write_c0_entryhi(oldpid); - local_irq_restore(flags); - - if (index < 0) { - printk("No entry for address 0x%08lx in TLB\n", addr); - return; - } - - printk("Entry %d maps address 0x%08lx\n", index, addr); - dump_tlb(index, index); -} - -void dump_tlb_nonwired(void) -{ - dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); -} - -void dump_list_process(struct task_struct *t, void *address) -{ - pgd_t *page_dir, *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte, page; - unsigned long addr, val; - int width = sizeof(long) * 2; - - addr = (unsigned long) address; - - printk("Addr == %08lx\n", addr); -#ifdef CONFIG_64BIT - printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); -#endif - -#ifdef CONFIG_64BIT - page_dir = pgd_offset(t->mm, 0UL); - pgd = pgd_offset(t->mm, addr); -#else - if (addr > KSEG0) { - page_dir = pgd_offset_k(0); - pgd = pgd_offset_k(addr); - } else if (t->mm) { - page_dir = pgd_offset(t->mm, 0); - pgd = pgd_offset(t->mm, addr); - } else { - printk("Current thread has no mm\n"); - return; - } -#endif - printk("page_dir == %0*lx\n", width, (unsigned long) page_dir); - printk("pgd == %0*lx\n", width, (unsigned long) pgd); - - pud = pud_offset(pgd, addr); - printk("pud == %0*lx\n", width, (unsigned long) pud); - - pmd = pmd_offset(pud, addr); - printk("pmd == %0*lx\n", width, (unsigned long) pmd); - - pte = pte_offset(pmd, addr); - printk("pte == %0*lx\n", width, (unsigned long) pte); - - page = *pte; -#ifdef CONFIG_64BIT_PHYS_ADDR - printk("page == %08Lx\n", pte_val(page)); -#else - printk("page == %0*lx\n", width, pte_val(page)); -#endif - - val = pte_val(page); - if (val & _PAGE_PRESENT) printk("present "); - if (val & _PAGE_READ) printk("read "); - if (val & _PAGE_WRITE) printk("write "); - if (val & _PAGE_ACCESSED) printk("accessed "); - if (val & _PAGE_MODIFIED) printk("modified "); - if (val & _PAGE_R4KBUG) printk("r4kbug "); - if (val & _PAGE_GLOBAL) printk("global "); - if (val & _PAGE_VALID) printk("valid "); - printk("\n"); -} - -void dump_list_current(void *address) -{ - dump_list_process(current, address); -} - -unsigned long vtop(void *address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned long addr, paddr; - - addr = (unsigned long) address; - pgd = pgd_offset(current->mm, addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - pte = pte_offset(pmd, addr); - paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK; - paddr |= (addr & ~PAGE_MASK); - - return paddr; -} - -void dump16(unsigned long *p) -{ - int i; - - for (i = 0; i < 8; i++) { - printk("*%08lx == %08lx, ", (unsigned long)p, *p); - p++; - printk("*%08lx == %08lx\n", (unsigned long)p, *p); - p++; - } -} diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 4f2cb74f0766..52f87795ecc3 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c @@ -7,19 +7,14 @@ */ #include #include -#include -#include -#include -#include -#include #include #include #include extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */ -void dump_tlb(int first, int last) +static void dump_tlb(int first, int last) { int i; unsigned int asid; @@ -65,118 +60,3 @@ void dump_tlb_all(void) { dump_tlb(0, current_cpu_data.tlbsize - 1); } - -void dump_tlb_wired(void) -{ - int wired = r3k_have_wired_reg ? read_c0_wired() : 8; - - printk("Wired: %d", wired); - dump_tlb(0, wired - 1); -} - -void dump_tlb_addr(unsigned long addr) -{ - unsigned long flags, oldpid; - int index; - - local_irq_save(flags); - oldpid = read_c0_entryhi() & 0xff; - write_c0_entryhi((addr & PAGE_MASK) | oldpid); - tlb_probe(); - index = read_c0_index(); - write_c0_entryhi(oldpid); - local_irq_restore(flags); - - if (index < 0) { - printk("No entry for address 0x%08lx in TLB\n", addr); - return; - } - - printk("Entry %d maps address 0x%08lx\n", index, addr); - dump_tlb(index, index); -} - -void dump_tlb_nonwired(void) -{ - int wired = r3k_have_wired_reg ? read_c0_wired() : 8; - dump_tlb(wired, current_cpu_data.tlbsize - 1); -} - -void dump_list_process(struct task_struct *t, void *address) -{ - pgd_t *page_dir, *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte, page; - unsigned int addr; - unsigned long val; - - addr = (unsigned int) address; - - printk("Addr == %08x\n", addr); - printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); - - page_dir = pgd_offset(t->mm, 0); - printk("page_dir == %08x\n", (unsigned int) page_dir); - - pgd = pgd_offset(t->mm, addr); - printk("pgd == %08x, ", (unsigned int) pgd); - - pud = pud_offset(pgd, addr); - printk("pud == %08x, ", (unsigned int) pud); - - pmd = pmd_offset(pud, addr); - printk("pmd == %08x, ", (unsigned int) pmd); - - pte = pte_offset(pmd, addr); - printk("pte == %08x, ", (unsigned int) pte); - - page = *pte; - printk("page == %08x\n", (unsigned int) pte_val(page)); - - val = pte_val(page); - if (val & _PAGE_PRESENT) printk("present "); - if (val & _PAGE_READ) printk("read "); - if (val & _PAGE_WRITE) printk("write "); - if (val & _PAGE_ACCESSED) printk("accessed "); - if (val & _PAGE_MODIFIED) printk("modified "); - if (val & _PAGE_GLOBAL) printk("global "); - if (val & _PAGE_VALID) printk("valid "); - printk("\n"); -} - -void dump_list_current(void *address) -{ - dump_list_process(current, address); -} - -unsigned int vtop(void *address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned int addr, paddr; - - addr = (unsigned long) address; - pgd = pgd_offset(current->mm, addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - pte = pte_offset(pmd, addr); - paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK; - paddr |= (addr & ~PAGE_MASK); - - return paddr; -} - -void dump16(unsigned long *p) -{ - int i; - - for (i = 0; i < 8; i++) { - printk("*%08lx == %08lx, ", (unsigned long)p, *p); - p++; - printk("*%08lx == %08lx\n", (unsigned long)p, *p); - p++; - } -} diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c index ce907eda221b..123141ab21a2 100644 --- a/arch/mips/sgi-ip27/ip27-berr.c +++ b/arch/mips/sgi-ip27/ip27-berr.c @@ -21,7 +21,6 @@ #include #include -extern void dump_tlb_addr(unsigned long addr); extern void dump_tlb_all(void); static void dump_hub_information(unsigned long errst0, unsigned long errst1) From 09bb9ce15f6e0daba70b7e6978f233ffe2d356eb Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 4 Jun 2007 17:46:31 +0200 Subject: [PATCH 486/551] [MIPS] Allow generic spaces.h to be included by platform specific ones Before this patch, when a platform needed to customize one constant in spaces.h, they need to redefine all of them. Now they can just redefine one constant and include the generic file header at the end: #include This patch doesn't allow to redefine CAC_BASE, IO_BASE and UNCAC_BASE for 32 bits platforms because there's no need to do so. This will avoid some macro duplications. It's important specially if we'll add complex macros. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle delete mode 100644 include/asm-mips/mach-ip32/spaces.h --- include/asm-mips/mach-generic/spaces.h | 18 +++++++++++++ include/asm-mips/mach-ip22/spaces.h | 33 +++-------------------- include/asm-mips/mach-ip27/spaces.h | 9 ++----- include/asm-mips/mach-ip32/spaces.h | 36 -------------------------- 4 files changed, 23 insertions(+), 73 deletions(-) delete mode 100644 include/asm-mips/mach-ip32/spaces.h diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h index 0ae9997bc9a8..9a3c521047b8 100644 --- a/include/asm-mips/mach-generic/spaces.h +++ b/include/asm-mips/mach-generic/spaces.h @@ -16,13 +16,18 @@ #define CAC_BASE 0x80000000 #define IO_BASE 0xa0000000 #define UNCAC_BASE 0xa0000000 + +#ifndef MAP_BASE #define MAP_BASE 0xc0000000 +#endif /* * This handles the memory map. * We handle pages at KSEG0 for kernels with 32 bit address space. */ +#ifndef PAGE_OFFSET #define PAGE_OFFSET 0x80000000UL +#endif /* * Memory above this physical address will be considered highmem. @@ -38,11 +43,13 @@ /* * This handles the memory map. */ +#ifndef PAGE_OFFSET #ifdef CONFIG_DMA_NONCOHERENT #define PAGE_OFFSET 0x9800000000000000UL #else #define PAGE_OFFSET 0xa800000000000000UL #endif +#endif /* * Memory above this physical address will be considered highmem. @@ -53,14 +60,25 @@ #define HIGHMEM_START (1UL << 59UL) #endif +#ifndef CAC_BASE #ifdef CONFIG_DMA_NONCOHERENT #define CAC_BASE 0x9800000000000000UL #else #define CAC_BASE 0xa800000000000000UL #endif +#endif + +#ifndef IO_BASE #define IO_BASE 0x9000000000000000UL +#endif + +#ifndef UNCAC_BASE #define UNCAC_BASE 0x9000000000000000UL +#endif + +#ifndef MAP_BASE #define MAP_BASE 0xc000000000000000UL +#endif #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) #define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h index ab20c026fd19..7f9fa6f66059 100644 --- a/include/asm-mips/mach-ip22/spaces.h +++ b/include/asm-mips/mach-ip22/spaces.h @@ -11,44 +11,17 @@ #define _ASM_MACH_IP22_SPACES_H -#ifdef CONFIG_32BIT - -#define CAC_BASE 0x80000000 -#define IO_BASE 0xa0000000 -#define UNCAC_BASE 0xa0000000 -#define MAP_BASE 0xc0000000 - -/* - * This handles the memory map. - * We handle pages at KSEG0 for kernels with 32 bit address space. - */ -#define PAGE_OFFSET 0x80000000UL - -/* - * Memory above this physical address will be considered highmem. - */ -#ifndef HIGHMEM_START -#define HIGHMEM_START 0x20000000UL -#endif - -#endif /* CONFIG_32BIT */ - #ifdef CONFIG_64BIT -#define PAGE_OFFSET 0xffffffff80000000UL -#ifndef HIGHMEM_START -#define HIGHMEM_START (1UL << 59UL) -#endif +#define PAGE_OFFSET 0xffffffff80000000UL #define CAC_BASE 0xffffffff80000000 #define IO_BASE 0xffffffffa0000000 #define UNCAC_BASE 0xffffffffa0000000 #define MAP_BASE 0xc000000000000000 -#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) -#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) -#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) - #endif /* CONFIG_64BIT */ +#include + #endif /* __ASM_MACH_IP22_SPACES_H */ diff --git a/include/asm-mips/mach-ip27/spaces.h b/include/asm-mips/mach-ip27/spaces.h index 45e61785ef42..b18802a0b17e 100644 --- a/include/asm-mips/mach-ip27/spaces.h +++ b/include/asm-mips/mach-ip27/spaces.h @@ -14,22 +14,17 @@ * IP27 uses the R10000's uncached attribute feature. Attribute 3 selects * uncached memory addressing. */ -#define CAC_BASE 0xa800000000000000 #define HSPEC_BASE 0x9000000000000000 #define IO_BASE 0x9200000000000000 #define MSPEC_BASE 0x9400000000000000 #define UNCAC_BASE 0x9600000000000000 -#define MAP_BASE 0xc000000000000000 -#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) -#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) -#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) #define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK)) #define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK)) -#define PAGE_OFFSET CAC_BASE - #define HIGHMEM_START (~0UL) +#include + #endif /* _ASM_MACH_IP27_SPACES_H */ diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h deleted file mode 100644 index 44abe5c02389..000000000000 --- a/include/asm-mips/mach-ip32/spaces.h +++ /dev/null @@ -1,36 +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) 1994 - 1999, 2000, 03, 04, 05 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2000, 2002 Maciej W. Rozycki - * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. - */ -#ifndef _ASM_MACH_IP32_SPACES_H -#define _ASM_MACH_IP32_SPACES_H - -/* - * Memory above this physical address will be considered highmem. - * Fixme: 59 bits is a fictive number and makes assumptions about processors - * in the distant future. Nobody will care for a few years :-) - */ -#ifndef HIGHMEM_START -#define HIGHMEM_START (1UL << 59UL) -#endif - -#define CAC_BASE 0x9800000000000000UL -#define IO_BASE 0x9000000000000000UL -#define UNCAC_BASE 0x9000000000000000UL -#define MAP_BASE 0xc000000000000000UL - -#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) -#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) -#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) - -/* - * This handles the memory map. - */ -#define PAGE_OFFSET CAC_BASE - -#endif /* __ASM_MACH_IP32_SPACES_H */ From c4612c8596084c898628bd1898da5987ec43ac1d Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 4 Jun 2007 17:46:32 +0200 Subject: [PATCH 487/551] [MIPS] Clean up asm-mips/mach-generic/spaces.h PAGE_OFFSET definition is now using CAC_BASE by default. This patch also reorder some macros to make them appear in the same order for both 32 and 64 bits configs. It also makes use of const.h generic header file to annotate constants. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- include/asm-mips/mach-generic/spaces.h | 69 +++++++++++--------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h index 9a3c521047b8..d901e084a479 100644 --- a/include/asm-mips/mach-generic/spaces.h +++ b/include/asm-mips/mach-generic/spaces.h @@ -10,74 +10,56 @@ #ifndef _ASM_MACH_GENERIC_SPACES_H #define _ASM_MACH_GENERIC_SPACES_H +#include #ifdef CONFIG_32BIT -#define CAC_BASE 0x80000000 -#define IO_BASE 0xa0000000 -#define UNCAC_BASE 0xa0000000 +#define CAC_BASE _AC(0x80000000, UL) +#define IO_BASE _AC(0xa0000000, UL) +#define UNCAC_BASE _AC(0xa0000000, UL) #ifndef MAP_BASE -#define MAP_BASE 0xc0000000 -#endif - -/* - * This handles the memory map. - * We handle pages at KSEG0 for kernels with 32 bit address space. - */ -#ifndef PAGE_OFFSET -#define PAGE_OFFSET 0x80000000UL +#define MAP_BASE _AC(0xc0000000, UL) #endif /* * Memory above this physical address will be considered highmem. */ #ifndef HIGHMEM_START -#define HIGHMEM_START 0x20000000UL +#define HIGHMEM_START _AC(0x20000000, UL) #endif #endif /* CONFIG_32BIT */ #ifdef CONFIG_64BIT -/* - * This handles the memory map. - */ -#ifndef PAGE_OFFSET +#ifndef CAC_BASE #ifdef CONFIG_DMA_NONCOHERENT -#define PAGE_OFFSET 0x9800000000000000UL +#define CAC_BASE _AC(0x9800000000000000, UL) #else -#define PAGE_OFFSET 0xa800000000000000UL +#define CAC_BASE _AC(0xa800000000000000, UL) #endif #endif +#ifndef IO_BASE +#define IO_BASE _AC(0x9000000000000000, UL) +#endif + +#ifndef UNCAC_BASE +#define UNCAC_BASE _AC(0x9000000000000000, UL) +#endif + +#ifndef MAP_BASE +#define MAP_BASE _AC(0xc000000000000000, UL) +#endif + /* * Memory above this physical address will be considered highmem. * Fixme: 59 bits is a fictive number and makes assumptions about processors * in the distant future. Nobody will care for a few years :-) */ #ifndef HIGHMEM_START -#define HIGHMEM_START (1UL << 59UL) -#endif - -#ifndef CAC_BASE -#ifdef CONFIG_DMA_NONCOHERENT -#define CAC_BASE 0x9800000000000000UL -#else -#define CAC_BASE 0xa800000000000000UL -#endif -#endif - -#ifndef IO_BASE -#define IO_BASE 0x9000000000000000UL -#endif - -#ifndef UNCAC_BASE -#define UNCAC_BASE 0x9000000000000000UL -#endif - -#ifndef MAP_BASE -#define MAP_BASE 0xc000000000000000UL +#define HIGHMEM_START (_AC(1, UL) << _AC(59, UL)) #endif #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) @@ -86,4 +68,11 @@ #endif /* CONFIG_64BIT */ +/* + * This handles the memory map. + */ +#ifndef PAGE_OFFSET +#define PAGE_OFFSET CAC_BASE +#endif + #endif /* __ASM_MACH_GENERIC_SPACES_H */ From db38501511a7513ec4f0ae9922d847c135cf3c78 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 4 Jun 2007 17:46:33 +0200 Subject: [PATCH 488/551] [MIPS] Make PAGE_OFFSET aware of PHYS_OFFSET For platforms that use PHYS_OFFSET and do not use a mapped kernel, this patch automatically adds PHYS_OFFSET into PAGE_OFFSET. Therefore there are no more needs for them to redefine PAGE_OFFSET. For mapped kernel, they need to redefine PAGE_OFFSET anyways. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- include/asm-mips/mach-generic/spaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h index d901e084a479..f0571b651940 100644 --- a/include/asm-mips/mach-generic/spaces.h +++ b/include/asm-mips/mach-generic/spaces.h @@ -72,7 +72,7 @@ * This handles the memory map. */ #ifndef PAGE_OFFSET -#define PAGE_OFFSET CAC_BASE +#define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET) #endif #endif /* __ASM_MACH_GENERIC_SPACES_H */ From 41b0483ee54d89f9ad068ceae3c91cdc7594d050 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 4 Jun 2007 17:46:34 +0200 Subject: [PATCH 489/551] [MIPS] Move PHY_OFFSET definition in spaces.h Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- include/asm-mips/mach-generic/spaces.h | 7 +++++++ include/asm-mips/page.h | 11 ++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h index f0571b651940..c9fa4b14968d 100644 --- a/include/asm-mips/mach-generic/spaces.h +++ b/include/asm-mips/mach-generic/spaces.h @@ -12,6 +12,13 @@ #include +/* + * This gives the physical RAM offset. + */ +#ifndef PHYS_OFFSET +#define PHYS_OFFSET _AC(0, UL) +#endif + #ifdef CONFIG_32BIT #define CAC_BASE _AC(0x80000000, UL) diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 5c3239dad0f2..c56c6a85908d 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -34,12 +34,8 @@ #ifndef __ASSEMBLY__ -/* - * This gives the physical RAM offset. - */ -#ifndef PHYS_OFFSET -#define PHYS_OFFSET 0UL -#endif +#include +#include /* * It's normally defined only for FLATMEM config but it's @@ -48,9 +44,6 @@ */ #define ARCH_PFN_OFFSET PFN_UP(PHYS_OFFSET) -#include -#include - extern void clear_page(void * page); extern void copy_page(void * to, void * from); From b1c65b3988c6e29ac371ab1cbbf6c4f8fb7092f8 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 4 Jun 2007 17:46:35 +0200 Subject: [PATCH 490/551] [MIPS] Fix PHYS_OFFSET for 64-bits kernels with 32-bits symbols The current implementation of __pa() for 64-bits kernels with 32-bits symbols is broken. In this configuration, we need 2 values for PAGE_OFFSET, one in XKPHYS and the other in CKSEG0 space. When the value in CKSEG0 space is used, it doesn't take into account of PHYS_OFFSET. Even worse we can't redefine this value. The patch restores CPHYSADDR() but in __pa()'s implementation because it removes the need of 2 PAGE_OFFSET. OTOH, CPHYSADDR() is quite bad when dealing with mapped kernels. So this patch assumes there's no need to deal with such kernel in 64-bits world. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- include/asm-mips/page.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index c56c6a85908d..b92dd8c760da 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -35,7 +35,7 @@ #ifndef __ASSEMBLY__ #include -#include +#include /* * It's normally defined only for FLATMEM config but it's @@ -143,11 +143,15 @@ typedef struct { unsigned long pgprot; } pgprot_t; * __pa()/__va() should be used only during mem init. */ #if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) -#define __pa_page_offset(x) ((unsigned long)(x) < CKSEG0 ? PAGE_OFFSET : CKSEG0) +#define __pa(x) \ +({ \ + unsigned long __x = (unsigned long)(x); \ + __x < CKSEG0 ? XPHYSADDR(__x) : CPHYSADDR(__x); \ +}) #else -#define __pa_page_offset(x) PAGE_OFFSET +#define __pa(x) \ + ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) #endif -#define __pa(x) ((unsigned long)(x) - __pa_page_offset(x) + PHYS_OFFSET) #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) From c66df567e596bd43d6d3e094d82f82951e1b17cd Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sat, 2 Jun 2007 02:12:41 +0900 Subject: [PATCH 491/551] [MIPS] update cobalt_defconfig Enable Cobalt button support and change ATA driver from BLK_DEV_VIA82CXXX to PATA_VIA.. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/configs/cobalt_defconfig | 494 +++++++++++++---------------- 1 file changed, 226 insertions(+), 268 deletions(-) diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 631b2138ad68..c1186005358e 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -1,27 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc7 -# Wed Apr 18 14:25:45 2007 +# Linux kernel version: 2.6.22-rc2 +# Fri May 25 11:17:29 2007 # CONFIG_MIPS=y # # Machine selection # -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MACH_ALCHEMY is not set # CONFIG_BASLER_EXCITE is not set CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set @@ -33,12 +20,9 @@ CONFIG_MIPS_COBALT=y # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_C is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set @@ -138,7 +122,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 +CONFIG_ZONE_DMA_FLAG=0 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set @@ -178,6 +162,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y # CONFIG_BLK_DEV_INITRD is not set @@ -193,14 +178,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -233,16 +223,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +# CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -268,7 +255,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -300,11 +286,11 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -345,13 +331,16 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -CONFIG_IEEE80211=y -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=y -CONFIG_IEEE80211_CRYPT_CCMP=y -CONFIG_IEEE80211_SOFTMAC=y -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -370,10 +359,6 @@ CONFIG_FW_LOADER=y # CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -418,7 +403,6 @@ CONFIG_MTD_CFI_UTIL=y # 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 @@ -445,16 +429,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0 # 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 +# CONFIG_MTD_ONENAND is not set # -# OneNAND Flash Device Drivers +# UBI - Unsorted block images # -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_UBI is not set # # Parallel port support @@ -479,87 +460,145 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_CDROM_PKTCDVD=y -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # # Misc devices # -CONFIG_SGI_IOC4=y +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -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_IDECD is not set -# 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_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -CONFIG_BLK_DEV_IT8213=y -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -CONFIG_BLK_DEV_TC86C001=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLINK is not set +# CONFIG_IDE is not set # # SCSI device support # CONFIG_RAID_ATTRS=y -# CONFIG_SCSI is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y # -# Serial ATA (prod) and Parallel ATA (experimental) drivers +# SCSI support type (disk, tape, CD-ROM) # -# CONFIG_ATA is not set +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +CONFIG_PATA_VIA=y +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set # # Multi-device support (RAID and LVM) @@ -570,10 +609,14 @@ CONFIG_RAID_ATTRS=y # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -594,24 +637,7 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -639,35 +665,8 @@ CONFIG_TULIP=y # CONFIG_ULI526X is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_QLA3XXX=y -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=y -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # # Token Ring devices @@ -675,18 +674,16 @@ CONFIG_NETXEN_NIC=y # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set +# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -711,10 +708,7 @@ 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_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set @@ -726,18 +720,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_PCSPKR is not set +CONFIG_INPUT_COBALT_BTNS=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_POLLDEV=y # # Hardware I/O ports # -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=y +# CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set # @@ -754,7 +753,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -773,16 +772,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set CONFIG_COBALT_LCD=y -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set @@ -792,10 +786,7 @@ CONFIG_COBALT_LCD=y # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -808,12 +799,7 @@ CONFIG_COBALT_LCD=y # Dallas's 1-wire bus # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # # Multifunction device drivers @@ -824,16 +810,19 @@ CONFIG_COBALT_LCD=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # # Graphics support # # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set # CONFIG_FB is not set # @@ -868,10 +857,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -912,17 +897,29 @@ CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set # -# RTC drivers +# I2C RTC drivers +# + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_V3020 is not set +# +# on-CPU RTC drivers +# + # # DMA Engine support # @@ -936,14 +933,6 @@ CONFIG_RTC_DRV_CMOS=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -952,8 +941,13 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y # CONFIG_EXT4DEV_FS 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 @@ -969,7 +963,7 @@ CONFIG_INOTIFY_USER=y CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y +# CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y # @@ -1003,7 +997,6 @@ CONFIG_CONFIGFS_FS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set @@ -1021,13 +1014,23 @@ CONFIG_CONFIGFS_FS=y # Network File Systems # CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1051,10 +1054,7 @@ CONFIG_MSDOS_PARTITION=y # # Distributed Lock Manager # -CONFIG_DLM=y -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set +# CONFIG_DLM is not set # # Profiling support @@ -1072,72 +1072,30 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" # # Security options # -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # # Cryptographic options # -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_TGR192=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_KHAZAD=y -CONFIG_CRYPTO_ANUBIS=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CAMELLIA=y - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO is not set # # Library routines # CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y From b63e804459b9b550c1ab21a43e6bac2272e32612 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 5 Jun 2007 01:28:07 +0900 Subject: [PATCH 492/551] [MIPS] Remove unused watchpoint support and arch/mips/lib-{32,64} Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 2 -- arch/mips/kernel/proc.c | 1 - arch/mips/kernel/traps.c | 1 - arch/mips/lib-32/Makefile | 5 ---- arch/mips/lib-32/watch.S | 60 --------------------------------------- arch/mips/lib-64/Makefile | 5 ---- arch/mips/lib-64/watch.S | 57 ------------------------------------- include/asm-mips/watch.h | 35 ----------------------- 8 files changed, 166 deletions(-) delete mode 100644 arch/mips/lib-32/Makefile delete mode 100644 arch/mips/lib-32/watch.S delete mode 100644 arch/mips/lib-64/Makefile delete mode 100644 arch/mips/lib-64/watch.S delete mode 100644 include/asm-mips/watch.h diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 077eb0bd1c78..12e24146a06c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -633,8 +633,6 @@ CPPFLAGS_vmlinux.lds := \ head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o libs-y += arch/mips/lib/ -libs-$(CONFIG_32BIT) += arch/mips/lib-32/ -libs-$(CONFIG_64BIT) += arch/mips/lib-64/ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 5ddc2e9deecf..eb7730d67934 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -14,7 +14,6 @@ #include #include #include -#include unsigned int vced_count, vcei_count; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 20bdbe48839b..7e9cb5b1b4a7 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile deleted file mode 100644 index 7bae849e544a..000000000000 --- a/arch/mips/lib-32/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for MIPS-specific library files.. -# - -lib-y += watch.o diff --git a/arch/mips/lib-32/watch.S b/arch/mips/lib-32/watch.S deleted file mode 100644 index 808b3af1a605..000000000000 --- a/arch/mips/lib-32/watch.S +++ /dev/null @@ -1,60 +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. - * - * Kernel debug stuff to use the Watch registers. - * Useful to find stack overflows, dangling pointers etc. - * - * Copyright (C) 1995, 1996, 1999 by Ralf Baechle - */ -#include -#include -#include - - .set noreorder -/* - * Parameter: a0 - logic address to watch - * Currently only KSEG0 addresses are allowed! - * a1 - set bit #1 to trap on load references - * bit #0 to trap on store references - * Results : none - */ - LEAF(__watch_set) - li t0, 0x80000000 - subu a0, t0 - ori a0, 7 - xori a0, 7 - or a0, a1 - mtc0 a0, CP0_WATCHLO - sw a0, watch_savelo - - jr ra - mtc0 zero, CP0_WATCHHI - END(__watch_set) - -/* - * Parameter: none - * Results : none - */ - LEAF(__watch_clear) - jr ra - mtc0 zero, CP0_WATCHLO - END(__watch_clear) - -/* - * Parameter: none - * Results : none - */ - LEAF(__watch_reenable) - lw t0, watch_savelo - jr ra - mtc0 t0, CP0_WATCHLO - END(__watch_reenable) - -/* - * Saved value of the c0_watchlo register for watch_reenable() - */ - .data -watch_savelo: .word 0 - .text diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile deleted file mode 100644 index 7bae849e544a..000000000000 --- a/arch/mips/lib-64/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for MIPS-specific library files.. -# - -lib-y += watch.o diff --git a/arch/mips/lib-64/watch.S b/arch/mips/lib-64/watch.S deleted file mode 100644 index f91434013695..000000000000 --- a/arch/mips/lib-64/watch.S +++ /dev/null @@ -1,57 +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. - * - * Kernel debug stuff to use the Watch registers. - * Useful to find stack overflows, dangling pointers etc. - * - * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle - */ -#include -#include -#include - - .set noreorder -/* - * Parameter: a0 - physical address to watch - * a1 - set bit #1 to trap on load references - * bit #0 to trap on store references - * Results : none - */ - LEAF(__watch_set) - ori a0, 7 - xori a0, 7 - or a0, a1 - mtc0 a0, CP0_WATCHLO - sd a0, watch_savelo - dsrl32 a0, a0, 0 - - jr ra - mtc0 zero, CP0_WATCHHI - END(__watch_set) - -/* - * Parameter: none - * Results : none - */ - LEAF(__watch_clear) - jr ra - mtc0 zero, CP0_WATCHLO - END(__watch_clear) - -/* - * Parameter: none - * Results : none - */ - LEAF(__watch_reenable) - ld t0, watch_savelo - jr ra - mtc0 t0, CP0_WATCHLO - END(__watch_reenable) - -/* - * Saved value of the c0_watchlo register for watch_reenable() - */ - .local watch_savelo - .comm watch_savelo, 8, 8 diff --git a/include/asm-mips/watch.h b/include/asm-mips/watch.h deleted file mode 100644 index 6aa90cae1114..000000000000 --- a/include/asm-mips/watch.h +++ /dev/null @@ -1,35 +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) 1996, 1997, 1998, 2000, 2001 by Ralf Baechle - */ -#ifndef _ASM_WATCH_H -#define _ASM_WATCH_H - -#include - -/* - * Types of reference for watch_set() - */ -enum wref_type { - wr_save = 1, - wr_load = 2 -}; - -extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref); -extern asmlinkage void __watch_clear(void); -extern asmlinkage void __watch_reenable(void); - -#define watch_set(addr, ref) \ - if (cpu_has_watch) \ - __watch_set(addr, ref) -#define watch_clear() \ - if (cpu_has_watch) \ - __watch_clear() -#define watch_reenable() \ - if (cpu_has_watch) \ - __watch_reenable() - -#endif /* _ASM_WATCH_H */ From d388d6853f1b584b8606cb3f2f9f9e4fa2e52258 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 29 May 2007 15:08:07 +0100 Subject: [PATCH 493/551] [MIPS] No I/O ports on the DECstation There are no I/O ports on the DECstation whatsoever in any configuration as neither the CPU nor the peripheral buses used have a concept of such. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 734b61f663b7..7080e7117f41 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -63,6 +63,7 @@ config MACH_DECSTATION bool "DECstations" select BOOT_ELF32 select DMA_NONCOHERENT + select NO_IOPORT select SYS_HAS_EARLY_PRINTK select IRQ_CPU select SYS_HAS_CPU_R3000 @@ -775,6 +776,9 @@ config MIPS_NILE4 config MIPS_DISABLE_OBSOLETE_IDE bool +config NO_IOPORT + def_bool n + config GENERIC_ISA_DMA_SUPPORT_BROKEN bool select ZONE_DMA From 36de48de85bdb9bc8c35c1eb513737c187d70a46 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 5 Jun 2007 11:45:07 +0100 Subject: [PATCH 494/551] [MIPS] DECstation: Optimised early printk() This is an optimised implementation of early printk() for the DECstation. After the recent conversion to a MIPS-specific generic routine using a character-by-character output the performance dropped significantly. This change reverts to the previous speed -- even at 9600 bps of the serial console the difference is visible with a naked eye; I presume for a framebuffer it is even worse (it may depend on exactly which one is used though). Additionally the change includes a fix for a problem that the old implementation had -- the format used would not actually limit the length of the string output. This new implementation uses a local buffer to deal with it -- even with this additional copying it is much faster than the generic function. Plus this driver is registered much earlier than the generic one, allowing one to see critical messages, such as one about an incorrect CPU setting used, that are produced beforehand. :-) Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 - arch/mips/dec/prom/console.c | 34 +++++++++++++++++++++++++++------- arch/mips/dec/prom/init.c | 3 +++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7080e7117f41..beff10528797 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -64,7 +64,6 @@ config MACH_DECSTATION select BOOT_ELF32 select DMA_NONCOHERENT select NO_IOPORT - select SYS_HAS_EARLY_PRINTK select IRQ_CPU select SYS_HAS_CPU_R3000 select SYS_HAS_CPU_R4X00 diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c index 65419bf32441..078e1a12421d 100644 --- a/arch/mips/dec/prom/console.c +++ b/arch/mips/dec/prom/console.c @@ -3,7 +3,7 @@ * * DECstation PROM-based early console support. * - * Copyright (C) 2004 Maciej W. Rozycki + * Copyright (C) 2004, 2007 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -13,15 +13,35 @@ #include #include #include +#include #include -void prom_putchar(char c) +static void __init prom_console_write(struct console *con, const char *s, + unsigned int c) { - char s[2]; + char buf[81]; + unsigned int chunk = sizeof(buf) - 1; - s[0] = c; - s[1] = '\0'; - - prom_printf( s); + while (c > 0) { + if (chunk > c) + chunk = c; + memcpy(buf, s, chunk); + buf[chunk] = '\0'; + prom_printf("%s", buf); + s += chunk; + c -= chunk; + } +} + +static struct console promcons __initdata = { + .name = "prom", + .write = prom_console_write, + .flags = CON_BOOT | CON_PRINTBUFFER, + .index = -1, +}; + +void __init register_prom_console(void) +{ + register_console(&promcons); } diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c index 4828cac4748f..808c182fd3fa 100644 --- a/arch/mips/dec/prom/init.c +++ b/arch/mips/dec/prom/init.c @@ -103,6 +103,9 @@ void __init prom_init(void) if (prom_is_rex(magic)) rex_clear_cache(); + /* Register the early console. */ + register_prom_console(); + /* Were we compiled with the right CPU option? */ #if defined(CONFIG_CPU_R3000) if ((current_cpu_data.cputype == CPU_R4000SC) || From 6b5bf509317c013ea0a7c166affc1d4631720d85 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 21 Jun 2007 15:06:21 +0900 Subject: [PATCH 495/551] [MIPS] EV64120: Remove support Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 31 +- arch/mips/Makefile | 8 - arch/mips/configs/atlas_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/ddb5477_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/ev64120_defconfig | 985 ------------------- arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/lasat200_defconfig | 1 - arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/ocelot_3_defconfig | 1 - arch/mips/configs/ocelot_c_defconfig | 1 - arch/mips/configs/ocelot_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/qemu_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 1 - arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/defconfig | 1 - arch/mips/gt64120/ev64120/Kconfig | 3 - arch/mips/gt64120/ev64120/Makefile | 9 - arch/mips/gt64120/ev64120/irq.c | 116 --- arch/mips/gt64120/ev64120/promcon.c | 48 - arch/mips/gt64120/ev64120/reset.c | 45 - arch/mips/gt64120/ev64120/serialGT.c | 212 ---- arch/mips/gt64120/ev64120/setup.c | 99 -- arch/mips/pci/Makefile | 1 - arch/mips/pci/pci-ev64120.c | 22 - include/asm-mips/bootinfo.h | 6 - include/asm-mips/mach-ev64120/mach-gt64120.h | 62 -- include/asm-mips/serial.h | 19 - 59 files changed, 2 insertions(+), 1708 deletions(-) delete mode 100644 arch/mips/configs/ev64120_defconfig delete mode 100644 arch/mips/gt64120/ev64120/Kconfig delete mode 100644 arch/mips/gt64120/ev64120/Makefile delete mode 100644 arch/mips/gt64120/ev64120/irq.c delete mode 100644 arch/mips/gt64120/ev64120/promcon.c delete mode 100644 arch/mips/gt64120/ev64120/reset.c delete mode 100644 arch/mips/gt64120/ev64120/serialGT.c delete mode 100644 arch/mips/gt64120/ev64120/setup.c delete mode 100644 arch/mips/pci/pci-ev64120.c delete mode 100644 include/asm-mips/mach-ev64120/mach-gt64120.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index beff10528797..8750e611ef59 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -88,24 +88,6 @@ config MACH_DECSTATION otherwise choose R3000. -config MIPS_EV64120 - bool "Galileo EV64120 Evaluation board (EXPERIMENTAL)" - depends on EXPERIMENTAL - select DMA_NONCOHERENT - select HW_HAS_PCI - select PCI_GT64XXX_PCI0 - select SYS_HAS_CPU_R5000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_KGDB - help - This is an evaluation board based on the Galileo GT-64120 - single-chip system controller that contains a MIPS R5000 compatible - core running at 75/100MHz. Their website is located at - . Say Y here if you wish to build a - kernel for this platform. - config MACH_JAZZ bool "Jazz family of machines" select ARC @@ -661,7 +643,6 @@ endchoice source "arch/mips/au1000/Kconfig" source "arch/mips/ddb5xxx/Kconfig" -source "arch/mips/gt64120/ev64120/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" @@ -884,19 +865,11 @@ config SERIAL_RM9000 # choice prompt "Galileo Chip Clock" - #default SYSCLK_83 if MIPS_EV64120 - depends on MIPS_EV64120 || MOMENCO_OCELOT - default SYSCLK_83 if MIPS_EV64120 + depends on MOMENCO_OCELOT default SYSCLK_100 if MOMENCO_OCELOT -config SYSCLK_75 - bool "75" if MIPS_EV64120 - -config SYSCLK_83 - bool "83.3" if MIPS_EV64120 - config SYSCLK_100 - bool "100" if MIPS_EV64120 || MOMENCO_OCELOT + bool "100" if MOMENCO_OCELOT endchoice diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 12e24146a06c..ddb048b8600a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -282,14 +282,6 @@ libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/ load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000 CLEAN_FILES += drivers/tc/lk201-map.c -# -# Galileo EV64120 Board -# -core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/ev64120/ -core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/common/ -cflags-$(CONFIG_MIPS_EV64120) += -Iinclude/asm-mips/mach-ev64120 -load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000 - # # Wind River PPMC Board (4KC + GT64120) # diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 39e251300c64..99c54f3da36a 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set CONFIG_MIPS_ATLAS=y diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 4713a13211ce..c885e4fc4e41 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 5e7ae56b1f3c..a5ebedc1d1de 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index c1186005358e..c70456ede3d5 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -12,7 +12,6 @@ CONFIG_MIPS=y # CONFIG_BASLER_EXCITE is not set CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 10f6af43753d..87e99e5ca84d 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 4b0862927748..5d46a9982832 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 820659e810dc..e6f4242268fb 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 4050b9b91bcb..ea5609339146 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index 7b3519058ab8..2728a0018b58 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 5b502a2013fb..d67f15009efa 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 4bbdab078ff1..25e533667504 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index b5714a6a5398..1257a7016c44 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index 2e3e155b4c55..9318fce31732 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig deleted file mode 100644 index c10e4e063226..000000000000 --- a/arch/mips/configs/ev64120_defconfig +++ /dev/null @@ -1,985 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:30 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -CONFIG_MIPS_EV64120=y -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_EVB_PCI1 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_MIPS_GT64120=y -# CONFIG_SYSCLK_75 is not set -# CONFIG_SYSCLK_83 is not set -CONFIG_SYSCLK_100=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -CONFIG_CPU_R5000=y -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R5000=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -# CONFIG_KMOD is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -# CONFIG_PACKET is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_QLA3XXX=m -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPP_MPPE=m -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=y -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_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=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=m -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM 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_HW_RANDOM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -# CONFIG_HID is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m - -# -# 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_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_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_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::" -CONFIG_SYS_SUPPORTS_KGDB=y - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=m -CONFIG_CRC_CCITT=y -CONFIG_CRC16=m -CONFIG_CRC32=m -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 460d7a26a8ba..e35a8f58c071 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -26,7 +26,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_BASLER_EXCITE_PROTOTYPE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 7ec618f3c8b9..c655d4da0c68 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 9ddc3eff4793..a2475e7e909d 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 8fc18809d5ff..f95d5fef3a0b 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 9331cb0a19b1..e2f5a5a41792 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set CONFIG_MACH_JAZZ=y # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 1b364cf69140..2c88b3295af4 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index fd4272c1458a..ccf7227cbf98 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set CONFIG_LASAT=y # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1f64d7632a03..1c839cf29d86 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index a2db5c201216..559f4d0038b0 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index ad5c0bf87b2b..811ada95d729 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index 28547313ce13..a53175a109e7 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index 82ff6fc0cd41..38e86f16f856 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 15a027e00eec..f5948e56b848 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 37d696c64541..e764285aac62 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index b11f0e8b6059..37e2a102f6e2 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 2927f38f4907..b1206a20e7e0 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -26,7 +26,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index fae16c5ec521..e7096449ba26 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index cd821e52181d..a46761f56a12 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index 8e8d03157954..93f382b32179 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index 35d64260917e..dbb485d499a5 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -24,7 +24,6 @@ CONFIG_MIPS=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 41011f770a67..c7c28a1616b2 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 5593cde9f74c..f3ee7e179f24 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 6c4f09a381e2..11f034764812 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index 988b9cdef01f..0d055b2d1510 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index 8b1675c07ec4..a0cda222254f 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index b5be8b74d896..9b0a1d59eddd 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 8bb6be4342b6..f8f11dcbb8de 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index 8f019ffcc71b..8558348cad3b 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 52b48c0715d3..01b05b2a497a 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 6824606309e5..3d40e7c1277b 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 41211f8b7738..195311dfeae6 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig deleted file mode 100644 index d691762cb0f7..000000000000 --- a/arch/mips/gt64120/ev64120/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config EVB_PCI1 - bool "Enable Second PCI (PCI1)" - depends on MIPS_EV64120 diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile deleted file mode 100644 index 323b2cebc691..000000000000 --- a/arch/mips/gt64120/ev64120/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright 2000 RidgeRun, Inc. -# Author: RidgeRun, Inc. -# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com -# -# Makefile for the Galileo EV64120 board. -# - -obj-y += irq.o promcon.o reset.o serialGT.o setup.o diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c deleted file mode 100644 index 64e4c80b6139..000000000000 --- a/arch/mips/gt64120/ev64120/irq.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Code to handle irqs on GT64120A boards - * Derived from mips/orion and Cort - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ - do_IRQ(4); - else if (pending & STATUSF_IP2) /* int0 hardware line */ - do_IRQ(GT_INTA); - else if (pending & STATUSF_IP5) /* int3 hardware line */ - do_IRQ(GT_INTD); - else if (pending & STATUSF_IP6) /* int4 hardware line */ - do_IRQ(6); - else if (pending & STATUSF_IP7) /* compare int */ - do_IRQ(7); - else - spurious_interrupt(); -} - -static void disable_ev64120_irq(unsigned int irq_nr) -{ - if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 - clear_c0_status(9 << 10); - } else { - clear_c0_status(1 << (irq_nr + 8)); - } -} - -static void enable_ev64120_irq(unsigned int irq_nr) -{ - if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2 - set_c0_status(9 << 10); - else - set_c0_status(1 << (irq_nr + 8)); -} - -static void end_ev64120_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_ev64120_irq(irq); -} - -static struct irq_chip ev64120_irq_type = { - .name = "EV64120", - .ack = disable_ev64120_irq, - .mask = disable_ev64120_irq, - .mask_ack = disable_ev64120_irq, - .unmask = enable_ev64120_irq, - .end = end_ev64120_irq, -}; - -void gt64120_irq_setup(void) -{ - /* - * Clear all of the interrupts while we change the able around a bit. - */ - clear_c0_status(ST0_IM); - - /* - * Enable timer. Other interrupts will be enabled as they are - * registered. - */ - set_c0_status(IE_IRQ2); -} - -void __init arch_init_irq(void) -{ - gt64120_irq_setup(); -} diff --git a/arch/mips/gt64120/ev64120/promcon.c b/arch/mips/gt64120/ev64120/promcon.c deleted file mode 100644 index 6e0ecfed9640..000000000000 --- a/arch/mips/gt64120/ev64120/promcon.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Wrap-around code for a console using the - * SGI PROM io-routines. - * - * Copyright (c) 1999 Ulf Carlsson - * - * Derived from DECstation promcon.c - * Copyright (c) 1998 Harald Koerfgen - */ -#include -#include -#include - -static void prom_console_write(struct console *co, const char *s, - unsigned count) -{ - extern int CONSOLE_CHANNEL; // The default serial port - unsigned i; - - for (i = 0; i < count; i++) { - if (*s == 10) - serial_putc(CONSOLE_CHANNEL, 13); - serial_putc(CONSOLE_CHANNEL, *s++); - } -} - -static struct console sercons = { - .name = "ttyS", - .write = prom_console_write, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ - -static int gal_serial_console_init(void) -{ - // serial_init(); - //serial_set(115200); - - register_console(&sercons); - - return 0; -} - -console_initcall(gal_serial_console_init); diff --git a/arch/mips/gt64120/ev64120/reset.c b/arch/mips/gt64120/ev64120/reset.c deleted file mode 100644 index 7b9f5e5bf21f..000000000000 --- a/arch/mips/gt64120/ev64120/reset.c +++ /dev/null @@ -1,45 +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) 1997 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include - -void galileo_machine_restart(char *command) -{ - *(volatile char *) 0xbc000000 = 0x0f; - /* - * Ouch, we're still alive ... This time we take the silver bullet ... - * ... and find that we leave the hardware in a state in which the - * kernel in the flush locks up somewhen during of after the PCI - * detection stuff. - */ - set_c0_status(ST0_BEV | ST0_ERL); - change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_c0_wired(0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -void galileo_machine_halt(void) -{ - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); - -} - -void galileo_machine_power_off(void) -{ - galileo_machine_halt(); -} diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c deleted file mode 100644 index 8f0d835491ff..000000000000 --- a/arch/mips/gt64120/ev64120/serialGT.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * serialGT.c - * - * BRIEF MODULE DESCRIPTION - * Low Level Serial Port control for use - * with the Galileo EVB64120A MIPS eval board and - * its on board two channel 16552 Uart. - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -// Note: -// Serial CHANNELS - 0 is the bottom connector of evb64120A. -// (The one that maps to the "B" channel of the -// board's uart) -// 1 is the top connector of evb64120A. -// (The one that maps to the "A" channel of the -// board's uart) -int DEBUG_CHANNEL = 0; // See Note Above -int CONSOLE_CHANNEL = 1; // See Note Above - -#define DUART 0xBD000000 /* Base address of Uart. */ -#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA - register set of the 16552 Uart device. - DUART+0 gets you to the ChanB register set. - */ -#define DUART_DELTA 0x4 -#define FIFO_ENABLE 0x07 -#define INT_ENABLE 0x04 /* default interrupt mask */ - -#define RBR 0x00 -#define THR 0x00 -#define DLL 0x00 -#define IER 0x01 -#define DLM 0x01 -#define IIR 0x02 -#define FCR 0x02 -#define LCR 0x03 -#define MCR 0x04 -#define LSR 0x05 -#define MSR 0x06 -#define SCR 0x07 - -#define LCR_DLAB 0x80 -#define XTAL 1843200 -#define LSR_THRE 0x20 -#define LSR_BI 0x10 -#define LSR_DR 0x01 -#define MCR_LOOP 0x10 -#define ACCESS_DELAY 0x10000 - -/****************************** - Routine: - Description: - ******************************/ -int inreg(int channel, int reg) -{ - int val; - val = - *((volatile unsigned char *) DUART + - (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); - return val; -} - -/****************************** - Routine: - Description: - ******************************/ -void outreg(int channel, int reg, unsigned char val) -{ - *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) - + (reg * DUART_DELTA)) = val; -} - -/****************************** - Routine: - Description: - Initialize the device driver. - ******************************/ -void serial_init(int channel) -{ - /* - * Configure active port, (CHANNELOFFSET already set.) - * - * Set 8 bits, 1 stop bit, no parity. - * - * LCR<7> 0 divisor latch access bit - * LCR<6> 0 break control (1=send break) - * LCR<5> 0 stick parity (0=space, 1=mark) - * LCR<4> 0 parity even (0=odd, 1=even) - * LCR<3> 0 parity enable (1=enabled) - * LCR<2> 0 # stop bits (0=1, 1=1.5) - * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) - */ - outreg(channel, LCR, 0x3); - - outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ - - outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ -} - -/****************************** - Routine: - Description: - Set the baud rate. - ******************************/ -void serial_set(int channel, unsigned long baud) -{ - unsigned char sav_lcr; - - /* - * Enable access to the divisor latches by setting DLAB in LCR. - * - */ - sav_lcr = inreg(channel, LCR); - -#if 0 - /* - * Set baud rate - */ - outreg(channel, LCR, LCR_DLAB | sav_lcr); - // outreg(DLL,(XTAL/(16*2*(baud))-2)); - outreg(channel, DLL, XTAL / (16 * baud)); - // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); - outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); -#else - /* - * Note: Set baud rate, hardcoded here for rate of 115200 - * since became unsure of above "baud rate" algorithm (??). - */ - outreg(channel, LCR, 0x83); - outreg(channel, DLM, 0x00); // See note above - outreg(channel, DLL, 0x02); // See note above. - outreg(channel, LCR, 0x03); -#endif - - /* - * Restore line control register - */ - outreg(channel, LCR, sav_lcr); -} - - -/****************************** - Routine: - Description: - Transmit a character. - ******************************/ -void serial_putc(int channel, int c) -{ - while ((inreg(channel, LSR) & LSR_THRE) == 0); - outreg(channel, THR, c); -} - -/****************************** - Routine: - Description: - Read a received character if one is - available. Return -1 otherwise. - ******************************/ -int serial_getc(int channel) -{ - if (inreg(channel, LSR) & LSR_DR) { - return inreg(channel, RBR); - } - return -1; -} - -/****************************** - Routine: - Description: - Used by embedded gdb client. (example; gdb-stub.c) - ******************************/ -char getDebugChar() -{ - int val; - while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. - return (char) val; -} - -/****************************** - Routine: - Description: - Used by embedded gdb target. (example; gdb-stub.c) - ******************************/ -void putDebugChar(char c) -{ - serial_putc(DEBUG_CHANNEL, (int) c); -} diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c deleted file mode 100644 index 477848c22a2c..000000000000 --- a/arch/mips/gt64120/ev64120/setup.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -unsigned long gt64120_base = KSEG1ADDR(0x14000000); - -/* These functions are used for rebooting or halting the machine*/ -extern void galileo_machine_restart(char *command); -extern void galileo_machine_halt(void); -extern void galileo_machine_power_off(void); -/* - *This structure holds pointers to the pci configuration space accesses - *and interrupts allocating routine for device over the PCI - */ -extern struct pci_ops galileo_pci_ops; - -void __init prom_free_prom_memory(void) -{ -} - -/* - * Initializes basic routines and structures pointers, memory size (as - * given by the bios and saves the command line. - */ - -void __init plat_mem_setup(void) -{ - _machine_restart = galileo_machine_restart; - _machine_halt = galileo_machine_halt; - pm_power_off = galileo_machine_power_off; - - set_io_port_base(KSEG1); -} - -const char *get_system_type(void) -{ - return "Galileo EV64120A"; -} - -/* - * Kernel arguments passed by the firmware - * - * $a0 - nothing - * $a1 - holds a pointer to the eprom parameters - * $a2 - nothing - */ - -void __init prom_init(void) -{ - mips_machgroup = MACH_GROUP_GALILEO; - mips_machtype = MACH_EV64120A; - - add_memory_region(0, 32 << 20, BOOT_MEM_RAM); -} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index aba3dbf47eda..3ff56b84add0 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o -obj-$(CONFIG_MIPS_EV64120) += pci-ev64120.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c deleted file mode 100644 index a84f594b5a18..000000000000 --- a/arch/mips/pci/pci-ev64120.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (!pin) - return 0; - - irq = allocate_irqno(); - if (irq < 0) - return 0; - - return irq; -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index b0c329783ac5..476563924fd1 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -108,12 +108,6 @@ #define MACH_GROUP_COSINE 10 /* CoSine Orion */ #define MACH_COSINE_ORION 0 -/* - * Valid machtype for group GALILEO - */ -#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ -#define MACH_EV64120A 0 /* EV64120A */ - /* * Valid machtype for group MOMENCO */ diff --git a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h deleted file mode 100644 index 7e272ce57ea3..000000000000 --- a/include/asm-mips/mach-ev64120/mach-gt64120.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global - * search and replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef __ASM_GALILEO_BOARDS_MIPS_EV64120_H -#define __ASM_GALILEO_BOARDS_MIPS_EV64120_H - -/* - * GT64120 config space base address - */ -extern unsigned long gt64120_base; - -#define GT64120_BASE (gt64120_base) - -/* - * PCI Bus allocation - */ -#define GT_PCI_MEM_BASE 0x12000000UL -#define GT_PCI_MEM_SIZE 0x02000000UL -#define GT_PCI_IO_BASE 0x10000000UL -#define GT_PCI_IO_SIZE 0x02000000UL -#define GT_ISA_IO_BASE PCI_IO_BASE - -/* - * Duart I/O ports. - */ -#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20) -#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00) - - -/* - * EV64120 interrupt controller register base. - */ -#define EV64120_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) - -/* - * EV64120 UART register base. - */ -#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR)) -#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR)) -#define EV64120_BASE_BAUD ( 3686400 / 16 ) -#define EV64120_UART_IRQ 6 - -/* - * PCI interrupts will come in on either the INTA or INTD interrups lines, - * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our - * boards, they all either come in on IntD or they all come in on IntA, they - * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the - * "requested" interrupt numbers and go through the list whenever we get an - * IntA/D. - * - * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and - * INTD is 11. - */ -#define GT_TIMER 4 -#define GT_INTA 2 -#define GT_INTD 5 - -#endif /* __ASM_GALILEO_BOARDS_MIPS_EV64120_H */ diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index ce51213d84f9..01f1a8213ccc 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -51,24 +51,6 @@ #define JAZZ_SERIAL_PORT_DEFNS #endif -/* - * Galileo EV64120 evaluation board - */ -#ifdef CONFIG_MIPS_EV64120 -#include -#define EV64120_SERIAL_PORT_DEFNS \ - { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \ - .flags = STD_COM_FLAGS, \ - .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \ - .io_type = SERIAL_IO_MEM }, \ - { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \ - .flags = STD_COM_FLAGS, \ - .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \ - .io_type = SERIAL_IO_MEM }, -#else -#define EV64120_SERIAL_PORT_DEFNS -#endif - #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT #define STD_SERIAL_PORT_DEFNS \ /* UART CLK PORT IRQ FLAGS */ \ @@ -166,7 +148,6 @@ #define SERIAL_PORT_DFNS \ DDB5477_SERIAL_PORT_DEFNS \ - EV64120_SERIAL_PORT_DEFNS \ IP32_SERIAL_PORT_DEFNS \ JAZZ_SERIAL_PORT_DEFNS \ STD_SERIAL_PORT_DEFNS \ From 19df0d1169b3ddcc84933794d1401aaafe2f0000 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:00 +0100 Subject: [PATCH 496/551] [MIPS] PCI: Make dev pointer argument of pcibios_map_irq const. This is to break the code of people who think they are supposed to scribble into the pci device structure - it's off limits. Signed-off-by: Ralf Baechle --- arch/mips/pci/fixup-atlas.c | 2 +- arch/mips/pci/fixup-au1000.c | 2 +- arch/mips/pci/fixup-capcella.c | 2 +- arch/mips/pci/fixup-cobalt.c | 2 +- arch/mips/pci/fixup-emma2rh.c | 2 +- arch/mips/pci/fixup-excite.c | 2 +- arch/mips/pci/fixup-ip32.c | 2 +- arch/mips/pci/fixup-jmr3927.c | 2 +- arch/mips/pci/fixup-malta.c | 2 +- arch/mips/pci/fixup-mpc30x.c | 2 +- arch/mips/pci/fixup-ocelot-c.c | 2 +- arch/mips/pci/fixup-ocelot3.c | 2 +- arch/mips/pci/fixup-pnx8550.c | 2 +- arch/mips/pci/fixup-rbtx4927.c | 2 +- arch/mips/pci/fixup-sni.c | 2 +- arch/mips/pci/fixup-tb0219.c | 2 +- arch/mips/pci/fixup-tb0226.c | 2 +- arch/mips/pci/fixup-tb0287.c | 2 +- arch/mips/pci/fixup-tx4938.c | 2 +- arch/mips/pci/fixup-vr4133.c | 2 +- arch/mips/pci/fixup-wrppmc.c | 2 +- arch/mips/pci/fixup-yosemite.c | 2 +- arch/mips/pci/pci-bcm1480.c | 3 ++- arch/mips/pci/pci-ddb5477.c | 2 +- arch/mips/pci/pci-ip27.c | 2 +- arch/mips/pci/pci-lasat.c | 2 +- arch/mips/pci/pci-sb1250.c | 2 +- include/asm-mips/pci.h | 2 +- 28 files changed, 29 insertions(+), 28 deletions(-) diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c index c6cd6e9cdfbc..45224fd2c7ba 100644 --- a/arch/mips/pci/fixup-atlas.c +++ b/arch/mips/pci/fixup-atlas.c @@ -58,7 +58,7 @@ static char irq_tab[][5] __initdata = { {0, 0, 0, 0, 0 } /* 21: Unused */ }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab[slot][pin]; } diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c index c2f8304fe55b..ca0276c8070a 100644 --- a/arch/mips/pci/fixup-au1000.c +++ b/arch/mips/pci/fixup-au1000.c @@ -35,7 +35,7 @@ extern char irq_tab_alchemy[][5]; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_alchemy[slot][pin]; } diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c index 1e530751936c..1416bca6d1a3 100644 --- a/arch/mips/pci/fixup-capcella.c +++ b/arch/mips/pci/fixup-capcella.c @@ -38,7 +38,7 @@ static char irq_tab_capcella[][5] __initdata = { [14] = { -1, INTA, INTB, INTC, INTD } }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_capcella[slot][pin]; } diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index d57ffd7242ca..7fc475f7eae5 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -161,7 +161,7 @@ static char irq_tab_raq2[] __initdata = { [COBALT_PCICONF_ETH1] = COBALT_ETH1_IRQ }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (cobalt_board_id < COBALT_BRD_ID_QUBE2) return irq_tab_qube1[slot]; diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index 7abcfd175d43..a2705895561d 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c @@ -89,7 +89,7 @@ static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, emma2rh_pci_host_fixup); -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_map[slot][pin]; } diff --git a/arch/mips/pci/fixup-excite.c b/arch/mips/pci/fixup-excite.c index 1da696d43f00..cd64d9f177c4 100644 --- a/arch/mips/pci/fixup-excite.c +++ b/arch/mips/pci/fixup-excite.c @@ -21,7 +21,7 @@ #include #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (pin == 0) return -1; diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c index 3e66b0aa63ca..190fffd08d3e 100644 --- a/arch/mips/pci/fixup-ip32.c +++ b/arch/mips/pci/fixup-ip32.c @@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = { * irqs. I suppose a device without a pin A will thank us for doing it * right if there exists such a broken piece of crap. */ -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_mace[slot][pin]; } diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 73d18503517c..e974394be7bc 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -33,7 +33,7 @@ #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index bf2c41d1e9c5..0f48498bc231 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -36,7 +36,7 @@ static char irq_tab[][5] __initdata = { {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int virq; virq = irq_tab[slot][pin]; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c index 3c9ae41f7517..591159625722 100644 --- a/arch/mips/pci/fixup-mpc30x.c +++ b/arch/mips/pci/fixup-mpc30x.c @@ -34,7 +34,7 @@ static const int irq_tab_mpc30x[] __initdata = { [29] = MQ200_IRQ, }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 30) return internal_func_irqs[PCI_FUNC(dev->devfn)]; diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c index d45494807a33..6616648712c2 100644 --- a/arch/mips/pci/fixup-ocelot-c.c +++ b/arch/mips/pci/fixup-ocelot-c.c @@ -19,7 +19,7 @@ #include #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int bus = dev->bus->number; diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c index ececc03ec620..702f997b8673 100644 --- a/arch/mips/pci/fixup-ocelot3.c +++ b/arch/mips/pci/fixup-ocelot3.c @@ -23,7 +23,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int bus = dev->bus->number; diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c index 50546dab6689..96857ac63bf5 100644 --- a/arch/mips/pci/fixup-pnx8550.c +++ b/arch/mips/pci/fixup-pnx8550.c @@ -45,7 +45,7 @@ void __init pcibios_fixup(void) /* nothing to do here */ } -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return pnx8550_irq_tab[slot][pin]; } diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index ceeb1860895a..3cdbecb8e714 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -119,7 +119,7 @@ int pci_get_irq(struct pci_dev *dev, int pin) return irq; } -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq; diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c index 36e5fb1b3786..a45bedd17233 100644 --- a/arch/mips/pci/fixup-sni.c +++ b/arch/mips/pci/fixup-sni.c @@ -120,7 +120,7 @@ static inline int is_rm300_revd(void) return (csmsr & 0xa0) == 0x20; } -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (sni_brd_type) { case SNI_BRD_PCI_TOWER: diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c index 734f2b71e164..720a2b720c5c 100644 --- a/arch/mips/pci/fixup-tb0219.c +++ b/arch/mips/pci/fixup-tb0219.c @@ -23,7 +23,7 @@ #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c index c9e7cb4361a1..e3eedf4bf9bd 100644 --- a/arch/mips/pci/fixup-tb0226.c +++ b/arch/mips/pci/fixup-tb0226.c @@ -23,7 +23,7 @@ #include #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c index fbe6bcb28199..267ab3dc3d42 100644 --- a/arch/mips/pci/fixup-tb0287.c +++ b/arch/mips/pci/fixup-tb0287.c @@ -22,7 +22,7 @@ #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char bus; int irq = -1; diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c index f455520ada88..2485f47dfe6f 100644 --- a/arch/mips/pci/fixup-tx4938.c +++ b/arch/mips/pci/fixup-tx4938.c @@ -69,7 +69,7 @@ int pci_get_irq(struct pci_dev *dev, int pin) return irq; } -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = 0; diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c index a8d9d22b13df..de5e5f6bbf4c 100644 --- a/arch/mips/pci/fixup-vr4133.c +++ b/arch/mips/pci/fixup-vr4133.c @@ -169,7 +169,7 @@ void i8259_init(void) } #endif -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { extern int pci_probe_only; pci_probe_only = 1; diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c index 3357c1300bb1..3d277549d5df 100644 --- a/arch/mips/pci/fixup-wrppmc.c +++ b/arch/mips/pci/fixup-wrppmc.c @@ -25,7 +25,7 @@ static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = { [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0}, }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return pci_irq_tab[slot][pin]; } diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c index 81d77a587a51..fdafb13a793b 100644 --- a/arch/mips/pci/fixup-yosemite.c +++ b/arch/mips/pci/fixup-yosemite.c @@ -26,7 +26,7 @@ #include #include -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (pin == 0) return -1; diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index d7b9e1349f6d..2b4e30c7d105 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -74,8 +74,9 @@ static inline void WRITECFG32(u32 addr, u32 data) *(u32 *)(cfg_space + (addr & ~3)) = data; } -int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { + This is b0rked. return dev->irq; } diff --git a/arch/mips/pci/pci-ddb5477.c b/arch/mips/pci/pci-ddb5477.c index d071bc375b11..7363e1877842 100644 --- a/arch/mips/pci/pci-ddb5477.c +++ b/arch/mips/pci/pci-ddb5477.c @@ -131,7 +131,7 @@ static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = { /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */ }; -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int slot_num; unsigned char *slot_irq_map; diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 405ce0152739..a322543ac34e 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -134,7 +134,7 @@ int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) * A given PCI device, in general, should be able to intr any of the cpus * on any one of the hubs connected to its xbow. */ -int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); int irq = bc->pci_int[slot]; diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 985784a3e6f8..c5045ff3ad8c 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -64,7 +64,7 @@ arch_initcall(lasat_pci_setup); #define LASATINT_PCIC 7 #define LASATINT_PCID 8 -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 1: diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index 75c1246ced5f..c1ac6493155e 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c @@ -84,7 +84,7 @@ static inline void WRITECFG32(u32 addr, u32 data) *(u32 *) (cfg_space + (addr & ~3)) = data; } -int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return dev->irq; } diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 3eea3ba0fca5..a59d54749eef 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -56,7 +56,7 @@ extern void register_pci_controller(struct pci_controller *hose); /* * board supplied pci irq fixup routine */ -extern int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin); +extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); /* Can be used to override the logic in pci_scan_bus for skipping From cfd2afc0f654e86e3f0b5060409b90f21964b9d3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:00 +0100 Subject: [PATCH 497/551] [MIPS] IP32: Remove experimental tag from kconfig. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8750e611ef59..a29ebfde6077 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -433,8 +433,7 @@ config SGI_IP27 here. config SGI_IP32 - bool "SGI IP32 (O2) (EXPERIMENTAL)" - depends on EXPERIMENTAL + bool "SGI IP32 (O2)" select ARC select ARC32 select BOOT_ELF32 From 192cca6ef2c49ac5ff46f7a31cb9dd175995658e Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 11 Jun 2007 15:08:55 +0200 Subject: [PATCH 498/551] [MIPS] Remove Momenco Ocelot C support Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle delete mode 100644 arch/mips/configs/ocelot_c_defconfig delete mode 100644 arch/mips/momentum/ocelot_c/Makefile delete mode 100644 arch/mips/momentum/ocelot_c/cpci-irq.c delete mode 100644 arch/mips/momentum/ocelot_c/dbg_io.c delete mode 100644 arch/mips/momentum/ocelot_c/irq.c delete mode 100644 arch/mips/momentum/ocelot_c/ocelot_c_fpga.h delete mode 100644 arch/mips/momentum/ocelot_c/platform.c delete mode 100644 arch/mips/momentum/ocelot_c/prom.c delete mode 100644 arch/mips/momentum/ocelot_c/reset.c delete mode 100644 arch/mips/momentum/ocelot_c/setup.c delete mode 100644 arch/mips/momentum/ocelot_c/uart-irq.c delete mode 100644 arch/mips/pci/fixup-ocelot-c.c delete mode 100644 arch/mips/pci/pci-ocelot-c.c --- arch/mips/Kconfig | 18 - arch/mips/Makefile | 8 - arch/mips/configs/atlas_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/ddb5477_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/lasat200_defconfig | 1 - arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/ocelot_3_defconfig | 1 - arch/mips/configs/ocelot_c_defconfig | 981 -------------------- arch/mips/configs/ocelot_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/qemu_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 1 - arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/defconfig | 1 - arch/mips/momentum/ocelot_c/Makefile | 8 - arch/mips/momentum/ocelot_c/cpci-irq.c | 100 -- arch/mips/momentum/ocelot_c/dbg_io.c | 121 --- arch/mips/momentum/ocelot_c/irq.c | 107 --- arch/mips/momentum/ocelot_c/ocelot_c_fpga.h | 61 -- arch/mips/momentum/ocelot_c/platform.c | 183 ---- arch/mips/momentum/ocelot_c/prom.c | 183 ---- arch/mips/momentum/ocelot_c/reset.c | 58 -- arch/mips/momentum/ocelot_c/setup.c | 362 -------- arch/mips/momentum/ocelot_c/uart-irq.c | 91 -- arch/mips/pci/Makefile | 1 - arch/mips/pci/fixup-ocelot-c.c | 41 - arch/mips/pci/pci-ocelot-c.c | 145 --- drivers/mtd/devices/docprobe.c | 2 +- drivers/mtd/nand/diskonchip.c | 2 +- drivers/net/Kconfig | 2 +- include/asm-mips/bootinfo.h | 2 +- include/asm-mips/serial.h | 26 - include/asm-mips/war.h | 4 +- 65 files changed, 6 insertions(+), 2543 deletions(-) delete mode 100644 arch/mips/configs/ocelot_c_defconfig delete mode 100644 arch/mips/momentum/ocelot_c/Makefile delete mode 100644 arch/mips/momentum/ocelot_c/cpci-irq.c delete mode 100644 arch/mips/momentum/ocelot_c/dbg_io.c delete mode 100644 arch/mips/momentum/ocelot_c/irq.c delete mode 100644 arch/mips/momentum/ocelot_c/ocelot_c_fpga.h delete mode 100644 arch/mips/momentum/ocelot_c/platform.c delete mode 100644 arch/mips/momentum/ocelot_c/prom.c delete mode 100644 arch/mips/momentum/ocelot_c/reset.c delete mode 100644 arch/mips/momentum/ocelot_c/setup.c delete mode 100644 arch/mips/momentum/ocelot_c/uart-irq.c delete mode 100644 arch/mips/pci/fixup-ocelot-c.c delete mode 100644 arch/mips/pci/pci-ocelot-c.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a29ebfde6077..cba171a5eb03 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -276,24 +276,6 @@ config MOMENCO_OCELOT_3 The Ocelot-3 is based off Discovery III System Controller and PMC-Sierra Rm79000 core. -config MOMENCO_OCELOT_C - bool "Momentum Ocelot-C board" - select DMA_NONCOHERENT - select HW_HAS_PCI - select IRQ_CPU - select IRQ_MV64340 - select PCI_MARVELL - select RM7000_CPU_SCACHE - select SWAP_IO_SPACE - select SYS_HAS_CPU_RM7000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ - help - The Ocelot is a MIPS-based Single Board Computer (SBC) made by - Momentum Computer . - config PNX8550_JBS bool "Philips PNX8550 based JBS board" select PNX8550 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ddb048b8600a..fc09769b3dd4 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -334,14 +334,6 @@ core-$(CONFIG_MOMENCO_OCELOT) += arch/mips/gt64120/common/ \ cflags-$(CONFIG_MOMENCO_OCELOT) += -Iinclude/asm-mips/mach-ocelot load-$(CONFIG_MOMENCO_OCELOT) += 0xffffffff80100000 -# -# Momentum Ocelot-C and -CS boards -# -# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the -# mips_io_port_base. -core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ -load-$(CONFIG_MOMENCO_OCELOT_C) += 0xffffffff80100000 - # # PMC-Sierra Yosemite # diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 99c54f3da36a..de855d1fc01f 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -35,7 +35,6 @@ CONFIG_MIPS_ATLAS=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index c885e4fc4e41..bf88a6ce8042 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index a5ebedc1d1de..7582709874c3 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index c70456ede3d5..9c5750c91810 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -21,7 +21,6 @@ CONFIG_MIPS_COBALT=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 87e99e5ca84d..bbf007a69105 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 5d46a9982832..384e41afb544 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index e6f4242268fb..76c3c46851a7 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index ea5609339146..89c458086e6e 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index 2728a0018b58..c83ba3cc1f05 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index d67f15009efa..7ec230ed225a 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 25e533667504..2a4948a2d7d3 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -35,7 +35,6 @@ CONFIG_MACH_DECSTATION=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 1257a7016c44..d853278fce65 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index 9318fce31732..31f03f8113ee 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index e35a8f58c071..b1a9e0b3067e 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -36,7 +36,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index c655d4da0c68..2f2243658aad 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index a2475e7e909d..267af44f97ab 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index f95d5fef3a0b..00ec6ed5e550 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index e2f5a5a41792..12c02656013e 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -35,7 +35,6 @@ CONFIG_MACH_JAZZ=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 2c88b3295af4..61235a552df2 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index ccf7227cbf98..c427c08efb6c 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -35,7 +35,6 @@ CONFIG_LASAT=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1c839cf29d86..1f5cf9200846 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -35,7 +35,6 @@ CONFIG_MIPS_MALTA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 559f4d0038b0..ef5cae94c076 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -35,7 +35,6 @@ CONFIG_MIPS_SIM=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 811ada95d729..73a5314603e3 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index a53175a109e7..cc99c83a81d2 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set CONFIG_MOMENCO_OCELOT_3=y -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig deleted file mode 100644 index 38e86f16f856..000000000000 --- a/arch/mips/configs/ocelot_c_defconfig +++ /dev/null @@ -1,981 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:36 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -CONFIG_MOMENCO_OCELOT_C=y -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_IRQ_MV64340=y -CONFIG_PCI_MARVELL=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -CONFIG_CPU_RM7000=y -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_RM7000=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -# CONFIG_32BIT is not set -CONFIG_64BIT=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_RM7000_CPU_SCACHE=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_BUILD_ELF64 is not set -CONFIG_MIPS32_COMPAT=y -CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_MIPS32_O32=y -CONFIG_MIPS32_N32=y -CONFIG_BINFMT_ELF32=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -# CONFIG_PACKET is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_IEEE80211=y -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=y -CONFIG_IEEE80211_CRYPT_CCMP=y -CONFIG_IEEE80211_SOFTMAC=y -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=y -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=y - -# -# Misc devices -# -CONFIG_SGI_IOC4=y -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=y -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_MV643XX_ETH is not set -CONFIG_QLA3XXX=y -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=y -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=y - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_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=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=y -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM 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_HW_RANDOM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -# CONFIG_HID is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y -CONFIG_GENERIC_ACL=y - -# -# 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_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_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=y -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -CONFIG_DLM=y -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_TGR192=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_KHAZAD=y -CONFIG_CRYPTO_ANUBIS=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CAMELLIA=y - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y -CONFIG_CRC32=y -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index f5948e56b848..5f3b47fa3f19 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set CONFIG_MOMENCO_OCELOT=y # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index e764285aac62..b57662a2a3e3 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 37e2a102f6e2..350f9bdbb5e2 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index b1206a20e7e0..8ea039ab0895 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -36,7 +36,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index e7096449ba26..9c8c54ee5e9d 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set CONFIG_PNX8550_JBS=y diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index a46761f56a12..2f60c5a4286b 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index 93f382b32179..d7ace0857383 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index dbb485d499a5..b020e9270147 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -33,7 +33,6 @@ CONFIG_MIPS=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index c7c28a1616b2..b0abd16fae29 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index f3ee7e179f24..120dcff4942e 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 11f034764812..534de60fd03c 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index 0d055b2d1510..e0185ebdfa8f 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -35,7 +35,6 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index a0cda222254f..11f4c66ea456 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index 9b0a1d59eddd..1c54d1bbba7d 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index f8f11dcbb8de..7f2ece3d857c 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index 8558348cad3b..ef663304c93d 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 01b05b2a497a..d57d6cca646c 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -35,7 +35,6 @@ CONFIG_WR_PPMC=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 3d40e7c1277b..38349216668f 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 195311dfeae6..9515ed6128ca 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -35,7 +35,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile deleted file mode 100644 index d69161aa1675..000000000000 --- a/arch/mips/momentum/ocelot_c/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for Momentum Computer's Ocelot-C and -CS boards. -# - -obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \ - setup.o uart-irq.o - -obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c deleted file mode 100644 index 186a140fd2a9..000000000000 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2002 Momentum Computer - * Author: mdharm@momenco.com - * - * arch/mips/momentum/ocelot_c/cpci-irq.c - * Interrupt routines for cpci. Interrupt numbers are assigned from - * CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources). - * - * Note that the high-level software will need to be careful about using - * these interrupts. If this board is asserting a cPCI interrupt, it will - * also see the asserted interrupt. Care must be taken to avoid an - * interrupt flood. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "ocelot_c_fpga.h" - -#define CPCI_IRQ_BASE 8 - -static inline int ls1bit8(unsigned int x) -{ - int b = 7, s; - - s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; - s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; - s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; - - return b; -} - -/* mask off an interrupt -- 0 is enable, 1 is disable */ -static inline void mask_cpci_irq(unsigned int irq) -{ - uint32_t value; - - value = OCELOT_FPGA_READ(INTMASK); - value |= 1 << (irq - CPCI_IRQ_BASE); - OCELOT_FPGA_WRITE(value, INTMASK); - - /* read the value back to assure that it's really been written */ - value = OCELOT_FPGA_READ(INTMASK); -} - -/* unmask an interrupt -- 0 is enable, 1 is disable */ -static inline void unmask_cpci_irq(unsigned int irq) -{ - uint32_t value; - - value = OCELOT_FPGA_READ(INTMASK); - value &= ~(1 << (irq - CPCI_IRQ_BASE)); - OCELOT_FPGA_WRITE(value, INTMASK); - - /* read the value back to assure that it's really been written */ - value = OCELOT_FPGA_READ(INTMASK); -} - -/* - * Interrupt handler for interrupts coming from the FPGA chip. - * It could be built in ethernet ports etc... - */ -void ll_cpci_irq(void) -{ - unsigned int irq_src, irq_mask; - - /* read the interrupt status registers */ - irq_src = OCELOT_FPGA_READ(INTSTAT); - irq_mask = OCELOT_FPGA_READ(INTMASK); - - /* mask for just the interrupts we want */ - irq_src &= ~irq_mask; - - do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE); -} - -struct irq_chip cpci_irq_type = { - .name = "CPCI/FPGA", - .ack = mask_cpci_irq, - .mask = mask_cpci_irq, - .mask_ack = mask_cpci_irq, - .unmask = unmask_cpci_irq, -}; - -void cpci_irq_init(void) -{ - int i; - - for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) - set_irq_chip_and_handler(i, &cpci_irq_type, handle_level_irq); -} diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c deleted file mode 100644 index 32d6fb4ee679..000000000000 --- a/arch/mips/momentum/ocelot_c/dbg_io.c +++ /dev/null @@ -1,121 +0,0 @@ - -#include /* For the serial port location and base baud */ - -/* --- CONFIG --- */ - -typedef unsigned char uint8; -typedef unsigned int uint32; - -/* --- END OF CONFIG --- */ - -#define UART16550_BAUD_2400 2400 -#define UART16550_BAUD_4800 4800 -#define UART16550_BAUD_9600 9600 -#define UART16550_BAUD_19200 19200 -#define UART16550_BAUD_38400 38400 -#define UART16550_BAUD_57600 57600 -#define UART16550_BAUD_115200 115200 - -#define UART16550_PARITY_NONE 0 -#define UART16550_PARITY_ODD 0x08 -#define UART16550_PARITY_EVEN 0x18 -#define UART16550_PARITY_MARK 0x28 -#define UART16550_PARITY_SPACE 0x38 - -#define UART16550_DATA_5BIT 0x0 -#define UART16550_DATA_6BIT 0x1 -#define UART16550_DATA_7BIT 0x2 -#define UART16550_DATA_8BIT 0x3 - -#define UART16550_STOP_1BIT 0x0 -#define UART16550_STOP_2BIT 0x4 - -/* ----------------------------------------------------- */ - -/* === CONFIG === */ - -/* [jsun] we use the second serial port for kdb */ -#define BASE OCELOT_SERIAL1_BASE -#define MAX_BAUD OCELOT_BASE_BAUD - -/* === END OF CONFIG === */ - -#define REG_OFFSET 4 - -/* register offset */ -#define OFS_RCV_BUFFER 0 -#define OFS_TRANS_HOLD 0 -#define OFS_SEND_BUFFER 0 -#define OFS_INTR_ENABLE (1*REG_OFFSET) -#define OFS_INTR_ID (2*REG_OFFSET) -#define OFS_DATA_FORMAT (3*REG_OFFSET) -#define OFS_LINE_CONTROL (3*REG_OFFSET) -#define OFS_MODEM_CONTROL (4*REG_OFFSET) -#define OFS_RS232_OUTPUT (4*REG_OFFSET) -#define OFS_LINE_STATUS (5*REG_OFFSET) -#define OFS_MODEM_STATUS (6*REG_OFFSET) -#define OFS_RS232_INPUT (6*REG_OFFSET) -#define OFS_SCRATCH_PAD (7*REG_OFFSET) - -#define OFS_DIVISOR_LSB (0*REG_OFFSET) -#define OFS_DIVISOR_MSB (1*REG_OFFSET) - - -/* memory-mapped read/write of the port */ -#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) -#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) - -void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) -{ - /* disable interrupts */ - UART16550_WRITE(OFS_INTR_ENABLE, 0); - - /* set up baud rate */ - { - uint32 divisor; - - /* set DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x80); - - /* set divisor */ - divisor = MAX_BAUD / baud; - UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); - UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); - - /* clear DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x0); - } - - /* set data format */ - UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); -} - -static int remoteDebugInitialized = 0; - -uint8 getDebugChar(void) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_38400, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); - return UART16550_READ(OFS_RCV_BUFFER); -} - - -int putDebugChar(uint8 byte) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_38400, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); - UART16550_WRITE(OFS_SEND_BUFFER, byte); - return 1; -} diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c deleted file mode 100644 index 844d566c9de3..000000000000 --- a/arch/mips/momentum/ocelot_c/irq.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void uart_irq_init(void); -extern void cpci_irq_init(void); - -static struct irqaction cascade_fpga = { - no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL -}; - -static struct irqaction cascade_mv64340 = { - no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL -}; - -extern void ll_uart_irq(void); -extern void ll_cpci_irq(void); - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - - if (pending & STATUSF_IP0) - do_IRQ(0); - else if (pending & STATUSF_IP1) - do_IRQ(1); - else if (pending & STATUSF_IP2) - do_IRQ(2); - else if (pending & STATUSF_IP3) - ll_uart_irq(); - else if (pending & STATUSF_IP4) - do_IRQ(4); - else if (pending & STATUSF_IP5) - ll_cpci_irq(); - else if (pending & STATUSF_IP6) - ll_mv64340_irq(); - else if (pending & STATUSF_IP7) - do_IRQ(7); - else - spurious_interrupt(); -} - -void __init arch_init_irq(void) -{ - /* - * Clear all of the interrupts while we change the able around a bit. - * int-handler is not on bootstrap - */ - clear_c0_status(ST0_IM); - - mips_cpu_irq_init(); - - /* set up the cascading interrupts */ - setup_irq(3, &cascade_fpga); - setup_irq(5, &cascade_fpga); - setup_irq(6, &cascade_mv64340); - - mv64340_irq_init(16); - uart_irq_init(); - cpci_irq_init(); -} diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h deleted file mode 100644 index f0f5581dcb50..000000000000 --- a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Ocelot-C Board Register Definitions - * - * (C) 2002 Momentum Computer Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - */ - -#ifndef __OCELOT_C_FPGA_H__ -#define __OCELOT_C_FPGA_H__ - - -#ifdef CONFIG_64BIT -#define OCELOT_C_CS0_ADDR (0xfffffffffc000000) -#else -#define OCELOT_C_CS0_ADDR (0xfc000000) -#endif - -#define OCELOT_C_REG_BOARDREV 0x0 -#define OCELOT_C_REG_FPGA_REV 0x1 -#define OCELOT_C_REG_FPGA_TYPE 0x2 -#define OCELOT_C_REG_RESET_STATUS 0x3 -#define OCELOT_C_REG_BOARD_STATUS 0x4 -#define OCELOT_C_REG_CPCI_ID 0x5 -#define OCELOT_C_REG_SET 0x6 -#define OCELOT_C_REG_CLR 0x7 -#define OCELOT_C_REG_EEPROM_MODE 0x9 -#define OCELOT_C_REG_INTMASK 0xa -#define OCELOT_C_REG_INTSTAT 0xb -#define OCELOT_C_REG_UART_INTMASK 0xc -#define OCELOT_C_REG_UART_INTSTAT 0xd -#define OCELOT_C_REG_INTSET 0xe -#define OCELOT_C_REG_INTCLR 0xf - -#define __FPGA_REG_TO_ADDR(reg) \ - ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg) -#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) -#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) - -#endif diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c deleted file mode 100644 index 7780aa0c6555..000000000000 --- a/arch/mips/momentum/ocelot_c/platform.c +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include -#include - -#include "ocelot_c_fpga.h" - -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) - -static struct resource mv643xx_eth_shared_resources[] = { - [0] = { - .name = "ethernet shared base", - .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, - .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + - MV643XX_ETH_SHARED_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device mv643xx_eth_shared_device = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), - .resource = mv643xx_eth_shared_resources, -}; - -#define MV_SRAM_BASE 0xfe000000UL -#define MV_SRAM_SIZE (256 * 1024) - -#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) -#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) - -#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE -#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) - -#define MV64x60_IRQ_ETH_0 48 -#define MV64x60_IRQ_ETH_1 49 - -static struct resource mv64x60_eth0_resources[] = { - [0] = { - .name = "eth0 irq", - .start = MV64x60_IRQ_ETH_0, - .end = MV64x60_IRQ_ETH_0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth0_pd = { - .port_number = 0, - - .tx_sram_addr = MV_SRAM_BASE_ETH0, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth0_device = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), - .resource = mv64x60_eth0_resources, - .dev = { - .platform_data = ð0_pd, - }, -}; - -static struct resource mv64x60_eth1_resources[] = { - [0] = { - .name = "eth1 irq", - .start = MV64x60_IRQ_ETH_1, - .end = MV64x60_IRQ_ETH_1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth1_pd = { - .port_number = 1, - - .tx_sram_addr = MV_SRAM_BASE_ETH1, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth1_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), - .resource = mv64x60_eth1_resources, - .dev = { - .platform_data = ð1_pd, - }, -}; - -static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { - &mv643xx_eth_shared_device, - ð0_device, - ð1_device, - /* The third port is not wired up on the Ocelot C */ -}; - -static u8 __init exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - udelay(1); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - udelay(1); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; -} - -static void __init get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} - -/* - * Copy and increment ethernet MAC address by a small value. - * - * This is useful for systems where the only one MAC address is stored in - * non-volatile memory for multiple ports. - */ -static inline void eth_mac_add(unsigned char *dst, unsigned char *src, - unsigned int add) -{ - int i; - - BUG_ON(add >= 256); - - for (i = ETH_ALEN; i >= 0; i--) { - dst[i] = src[i] + add; - add = dst[i] < src[i]; /* compute carry */ - } - - WARN_ON(add); -} - -static int __init mv643xx_eth_add_pds(void) -{ - unsigned char mac[ETH_ALEN]; - int ret; - - get_mac(mac); - eth_mac_add(eth0_pd.mac_addr, mac, 0); - eth_mac_add(eth1_pd.mac_addr, mac, 1); - ret = platform_add_devices(mv643xx_eth_pd_devs, - ARRAY_SIZE(mv643xx_eth_pd_devs)); - - return ret; -} - -device_initcall(mv643xx_eth_add_pds); - -#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c deleted file mode 100644 index b689ceea8cfb..000000000000 --- a/arch/mips/momentum/ocelot_c/prom.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ocelot_c_fpga.h" - -struct callvectors* debug_vectors; - -extern unsigned long marvell_base; -extern unsigned int cpu_clock; - -const char *get_system_type(void) -{ -#ifdef CONFIG_CPU_SR71000 - return "Momentum Ocelot-CS"; -#else - return "Momentum Ocelot-C"; -#endif -} - -#ifdef CONFIG_64BIT - -unsigned long signext(unsigned long addr) -{ - addr &= 0xffffffff; - return (unsigned long)((int)addr); -} - -void *get_arg(unsigned long args, int arc) -{ - unsigned long ul; - unsigned char *puc, uc; - - args += (arc * 4); - ul = (unsigned long)signext(args); - puc = (unsigned char *)ul; - if (puc == 0) - return (void *)0; - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - uc = *puc++; - ul = (unsigned long)uc; - uc = *puc++; - ul |= (((unsigned long)uc) << 8); - uc = *puc++; - ul |= (((unsigned long)uc) << 16); - uc = *puc++; - ul |= (((unsigned long)uc) << 24); -#else /* CONFIG_CPU_LITTLE_ENDIAN */ - uc = *puc++; - ul = ((unsigned long)uc) << 24; - uc = *puc++; - ul |= (((unsigned long)uc) << 16); - uc = *puc++; - ul |= (((unsigned long)uc) << 8); - uc = *puc++; - ul |= ((unsigned long)uc); -#endif /* CONFIG_CPU_LITTLE_ENDIAN */ - ul = signext(ul); - return (void *)ul; -} - -char *arg64(unsigned long addrin, int arg_index) -{ - unsigned long args; - char *p; - args = signext(addrin); - p = (char *)get_arg(args, arg_index); - return p; -} -#endif /* CONFIG_64BIT */ - - -void __init prom_init(void) -{ - int argc = fw_arg0; - char **arg = (char **) fw_arg1; - char **env = (char **) fw_arg2; - struct callvectors *cv = (struct callvectors *) fw_arg3; - int i; - -#ifdef CONFIG_64BIT - char *ptr; - - printk("prom_init - MIPS64\n"); - /* save the PROM vectors for debugging use */ - debug_vectors = (struct callvectors *)signext((unsigned long)cv); - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - - for (i = 1; i < argc; i++) { - ptr = (char *)arg64((unsigned long)arg, i); - if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= - sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, ptr); - strcat(arcs_cmdline, " "); - } - i = 0; - while (1) { - ptr = (char *)arg64((unsigned long)env, i); - if (! ptr) - break; - - if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { - marvell_base = simple_strtol(ptr + strlen("gtbase="), - NULL, 16); - - if ((marvell_base & 0xffffffff00000000) == 0) - marvell_base |= 0xffffffff00000000; - - printk("marvell_base set to 0x%016lx\n", marvell_base); - } - if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { - cpu_clock = simple_strtol(ptr + strlen("cpuclock="), - NULL, 10); - printk("cpu_clock set to %d\n", cpu_clock); - } - i++; - } - printk("arcs_cmdline: %s\n", arcs_cmdline); - -#else /* CONFIG_64BIT */ - /* save the PROM vectors for debugging use */ - debug_vectors = cv; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, arg[i]); - strcat(arcs_cmdline, " "); - } - - while (*env) { - if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { - marvell_base = simple_strtol(*env + strlen("gtbase="), - NULL, 16); - } - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { - cpu_clock = simple_strtol(*env + strlen("cpuclock="), - NULL, 10); - } - env++; - } -#endif /* CONFIG_64BIT */ - - mips_machgroup = MACH_GROUP_MOMENCO; - mips_machtype = MACH_MOMENCO_OCELOT_C; - -#ifndef CONFIG_64BIT - debug_vectors->printf("Booting Linux kernel...\n"); -#endif -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/momentum/ocelot_c/reset.c b/arch/mips/momentum/ocelot_c/reset.c deleted file mode 100644 index 3fdcb64ff1e6..000000000000 --- a/arch/mips/momentum/ocelot_c/reset.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1997, 2001 Ralf Baechle - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright (C) 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - */ -#include -#include -#include -#include -#include -#include -#include -#include - -void momenco_ocelot_restart(char *command) -{ - /* base address of timekeeper portion of part */ - void *nvram = (void *) -#ifdef CONFIG_64BIT - 0xfffffffffc807000; -#else - 0xfc807000; -#endif - - /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); - - /* wait for the watchdog to go off */ - mdelay(100+(1000/16)); - - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); -} - -void momenco_ocelot_halt(void) -{ - printk(KERN_NOTICE "\n** You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); -} - -void momenco_ocelot_power_off(void) -{ - momenco_ocelot_halt(); -} diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c deleted file mode 100644 index 0b6b2338cfb4..000000000000 --- a/arch/mips/momentum/ocelot_c/setup.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Momentum Computer Ocelot-C and -CS board dependent boot routines - * - * Copyright (C) 1996, 1997, 2001 Ralf Baechle - * Copyright (C) 2000 RidgeRun, Inc. - * Copyright (C) 2001 Red Hat, Inc. - * Copyright (C) 2002 Momentum Computer - * - * Author: Matthew Dharm, Momentum Computer - * mdharm@momenco.com - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#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 "ocelot_c_fpga.h" - -unsigned long marvell_base; -unsigned int cpu_clock; - -/* These functions are used for rebooting or halting the machine*/ -extern void momenco_ocelot_restart(char *command); -extern void momenco_ocelot_halt(void); -extern void momenco_ocelot_power_off(void); - -void momenco_time_init(void); - -static char reset_reason; - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask); - -static unsigned long ENTRYLO(unsigned long paddr) -{ - return ((paddr & PAGE_MASK) | - (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL | - _CACHE_UNCACHED)) >> 6; -} - -/* setup code for a handoff from a version 2 PMON 2000 PROM */ -void PMON_v2_setup(void) -{ - /* Some wired TLB entries for the MV64340 and perhiperals. The - MV64340 is going to be hit on every IRQ anyway - there's - absolutely no point in letting it be a random TLB entry, as - it'll just cause needless churning of the TLB. And we use - the other half for the serial port, which is just a PITA - otherwise :) - - Device Physical Virtual - MV64340 Internal Regs 0xf4000000 0xf4000000 - Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000 - NVRAM (CS1) 0xfc800000 0xfc800000 - UARTs (CS2) 0xfd000000 0xfd000000 - Internal SRAM 0xfe000000 0xfe000000 - M-Systems DOC (CS3) 0xff000000 0xff000000 - */ - printk("PMON_v2_setup\n"); - -#ifdef CONFIG_64BIT - /* marvell and extra space */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K); - /* fpga, rtc, and uart */ - add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M); - /* m-sys and internal SRAM */ - add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); - - marvell_base = 0xfffffffff4000000; -#else - /* marvell and extra space */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); - /* fpga, rtc, and uart */ - add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M); - /* m-sys and internal SRAM */ - add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); - - marvell_base = 0xf4000000; -#endif -} - -unsigned long m48t37y_get_time(void) -{ -#ifdef CONFIG_64BIT - unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000; -#else - unsigned char* rtc_base = (unsigned char*)0xfc800000; -#endif - unsigned int year, month, day, hour, min, sec; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - /* stop the update */ - rtc_base[0x7ff8] = 0x40; - - year = BCD2BIN(rtc_base[0x7fff]); - year += BCD2BIN(rtc_base[0x7ff1]) * 100; - - month = BCD2BIN(rtc_base[0x7ffe]); - - day = BCD2BIN(rtc_base[0x7ffd]); - - hour = BCD2BIN(rtc_base[0x7ffb]); - min = BCD2BIN(rtc_base[0x7ffa]); - sec = BCD2BIN(rtc_base[0x7ff9]); - - /* start the update */ - rtc_base[0x7ff8] = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - return mktime(year, month, day, hour, min, sec); -} - -int m48t37y_set_time(unsigned long sec) -{ -#ifdef CONFIG_64BIT - unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000; -#else - unsigned char* rtc_base = (unsigned char*)0xfc800000; -#endif - struct rtc_time tm; - unsigned long flags; - - /* convert to a more useful format -- note months count from 0 */ - to_tm(sec, &tm); - tm.tm_mon += 1; - - spin_lock_irqsave(&rtc_lock, flags); - /* enable writing */ - rtc_base[0x7ff8] = 0x80; - - /* year */ - rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); - - /* month */ - rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); - - /* day */ - rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); - - /* hour/min/sec */ - rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); - rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); - rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); - - /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); - - /* disable writing */ - rtc_base[0x7ff8] = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - -void __init plat_timer_setup(struct irqaction *irq) -{ - setup_irq(7, irq); -} - -void momenco_time_init(void) -{ -#ifdef CONFIG_CPU_SR71000 - mips_hpt_frequency = cpu_clock; -#elif defined(CONFIG_CPU_RM7000) - mips_hpt_frequency = cpu_clock / 2; -#else -#error Unknown CPU for this board -#endif - printk("momenco_time_init cpu_clock=%d\n", cpu_clock); - - rtc_mips_get_time = m48t37y_get_time; - rtc_mips_set_time = m48t37y_set_time; -} - -void __init plat_mem_setup(void) -{ - unsigned int tmpword; - - board_time_init = momenco_time_init; - - _machine_restart = momenco_ocelot_restart; - _machine_halt = momenco_ocelot_halt; - pm_power_off = momenco_ocelot_power_off; - - /* - * initrd_start = (unsigned long)ocelot_initrd_start; - * initrd_end = (unsigned long)ocelot_initrd_start + (ulong)ocelot_initrd_size; - * initrd_below_start_ok = 1; - */ - - /* do handoff reconfiguration */ - PMON_v2_setup(); - - /* shut down ethernet ports, just to be sure our memory doesn't get - * corrupted by random ethernet traffic. - */ - MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); - MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); - do {} - while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); - MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), - MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); - MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), - MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); - - /* Turn off the Bit-Error LED */ - OCELOT_FPGA_WRITE(0x80, CLR); - - tmpword = OCELOT_FPGA_READ(BOARDREV); -#ifdef CONFIG_CPU_SR71000 - if (tmpword < 26) - printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n", - 'A'+tmpword); - else - printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n", - tmpword); -#else - if (tmpword < 26) - printk("Momenco Ocelot-C: Board Assembly Rev. %c\n", - 'A'+tmpword); - else - printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n", - tmpword); -#endif - - tmpword = OCELOT_FPGA_READ(FPGA_REV); - printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); - tmpword = OCELOT_FPGA_READ(RESET_STATUS); - printk("Reset reason: 0x%x\n", tmpword); - switch (tmpword) { - case 0x1: - printk(" - Power-up reset\n"); - break; - case 0x2: - printk(" - Push-button reset\n"); - break; - case 0x4: - printk(" - cPCI bus reset\n"); - break; - case 0x8: - printk(" - Watchdog reset\n"); - break; - case 0x10: - printk(" - Software reset\n"); - break; - default: - printk(" - Unknown reset cause\n"); - } - reset_reason = tmpword; - OCELOT_FPGA_WRITE(0xff, RESET_STATUS); - - tmpword = OCELOT_FPGA_READ(CPCI_ID); - printk("cPCI ID register: 0x%02x\n", tmpword); - printk(" - Slot number: %d\n", tmpword & 0x1f); - printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no"); - printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no"); - - tmpword = OCELOT_FPGA_READ(BOARD_STATUS); - printk("Board Status register: 0x%02x\n", tmpword); - printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); - printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); - printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); - printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); - - switch(tmpword &3) { - case 3: - /* 512MiB */ - add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM); - break; - case 2: - /* 256MiB */ - add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM); - break; - case 1: - /* 128MiB */ - add_memory_region(0x0, 0x80<<20, BOOT_MEM_RAM); - break; - case 0: - /* 1GiB -- needs CONFIG_HIGHMEM */ - add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM); - break; - } -} - -/* - * This needs to be one of the first initcalls, because no I/O port access - * can work before this - */ -static int io_base_ioremap(void) -{ - void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000); - - if (!io_remap_range) - panic("Could not ioremap I/O port range"); - - set_io_port_base((unsigned long) io_remap_range); - - return 0; -} - -module_init(io_base_ioremap); diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c deleted file mode 100644 index de1a31ee52f3..000000000000 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2002 Momentum Computer - * Author: mdharm@momenco.com - * - * arch/mips/momentum/ocelot_c/uart-irq.c - * Interrupt routines for UARTs. Interrupt numbers are assigned from - * 80 to 81 (2 interrupt sources). - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ocelot_c_fpga.h" - -static inline int ls1bit8(unsigned int x) -{ - int b = 7, s; - - s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; - s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; - s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; - - return b; -} - -/* mask off an interrupt -- 0 is enable, 1 is disable */ -static inline void mask_uart_irq(unsigned int irq) -{ - uint8_t value; - - value = OCELOT_FPGA_READ(UART_INTMASK); - value |= 1 << (irq - 74); - OCELOT_FPGA_WRITE(value, UART_INTMASK); - - /* read the value back to assure that it's really been written */ - value = OCELOT_FPGA_READ(UART_INTMASK); -} - -/* unmask an interrupt -- 0 is enable, 1 is disable */ -static inline void unmask_uart_irq(unsigned int irq) -{ - uint8_t value; - - value = OCELOT_FPGA_READ(UART_INTMASK); - value &= ~(1 << (irq - 74)); - OCELOT_FPGA_WRITE(value, UART_INTMASK); - - /* read the value back to assure that it's really been written */ - value = OCELOT_FPGA_READ(UART_INTMASK); -} - -/* - * Interrupt handler for interrupts coming from the FPGA chip. - */ -void ll_uart_irq(void) -{ - unsigned int irq_src, irq_mask; - - /* read the interrupt status registers */ - irq_src = OCELOT_FPGA_READ(UART_INTSTAT); - irq_mask = OCELOT_FPGA_READ(UART_INTMASK); - - /* mask for just the interrupts we want */ - irq_src &= ~irq_mask; - - do_IRQ(ls1bit8(irq_src) + 74); -} - -struct irq_chip uart_irq_type = { - .name = "UART/FPGA", - .ack = mask_uart_irq, - .mask = mask_uart_irq, - .mask_ack = mask_uart_irq, - .unmask = unmask_uart_irq, -}; - -void uart_irq_init(void) -{ - set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq); - set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq); -} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 3ff56b84add0..a3e741e190f2 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o -obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ pci-yosemite.o obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c deleted file mode 100644 index 6616648712c2..000000000000 --- a/arch/mips/pci/fixup-ocelot-c.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Based on work for the Linux port to the Ocelot board, which is - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/momentum/ocelot_g/pci.c - * Board-specific PCI routines for mv64340 controller. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - int bus = dev->bus->number; - - if (bus == 0 && slot == 1) - return 2; /* PCI-X A */ - if (bus == 1 && slot == 1) - return 12; /* PCI-X B */ - if (bus == 1 && slot == 2) - return 4; /* PCI B */ - -return 0; - panic("Whooops in pcibios_map_irq"); -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c deleted file mode 100644 index 027759f7c904..000000000000 --- a/arch/mips/pci/pci-ocelot-c.c +++ /dev/null @@ -1,145 +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) 2004, 06 by Ralf Baechle (ralf@linux-mips.org) - */ - -#include -#include -#include - -#include - -#include - -/* - * We assume the address ranges have already been setup appropriately by - * the firmware. PMON in case of the Ocelot C does that. - */ -static struct resource mv_pci_io_mem0_resource = { - .name = "MV64340 PCI0 IO MEM", - .flags = IORESOURCE_IO -}; - -static struct resource mv_pci_mem0_resource = { - .name = "MV64340 PCI0 MEM", - .flags = IORESOURCE_MEM -}; - -static struct mv_pci_controller mv_bus0_controller = { - .pcic = { - .pci_ops = &mv_pci_ops, - .mem_resource = &mv_pci_mem0_resource, - .io_resource = &mv_pci_io_mem0_resource, - }, - .config_addr = MV64340_PCI_0_CONFIG_ADDR, - .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, -}; - -static uint32_t mv_io_base, mv_io_size; - -static void mv64340_pci0_init(void) -{ - uint32_t mem0_base, mem0_size; - uint32_t io_base, io_size; - - io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16; - io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16; - mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16; - mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16; - - mv_pci_io_mem0_resource.start = 0; - mv_pci_io_mem0_resource.end = io_size - 1; - mv_pci_mem0_resource.start = mem0_base; - mv_pci_mem0_resource.end = mem0_base + mem0_size - 1; - mv_bus0_controller.pcic.mem_offset = mem0_base; - mv_bus0_controller.pcic.io_offset = 0; - - ioport_resource.end = io_size - 1; - - register_pci_controller(&mv_bus0_controller.pcic); - - mv_io_base = io_base; - mv_io_size = io_size; -} - -static struct resource mv_pci_io_mem1_resource = { - .name = "MV64340 PCI1 IO MEM", - .flags = IORESOURCE_IO -}; - -static struct resource mv_pci_mem1_resource = { - .name = "MV64340 PCI1 MEM", - .flags = IORESOURCE_MEM -}; - -static struct mv_pci_controller mv_bus1_controller = { - .pcic = { - .pci_ops = &mv_pci_ops, - .mem_resource = &mv_pci_mem1_resource, - .io_resource = &mv_pci_io_mem1_resource, - }, - .config_addr = MV64340_PCI_1_CONFIG_ADDR, - .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, -}; - -static __init void mv64340_pci1_init(void) -{ - uint32_t mem0_base, mem0_size; - uint32_t io_base, io_size; - - io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16; - io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16; - mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16; - mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16; - - /* - * Here we assume the I/O window of second bus to be contiguous with - * the first. A gap is no problem but would waste address space for - * remapping the port space. - */ - mv_pci_io_mem1_resource.start = mv_io_size; - mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1; - mv_pci_mem1_resource.start = mem0_base; - mv_pci_mem1_resource.end = mem0_base + mem0_size - 1; - mv_bus1_controller.pcic.mem_offset = mem0_base; - mv_bus1_controller.pcic.io_offset = 0; - - ioport_resource.end = io_base + io_size -mv_io_base - 1; - - register_pci_controller(&mv_bus1_controller.pcic); - - mv_io_size = io_base + io_size - mv_io_base; -} - -static __init int __init ocelot_c_pci_init(void) -{ - unsigned long io_v_base; - uint32_t enable; - - enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); - - /* - * We require at least one enabled I/O or PCI memory window or we - * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3. - */ - if (enable & (0x01 << 9) || enable & (0x01 << 10)) - mv64340_pci0_init(); - - if (enable & (0x01 << 14) || enable & (0x01 << 15)) - mv64340_pci1_init(); - - if (mv_io_size) { - io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size); - if (!io_v_base) - panic("Could not ioremap I/O port range"); - - set_io_port_base(io_v_base); - } - - return 0; -} - -arch_initcall(ocelot_c_pci_init); diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c index 78872c3f3760..b96ac8e119dc 100644 --- a/drivers/mtd/devices/docprobe.c +++ b/drivers/mtd/devices/docprobe.c @@ -84,7 +84,7 @@ static unsigned long __initdata doc_locations[] = { #elif defined(CONFIG_MOMENCO_OCELOT) 0x2f000000, 0xff000000, -#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) +#elif defined(CONFIG_MOMENCO_OCELOT_G) 0xff000000, ##else #warning Unknown architecture for DiskOnChip. No default probe locations defined diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 595208f965a5..17c868034aad 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -59,7 +59,7 @@ static unsigned long __initdata doc_locations[] = { #elif defined(CONFIG_MOMENCO_OCELOT) 0x2f000000, 0xff000000, -#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) +#elif defined(CONFIG_MOMENCO_OCELOT_G) 0xff000000, #else #warning Unknown architecture for DiskOnChip. No default probe locations defined diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5cc3d517e39b..62a1390458c3 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2307,7 +2307,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "MV-643XX Ethernet support" - depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) + depends on MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) select MII help This driver supports the gigabit Ethernet on the Marvell MV643XX diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 476563924fd1..8b76e7602425 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -114,7 +114,7 @@ #define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ #define MACH_MOMENCO_OCELOT 0 #define MACH_MOMENCO_OCELOT_G 1 /* no more supported (may 2007) */ -#define MACH_MOMENCO_OCELOT_C 2 +#define MACH_MOMENCO_OCELOT_C 2 /* no more supported (jun 2007) */ #define MACH_MOMENCO_JAGUAR_ATX 3 /* no more supported (may 2007) */ #define MACH_MOMENCO_OCELOT_3 4 diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 01f1a8213ccc..5b9c8ea977b8 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -97,31 +97,6 @@ #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS #endif -#ifdef CONFIG_MOMENCO_OCELOT_C -/* Ordinary NS16552 duart with a 20MHz crystal. */ -#define OCELOT_C_BASE_BAUD ( 20000000 / 16 ) - -#define OCELOT_C_SERIAL1_IRQ 80 -#define OCELOT_C_SERIAL1_BASE 0xfd000020 - -#define OCELOT_C_SERIAL2_IRQ 81 -#define OCELOT_C_SERIAL2_BASE 0xfd000000 - -#define _OCELOT_C_SERIAL_INIT(int, base) \ - { .baud_base = OCELOT_C_BASE_BAUD, \ - .irq = (int), \ - .flags = STD_COM_FLAGS, \ - .iomem_base = (u8 *) base, \ - .iomem_reg_shift = 2, \ - .io_type = SERIAL_IO_MEM \ - } -#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ - _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \ - _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE) -#else -#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS -#endif - #ifdef CONFIG_DDB5477 #include #define DDB5477_SERIAL_PORT_DEFNS \ @@ -151,7 +126,6 @@ IP32_SERIAL_PORT_DEFNS \ JAZZ_SERIAL_PORT_DEFNS \ STD_SERIAL_PORT_DEFNS \ - MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index ec0eeebd8802..4396b2fb5e2d 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -185,8 +185,8 @@ #if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MOMENCO_JAGUAR_ATX) || \ defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) || \ defined(CONFIG_MOMENCO_OCELOT) || defined(CONFIG_MOMENCO_OCELOT_3) || \ - defined(CONFIG_MOMENCO_OCELOT_C) || defined(CONFIG_PMC_YOSEMITE) || \ - defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC) + defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_SGI_IP32) || \ + defined(CONFIG_WR_PPMC) #define ICACHE_REFILLS_WORKAROUND_WAR 1 #endif From e7c4782f92fc4b83d953ce53f77f05ae65dcd773 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:01 +0100 Subject: [PATCH 499/551] [MIPS] Put an end to 's long and annyoing existence Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 - arch/mips/ddb5xxx/ddb5477/Makefile | 3 +- arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c | 49 ++++++++ arch/mips/gt64120/momenco_ocelot/Makefile | 2 +- .../gt64120/momenco_ocelot/ocelot-platform.c | 46 ++++++++ arch/mips/jazz/Makefile | 2 +- arch/mips/jazz/jazz-platform.c | 60 ++++++++++ arch/mips/kernel/8250-platform.c | 47 ++++++++ arch/mips/kernel/Makefile | 2 + arch/mips/mips-boards/malta/Makefile | 3 +- arch/mips/mips-boards/malta/malta_platform.c | 65 +++++++++++ arch/mips/momentum/ocelot_3/platform.c | 44 +++++++ arch/mips/sgi-ip32/ip32-platform.c | 52 +++++++++ arch/mips/sgi-ip32/ip32-setup.c | 36 ------ include/asm-mips/serial.h | 110 ------------------ 15 files changed, 371 insertions(+), 151 deletions(-) create mode 100644 arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c create mode 100644 arch/mips/gt64120/momenco_ocelot/ocelot-platform.c create mode 100644 arch/mips/jazz/jazz-platform.c create mode 100644 arch/mips/kernel/8250-platform.c create mode 100644 arch/mips/mips-boards/malta/malta_platform.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cba171a5eb03..624c31cd8077 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -155,7 +155,6 @@ config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 - select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT select GENERIC_ISA_DMA select IRQ_CPU diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile index 23fd3b81fe1a..4864b8a659c7 100644 --- a/arch/mips/ddb5xxx/ddb5477/Makefile +++ b/arch/mips/ddb5xxx/ddb5477/Makefile @@ -2,7 +2,8 @@ # Makefile for NEC DDB-Vrc5477 board # -obj-y += irq.o irq_5477.o setup.o lcd44780.o +obj-y += ddb5477-platform.o irq.o irq_5477.o setup.o \ + lcd44780.o obj-$(CONFIG_RUNTIME_DEBUG) += debug.o obj-$(CONFIG_KGDB) += kgdb_io.o diff --git a/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c b/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c new file mode 100644 index 000000000000..c16020ad54c2 --- /dev/null +++ b/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c @@ -0,0 +1,49 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include + +#include + +#define DDB_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) + +#define DDB5477_PORT(base, int) \ +{ \ + .mapbase = base, \ + .irq = int, \ + .uartclk = 1843200, \ + .iotype = UPIO_MEM, \ + .flags = DDB_UART_FLAGS, \ + .regshift = 3, \ +} + +static struct plat_serial8250_port uart8250_data[] = { + DDB5477_PORT(0xbfa04200, VRC5477_IRQ_UART0), + DDB5477_PORT(0xbfa04240, VRC5477_IRQ_UART1), + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the NEC DDB5477"); diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile index 9f9a33fc76b9..1df5fe23c642 100644 --- a/arch/mips/gt64120/momenco_ocelot/Makefile +++ b/arch/mips/gt64120/momenco_ocelot/Makefile @@ -2,6 +2,6 @@ # Makefile for Momentum's Ocelot board. # -obj-y += irq.o prom.o reset.o setup.o +obj-y += irq.o ocelot-platform.o prom.o reset.o setup.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c b/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c new file mode 100644 index 000000000000..81d9031a5a2a --- /dev/null +++ b/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c @@ -0,0 +1,46 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + * + * A NS16552 DUART with a 20MHz crystal. + * + */ +#include +#include +#include + +#define OCELOT_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) + +static struct plat_serial8250_port uart8250_data[] = { + { + .mapbase = 0xe0001020, + .irq = 4, + .uartclk = 20000000, + .iotype = UPIO_MEM, + .flags = OCELOT_UART_FLAGS, + .regshift = 2, + }, + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the Momenco Ocelot"); diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile index dd9d99bfcf7a..ae4c402b5004 100644 --- a/arch/mips/jazz/Makefile +++ b/arch/mips/jazz/Makefile @@ -2,4 +2,4 @@ # Makefile for the Jazz family specific parts of the kernel # -obj-y := irq.o jazzdma.o reset.o setup.o +obj-y := irq.o jazzdma.o jazz-platform.o reset.o setup.o diff --git a/arch/mips/jazz/jazz-platform.c b/arch/mips/jazz/jazz-platform.c new file mode 100644 index 000000000000..fd736703eef2 --- /dev/null +++ b/arch/mips/jazz/jazz-platform.c @@ -0,0 +1,60 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include + +#include + +/* + * Confusion ... It seems the original Microsoft Jazz machine used to have a + * 4.096MHz clock for its UART while the MIPS Magnum and Millenium systems + * had 8MHz. The Olivetti M700-10 and the Acer PICA have 1.8432MHz like PCs. + */ +#ifdef CONFIG_OLIVETTI_M700 +#define JAZZ_BASE_BAUD 1843200 +#else +#define JAZZ_BASE_BAUD 8000000 /* 3072000 */ +#endif + +#define JAZZ_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) + +#define JAZZ_PORT(base, int) \ +{ \ + .mapbase = base, \ + .irq = int, \ + .uartclk = JAZZ_BASE_BAUD, \ + .iotype = UPIO_MEM, \ + .flags = JAZZ_UART_FLAGS, \ + .regshift = 0, \ +} + +static struct plat_serial8250_port uart8250_data[] = { + JAZZ_PORT(JAZZ_SERIAL1_BASE, JAZZ_SERIAL1_IRQ), + JAZZ_PORT(JAZZ_SERIAL2_BASE, JAZZ_SERIAL2_IRQ), + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the Jazz family"); diff --git a/arch/mips/kernel/8250-platform.c b/arch/mips/kernel/8250-platform.c new file mode 100644 index 000000000000..cbf3fe20ad17 --- /dev/null +++ b/arch/mips/kernel/8250-platform.c @@ -0,0 +1,47 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + */ +#include +#include +#include + +#define PORT(base, int) \ +{ \ + .iobase = base, \ + .irq = int, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +static struct plat_serial8250_port uart8250_data[] = { + PORT(0x3F8, 4), + PORT(0x2F8, 3), + PORT(0x3E8, 4), + PORT(0x2E8, 3), + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic 8250 UART probe driver"); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 49246264cc7c..bb25dd8ce437 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -68,3 +68,5 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) + +obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index 377d9e8f250a..a242b0fc377d 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile @@ -19,6 +19,7 @@ # under Linux. # -obj-y := malta_int.o malta_setup.o +obj-y := malta_int.o malta_platform.o malta_setup.o + obj-$(CONFIG_MTD) += malta_mtd.o obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o diff --git a/arch/mips/mips-boards/malta/malta_platform.c b/arch/mips/mips-boards/malta/malta_platform.c new file mode 100644 index 000000000000..83b9bab3cd3f --- /dev/null +++ b/arch/mips/mips-boards/malta/malta_platform.c @@ -0,0 +1,65 @@ +/* + * 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) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle (ralf@linux-mips.org) + * + * Probe driver for the Malta's UART ports: + * + * o 2 ports in the SMC SuperIO + * o 1 port in the CBUS UART, a discrete 16550 which normally is only used + * for bringups. + * + * We don't use 8250_platform.c on Malta as it would result in the CBUS + * UART becoming ttyS0. + */ +#include +#include +#include + +#define SMC_PORT(base, int) \ +{ \ + .iobase = base, \ + .irq = int, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) + +static struct plat_serial8250_port uart8250_data[] = { + SMC_PORT(0x3F8, 4), + SMC_PORT(0x2F8, 3), + { + .mapbase = 0x1f000900, /* The CBUS UART */ + .irq = MIPS_CPU_IRQ_BASE + 2, + .uartclk = 3686400, /* Twice the usual clk! */ + .iotype = UPIO_MEM32, + .flags = CBUS_UART_FLAGS, + .regshift = 3, + }, + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM2, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the Malta CBUS UART"); diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c index 44e4c3fc7403..cb63c82ef650 100644 --- a/arch/mips/momentum/ocelot_3/platform.c +++ b/arch/mips/momentum/ocelot_3/platform.c @@ -1,8 +1,19 @@ +/* + * 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) 2006, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2007 Dale Farnsworth (dale@farnsworth.org) + */ #include #include +#include #include +#include #include #include +#include #include "ocelot_3_fpga.h" @@ -206,3 +217,36 @@ static int __init mv643xx_eth_add_pds(void) device_initcall(mv643xx_eth_add_pds); #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ + +#define OCELOT3_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) + +static struct plat_serial8250_port uart8250_data[] = { + { + .membase = (signed long) 0xfd000020, + .irq = 6, + .uartclk = 20000000, + .iotype = UPIO_MEM, + .flags = OCELOT3_UART_FLAGS, + .regshift = 2, + }, + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the Ocelot 3"); diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 120b15932caf..ba3697ee7ff6 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -1,5 +1,53 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + */ +#include #include #include +#include + +#include +#include + +/* + * .iobase isn't a constant (in the sense of C) so we fill it in at runtime. + */ +#define MACE_PORT(int) \ +{ \ + .irq = int, \ + .uartclk = 1843200, \ + .iotype = UPIO_MEM, \ + .flags = UPF_SKIP_TEST, \ + .regshift = 8, \ +} + +static struct plat_serial8250_port uart8250_data[] = { + MACE_PORT(MACEISA_SERIAL1_IRQ), + MACE_PORT(MACEISA_SERIAL2_IRQ), + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + uart8250_data[0].iobase = (unsigned long) &mace->isa.serial1; + uart8250_data[1].iobase = (unsigned long) &mace->isa.serial1; + + return platform_device_register(&uart8250_device); +} + +device_initcall(uart8250_init); static __init int meth_devinit(void) { @@ -18,3 +66,7 @@ static __init int meth_devinit(void) } device_initcall(meth_devinit); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2"); diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index 57708fe28bd7..bbba066cb405 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c @@ -62,12 +62,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) } #endif -#ifdef CONFIG_SERIAL_8250 -#include -#include -#include -#endif /* CONFIG_SERIAL_8250 */ - /* An arbitrary time; this can be decreased if reliability looks good */ #define WAIT_MS 10 @@ -96,36 +90,6 @@ void __init plat_mem_setup(void) board_time_init = ip32_time_init; -#ifdef CONFIG_SERIAL_8250 - { - static struct uart_port o2_serial[2]; - - memset(o2_serial, 0, sizeof(o2_serial)); - o2_serial[0].type = PORT_16550A; - o2_serial[0].line = 0; - o2_serial[0].irq = MACEISA_SERIAL1_IRQ; - o2_serial[0].flags = UPF_SKIP_TEST; - o2_serial[0].uartclk = 1843200; - o2_serial[0].iotype = UPIO_MEM; - o2_serial[0].membase = (char *)&mace->isa.serial1; - o2_serial[0].fifosize = 14; - /* How much to shift register offset by. Each UART register - * is replicated over 256 byte space */ - o2_serial[0].regshift = 8; - o2_serial[1].type = PORT_16550A; - o2_serial[1].line = 1; - o2_serial[1].irq = MACEISA_SERIAL2_IRQ; - o2_serial[1].flags = UPF_SKIP_TEST; - o2_serial[1].uartclk = 1843200; - o2_serial[1].iotype = UPIO_MEM; - o2_serial[1].membase = (char *)&mace->isa.serial2; - o2_serial[1].fifosize = 14; - o2_serial[1].regshift = 8; - - early_serial_setup(&o2_serial[0]); - early_serial_setup(&o2_serial[1]); - } -#endif #ifdef CONFIG_SGI_O2MACE_ETH { char *mac = ArcGetEnvironmentVariable("eaddr"); diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 5b9c8ea977b8..c07ebd8eb9e7 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -19,114 +19,4 @@ */ #define BASE_BAUD (1843200 / 16) -/* Standard COM flags (except for COM4, because of the 8514 problem) */ -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF -#endif - -#ifdef CONFIG_MACH_JAZZ -#include - -#ifndef CONFIG_OLIVETTI_M700 - /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know - exactly which ones ... XXX */ -#define JAZZ_BASE_BAUD ( 8000000 / 16 ) /* ( 3072000 / 16) */ -#else -/* but the M700 isn't such a strange beast */ -#define JAZZ_BASE_BAUD BASE_BAUD -#endif - -#define _JAZZ_SERIAL_INIT(int, base) \ - { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ - .iomem_base = (u8 *) base, .iomem_reg_shift = 0, \ - .io_type = SERIAL_IO_MEM } -#define JAZZ_SERIAL_PORT_DEFNS \ - _JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE), \ - _JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE), -#else -#define JAZZ_SERIAL_PORT_DEFNS -#endif - -#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT -#define STD_SERIAL_PORT_DEFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - -#else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ -#define STD_SERIAL_PORT_DEFNS -#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ - -#ifdef CONFIG_MOMENCO_OCELOT_3 -#define OCELOT_3_BASE_BAUD ( 20000000 / 16 ) -#define OCELOT_3_SERIAL_IRQ 6 -#define OCELOT_3_SERIAL_BASE (signed)0xfd000020 - -#define _OCELOT_3_SERIAL_INIT(int, base) \ - { .baud_base = OCELOT_3_BASE_BAUD, irq: int, \ - .flags = STD_COM_FLAGS, \ - .iomem_base = (u8 *) base, iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM } - -#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \ - _OCELOT_3_SERIAL_INIT(OCELOT_3_SERIAL_IRQ, OCELOT_3_SERIAL_BASE) -#else -#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS -#endif - -#ifdef CONFIG_MOMENCO_OCELOT -/* Ordinary NS16552 duart with a 20MHz crystal. */ -#define OCELOT_BASE_BAUD ( 20000000 / 16 ) - -#define OCELOT_SERIAL1_IRQ 4 -#define OCELOT_SERIAL1_BASE 0xe0001020 - -#define _OCELOT_SERIAL_INIT(int, base) \ - { .baud_base = OCELOT_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ - .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \ - .io_type = SERIAL_IO_MEM } -#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ - _OCELOT_SERIAL_INIT(OCELOT_SERIAL1_IRQ, OCELOT_SERIAL1_BASE) -#else -#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS -#endif - -#ifdef CONFIG_DDB5477 -#include -#define DDB5477_SERIAL_PORT_DEFNS \ - { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0, \ - .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200, \ - .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, \ - { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1, \ - .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240, \ - .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, -#else -#define DDB5477_SERIAL_PORT_DEFNS -#endif - -#ifdef CONFIG_SGI_IP32 -/* - * The IP32 (SGI O2) has standard serial ports (UART 16550A) mapped in memory - * They are initialized in ip32_setup - */ -#define IP32_SERIAL_PORT_DEFNS \ - {},{}, -#else -#define IP32_SERIAL_PORT_DEFNS -#endif /* CONFIG_SGI_IP32 */ - -#define SERIAL_PORT_DFNS \ - DDB5477_SERIAL_PORT_DEFNS \ - IP32_SERIAL_PORT_DEFNS \ - JAZZ_SERIAL_PORT_DEFNS \ - STD_SERIAL_PORT_DEFNS \ - MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ - MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS - #endif /* _ASM_SERIAL_H */ From d223a86154f8c66f5a380b17e1c8091d56f47cf8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:02 +0100 Subject: [PATCH 500/551] [MIPS] FP affinity: Coding style cleanups Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips-mt.c | 40 ++++++++++++++------------ arch/mips/kernel/traps.c | 59 +++++++++++++++++++------------------- include/asm-mips/system.h | 12 ++++---- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index ba01800b6018..b1b994dd41db 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -109,7 +109,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, read_unlock(&tasklist_lock); /* Compute new global allowed CPU set if necessary */ - if( (p->thread.mflags & MF_FPUBOUND) + if ((p->thread.mflags & MF_FPUBOUND) && cpus_intersects(new_mask, mt_fpu_cpumask)) { cpus_and(effective_mask, new_mask, mt_fpu_cpumask); retval = set_cpus_allowed(p, effective_mask); @@ -195,27 +195,31 @@ void mips_mt_regdump(unsigned long mvpctl) nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; printk("-- per-VPE State --\n"); - for(i = 0; i < nvpe; i++) { - for(tc = 0; tc < ntc; tc++) { + for (i = 0; i < nvpe; i++) { + for (tc = 0; tc < ntc; tc++) { settc(tc); - if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { - printk(" VPE %d\n", i); - printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); - printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); - printk(" VPE%d.Status : %08lx\n", - i, read_vpe_c0_status()); - printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); - printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); - printk(" VPE%d.Config7 : %08lx\n", - i, read_vpe_c0_config7()); - break; /* Next VPE */ + if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { + printk(" VPE %d\n", i); + printk(" VPEControl : %08lx\n", + read_vpe_c0_vpecontrol()); + printk(" VPEConf0 : %08lx\n", + read_vpe_c0_vpeconf0()); + printk(" VPE%d.Status : %08lx\n", + i, read_vpe_c0_status()); + printk(" VPE%d.EPC : %08lx\n", + i, read_vpe_c0_epc()); + printk(" VPE%d.Cause : %08lx\n", + i, read_vpe_c0_cause()); + printk(" VPE%d.Config7 : %08lx\n", + i, read_vpe_c0_config7()); + break; /* Next VPE */ + } } - } } printk("-- per-TC State --\n"); - for(tc = 0; tc < ntc; tc++) { + for (tc = 0; tc < ntc; tc++) { settc(tc); - if(read_tc_c0_tcbind() == read_c0_tcbind()) { + if (read_tc_c0_tcbind() == read_c0_tcbind()) { /* Are we dumping ourself? */ haltval = 0; /* Then we're not halted, and mustn't be */ tcstatval = flags; /* And pre-dump TCStatus is flags */ @@ -384,7 +388,7 @@ void mips_mt_set_cpuoptions(void) mt_fpemul_threshold = fpaff_threshold; } else { mt_fpemul_threshold = - (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; + (FPUSEFACTOR * (loops_per_jiffy / (500000 / HZ))) / HZ; } printk("FPU Affinity set after %ld emulations\n", mt_fpemul_threshold); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 7e9cb5b1b4a7..c598e890a880 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -752,6 +752,33 @@ asmlinkage void do_ri(struct pt_regs *regs) force_sig(SIGILL, current); } +/* + * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've + * emulated more than some threshold number of instructions, force migration to + * a "CPU" that has FP support. + */ +static void mt_ase_fp_affinity(void) +{ +#ifdef CONFIG_MIPS_MT_FPAFF + if (mt_fpemul_threshold > 0 && + ((current->thread.emulated_fp++ > mt_fpemul_threshold))) { + /* + * If there's no FPU present, or if the application has already + * restricted the allowed set to exclude any CPUs with FPUs, + * we'll skip the procedure. + */ + if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) { + cpumask_t tmask; + + cpus_and(tmask, current->thread.user_cpus_allowed, + mt_fpu_cpumask); + set_cpus_allowed(current, tmask); + current->thread.mflags |= MF_FPUBOUND; + } + } +#endif /* CONFIG_MIPS_MT_FPAFF */ +} + asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; @@ -785,36 +812,8 @@ asmlinkage void do_cpu(struct pt_regs *regs) ¤t->thread.fpu, 0); if (sig) force_sig(sig, current); -#ifdef CONFIG_MIPS_MT_FPAFF - else { - /* - * MIPS MT processors may have fewer FPU contexts - * than CPU threads. If we've emulated more than - * some threshold number of instructions, force - * migration to a "CPU" that has FP support. - */ - if(mt_fpemul_threshold > 0 - && ((current->thread.emulated_fp++ - > mt_fpemul_threshold))) { - /* - * If there's no FPU present, or if the - * application has already restricted - * the allowed set to exclude any CPUs - * with FPUs, we'll skip the procedure. - */ - if (cpus_intersects(current->cpus_allowed, - mt_fpu_cpumask)) { - cpumask_t tmask; - - cpus_and(tmask, - current->thread.user_cpus_allowed, - mt_fpu_cpumask); - set_cpus_allowed(current, tmask); - current->thread.mflags |= MF_FPUBOUND; - } - } - } -#endif /* CONFIG_MIPS_MT_FPAFF */ + else + mt_ase_fp_affinity(); } return; diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index bb0b289dbc9e..9b3a8dd2c3db 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -44,7 +44,7 @@ struct task_struct; * different thread. */ -#define switch_to(prev,next,last) \ +#define __mips_mt_fpaff_switch_to(prev) \ do { \ if (cpu_has_fpu && \ (prev->thread.mflags & MF_FPUBOUND) && \ @@ -52,24 +52,22 @@ do { \ prev->thread.mflags &= ~MF_FPUBOUND; \ prev->cpus_allowed = prev->thread.user_cpus_allowed; \ } \ - if (cpu_has_dsp) \ - __save_dsp(prev); \ next->thread.emulated_fp = 0; \ - (last) = resume(prev, next, task_thread_info(next)); \ - if (cpu_has_dsp) \ - __restore_dsp(current); \ } while(0) #else +#define __mips_mt_fpaff_switch_to(prev) do { (prev); } while (0) +#endif + #define switch_to(prev,next,last) \ do { \ + __mips_mt_fpaff_switch_to(prev); \ if (cpu_has_dsp) \ __save_dsp(prev); \ (last) = resume(prev, next, task_thread_info(next)); \ if (cpu_has_dsp) \ __restore_dsp(current); \ } while(0) -#endif /* * On SMP systems, when the scheduler does migration-cost autodetection, From a36920200c5b89d56120a5e839fe4a603d51b16c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:02 +0100 Subject: [PATCH 501/551] [MIPS] Enable support for the userlocal hardware register Which will cut down the cost of RDHWR $29 which is used to obtain the TLS pointer and so far being emulated in software down to a single cycle operation. Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 2 ++ arch/mips/kernel/syscall.c | 5 ++--- arch/mips/kernel/traps.c | 9 ++++++++- include/asm-mips/cpu-features.h | 4 ++++ include/asm-mips/cpu.h | 1 + include/asm-mips/mipsregs.h | 6 +++++- include/asm-mips/system.h | 2 ++ 7 files changed, 24 insertions(+), 5 deletions(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b12eeee0e974..27fc1843423e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -588,6 +588,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) c->options |= MIPS_CPU_VEIC; if (config3 & MIPS_CONF3_MT) c->ases |= MIPS_ASE_MIPSMT; + if (config3 & MIPS_CONF3_ULRI) + c->options |= MIPS_CPU_ULRI; return config3 & MIPS_CONF_M; } diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 9dd5a2df8eac..b947c61c0cc8 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -272,9 +272,8 @@ asmlinkage int sys_set_thread_area(unsigned long addr) struct thread_info *ti = task_thread_info(current); ti->tp_value = addr; - - /* If some future MIPS implementation has this register in hardware, - * we will need to update it here (and in context switches). */ + if (cpu_has_userlocal) + write_c0_userlocal(addr); return 0; } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c598e890a880..9b19a84d11ef 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1341,7 +1341,14 @@ void __init per_cpu_trap_init(void) set_c0_status(ST0_MX); #ifdef CONFIG_CPU_MIPSR2 - write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ + if (cpu_has_mips_r2) { + unsigned int enable = 0x0000000f; + + if (cpu_has_userlocal) + enable |= (1 << 29); + + write_c0_hwrena(enable); + } #endif #ifdef CONFIG_MIPS_MT_SMTC diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index 5e4bed123b48..d95a83e3e1d7 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h @@ -150,6 +150,10 @@ #define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT) #endif +#ifndef cpu_has_userlocal +#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI) +#endif + #ifdef CONFIG_32BIT # ifndef cpu_has_nofpuex # define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX) diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 2924069075e0..49c1f0011863 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -257,6 +257,7 @@ #define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */ #define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */ #define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */ +#define MIPS_CPU_ULRI 0x00400000 /* CPU has ULRI feature */ /* * CPU ASE encodings diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 89c81922d47c..668db02c2804 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -7,7 +7,7 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Modified for further R[236]000 support by Paul M. Antoine, 1996. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2000, 07 MIPS Technologies, Inc. * Copyright (C) 2003, 2004 Maciej W. Rozycki */ #ifndef _ASM_MIPSREGS_H @@ -533,6 +533,7 @@ #define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) #define MIPS_CONF3_DSP (_ULCAST_(1) << 10) +#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) #define MIPS_CONF7_WII (_ULCAST_(1) << 31) @@ -772,6 +773,9 @@ do { \ #define read_c0_context() __read_ulong_c0_register($4, 0) #define write_c0_context(val) __write_ulong_c0_register($4, 0, val) +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + #define read_c0_pagemask() __read_32bit_c0_register($5, 0) #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 9b3a8dd2c3db..be64fc55562a 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -67,6 +67,8 @@ do { \ (last) = resume(prev, next, task_thread_info(next)); \ if (cpu_has_dsp) \ __restore_dsp(current); \ + if (cpu_has_userlocal) \ + write_c0_userlocal(task_thread_info(current)->tp_value);\ } while(0) /* From fee578fad1a29e6a149659e5467aedcae6897c06 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 17:33:02 +0100 Subject: [PATCH 502/551] [MIPS] Convert init_thread initialization to ISO C initializers. Signed-off-by: Ralf Baechle --- include/asm-mips/processor.h | 90 +++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 3a466dc7b7db..1d8b9a8ae324 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -82,10 +82,6 @@ struct mips_fpu_struct { unsigned int fcr31; }; -#define INIT_FPU { \ - {0,} \ -} - #define NUM_DSP_REGS 6 typedef __u32 dspreg_t; @@ -95,8 +91,6 @@ struct mips_dsp_state { unsigned int dspcontrol; }; -#define INIT_DSP {{0,},} - #define INIT_CPUMASK { \ {0,} \ } @@ -155,41 +149,63 @@ struct thread_struct { #define MF_N64 0 #ifdef CONFIG_MIPS_MT_FPAFF -#define FPAFF_INIT 0, INIT_CPUMASK, +#define FPAFF_INIT \ + .emulated_fp = 0, \ + .user_cpus_allowed = INIT_CPUMASK, #else #define FPAFF_INIT #endif /* CONFIG_MIPS_MT_FPAFF */ -#define INIT_THREAD { \ - /* \ - * saved main processor registers \ - */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, \ - /* \ - * saved cp0 stuff \ - */ \ - 0, \ - /* \ - * saved fpu/fpu emulator stuff \ - */ \ - INIT_FPU, \ - /* \ - * fpu affinity state (null if not FPAFF) \ - */ \ - FPAFF_INIT \ - /* \ - * saved dsp/dsp emulator stuff \ - */ \ - INIT_DSP, \ - /* \ - * Other stuff associated with the process \ - */ \ - 0, 0, 0, 0, \ - /* \ - * For now the default is to fix address errors \ - */ \ - MF_FIXADE, 0, 0 \ +#define INIT_THREAD { \ + /* \ + * Saved main processor registers \ + */ \ + .reg16 = 0, \ + .reg17 = 0, \ + .reg18 = 0, \ + .reg19 = 0, \ + .reg20 = 0, \ + .reg21 = 0, \ + .reg22 = 0, \ + .reg23 = 0, \ + .reg29 = 0, \ + .reg30 = 0, \ + .reg31 = 0, \ + /* \ + * Saved cp0 stuff \ + */ \ + .cp0_status = 0, \ + /* \ + * Saved FPU/FPU emulator stuff \ + */ \ + .fpu = { \ + .fpr = {0,}, \ + .fcr31 = 0, \ + }, \ + /* \ + * FPU affinity state (null if not FPAFF) \ + */ \ + FPAFF_INIT \ + /* \ + * Saved DSP stuff \ + */ \ + .dsp = { \ + .dspr = {0, }, \ + .dspcontrol = 0, \ + }, \ + /* \ + * Other stuff associated with the process \ + */ \ + .cp0_badvaddr = 0, \ + .cp0_baduaddr = 0, \ + .error_code = 0, \ + .trap_no = 0, \ + /* \ + * For now the default is to fix address errors \ + */ \ + .mflags = MF_FIXADE, \ + .irix_trampoline = 0, \ + .irix_oldctx = 0, \ } struct task_struct; From 2a21c7300b53b744d16903256a172d9cbcfdd03e Mon Sep 17 00:00:00 2001 From: Fuxin Zhang Date: Wed, 6 Jun 2007 14:52:43 +0800 Subject: [PATCH 503/551] [MIPS] define Hit_Invalidate_I to Index_Invalidate_I for loongson2 Signed-off-by: Fuxin Zhang Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 22 +++++++++++++++ arch/mips/Makefile | 1 + arch/mips/kernel/Makefile | 13 +++++---- arch/mips/kernel/cpu-probe.c | 8 ++++++ arch/mips/kernel/proc.c | 1 + arch/mips/lib/Makefile | 1 + arch/mips/mm/Makefile | 1 + arch/mips/mm/c-r4k.c | 54 ++++++++++++++++++++++++++++++++++++ arch/mips/mm/tlb-r4k.c | 23 ++++++++++++++- arch/mips/mm/tlbex.c | 8 ++++-- include/asm-mips/cacheops.h | 4 +++ include/asm-mips/cpu.h | 7 ++++- include/asm-mips/module.h | 2 ++ 13 files changed, 134 insertions(+), 11 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 624c31cd8077..c8d954d6f2c4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -894,6 +894,16 @@ choice prompt "CPU type" default CPU_R4X00 +config CPU_LOONGSON2 + bool "Loongson 2" + depends on SYS_HAS_CPU_LOONGSON2 + select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM + help + The Loongson 2E processor implements the MIPS III instruction set + with many extensions. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1104,6 +1114,9 @@ config CPU_SB1 endchoice +config SYS_HAS_CPU_LOONGSON2 + bool + config SYS_HAS_CPU_MIPS32_R1 bool @@ -1438,6 +1451,15 @@ config CPU_HAS_SMARTMIPS config CPU_HAS_WB bool +config 64BIT_CONTEXT + bool "Save 64bit integer registers" + depends on 32BIT && CPU_LOONGSON2 + help + Loongson2 CPU is 64bit , when used in 32BIT mode, its integer + registers can still be accessed as 64bit, mainly for multimedia + instructions. We must have all 64bit save/restored to make sure + those instructions to get correct result. + # # Vectored interrupt mode is an R2 feature # diff --git a/arch/mips/Makefile b/arch/mips/Makefile index fc09769b3dd4..1e4579cc54ef 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -118,6 +118,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap +cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ -Wa,-mips32 -Wa,--trap cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index bb25dd8ce437..73983eee1431 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -14,14 +14,15 @@ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o +obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o @@ -29,9 +30,9 @@ obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o +obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 27fc1843423e..23d8a3b7dd75 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -485,6 +485,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) MIPS_CPU_LLSC; c->tlbsize = 64; break; + case PRID_IMP_LOONGSON2: + c->cputype = CPU_LOONGSON2; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | + MIPS_CPU_FPU | MIPS_CPU_LLSC | + MIPS_CPU_32FPR; + c->tlbsize = 64; + break; } } diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index eb7730d67934..ec04f5a1a5ea 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -83,6 +83,7 @@ static const char *cpu_name[] = { [CPU_VR4181A] = "NEC VR4181A", [CPU_SR71000] = "Sandcraft SR71000", [CPU_PR4450] = "Philips PR4450", + [CPU_LOONGSON2] = "ICT Loongson-2", }; diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 1a484e430b3c..91ed1eb33102 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -8,6 +8,7 @@ lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \ obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o +obj-$(CONFIG_CPU_LOONGSON2) += dump_tlb.o obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 293697b15603..19a0e544c4e9 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o obj-$(CONFIG_HIGHMEM) += highmem.o +obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index df04a315d830..be96231dccb6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -335,6 +335,10 @@ static void r4k_flush_cache_all(void) static inline void local_r4k___flush_cache_all(void * args) { +#if defined(CONFIG_CPU_LOONGSON2) + r4k_blast_scache(); + return; +#endif r4k_blast_dcache(); r4k_blast_icache(); @@ -848,6 +852,24 @@ static void __init probe_pcache(void) c->options |= MIPS_CPU_PREFETCH; break; + case CPU_LOONGSON2: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + if (prid & 0x3) + c->icache.ways = 4; + else + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + if (prid & 0x3) + c->dcache.ways = 4; + else + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + default: if (!(config & MIPS_CONF_M)) panic("Don't know how to probe P-caches on this cpu."); @@ -963,6 +985,14 @@ static void __init probe_pcache(void) break; } +#ifdef CONFIG_CPU_LOONGSON2 + /* + * LOONGSON2 has 4 way icache, but when using indexed cache op, + * one op will act on all 4 ways + */ + c->icache.ways = 1; +#endif + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", icache_size >> 10, cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", @@ -1036,6 +1066,24 @@ static int __init probe_scache(void) return 1; } +#if defined(CONFIG_CPU_LOONGSON2) +static void __init loongson2_sc_init(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + scache_size = 512*1024; + c->scache.linesz = 32; + c->scache.ways = 4; + c->scache.waybit = 0; + c->scache.waysize = scache_size / (c->scache.ways); + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); + pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + c->options |= MIPS_CPU_INCLUSIVE_CACHES; +} +#endif + extern int r5k_sc_init(void); extern int rm7k_sc_init(void); extern int mips_sc_init(void); @@ -1085,6 +1133,12 @@ static void __init setup_scache(void) #endif return; +#if defined(CONFIG_CPU_LOONGSON2) + case CPU_LOONGSON2: + loongson2_sc_init(); + return; +#endif + default: if (c->isa_level == MIPS_CPU_ISA_M32R1 || c->isa_level == MIPS_CPU_ISA_M32R2 || diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 65160d4984d9..dcd6913dc1ff 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void); #endif /* CONFIG_MIPS_MT_SMTC */ +#if defined(CONFIG_CPU_LOONGSON2) +/* + * LOONGSON2 has a 4 entry itlb which is a subset of dtlb, + * unfortrunately, itlb is not totally transparent to software. + */ +#define FLUSH_ITLB write_c0_diag(4); + +#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC) write_c0_diag(4); } + +#else + +#define FLUSH_ITLB +#define FLUSH_ITLB_VM(vma) + +#endif + void local_flush_tlb_all(void) { unsigned long flags; @@ -73,6 +89,7 @@ void local_flush_tlb_all(void) } tlbw_use_hazard(); write_c0_entryhi(old_ctx); + FLUSH_ITLB; EXIT_CRITICAL(flags); } @@ -136,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, } else { drop_mmu_context(mm, cpu); } + FLUSH_ITLB; EXIT_CRITICAL(flags); } } @@ -178,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) } else { local_flush_tlb_all(); } + FLUSH_ITLB; EXIT_CRITICAL(flags); } @@ -210,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) finish: write_c0_entryhi(oldpid); + FLUSH_ITLB_VM(vma); EXIT_CRITICAL(flags); } } @@ -241,7 +261,7 @@ void local_flush_tlb_one(unsigned long page) tlbw_use_hazard(); } write_c0_entryhi(oldpid); - + FLUSH_ITLB; EXIT_CRITICAL(flags); } @@ -293,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) else tlb_write_indexed(); tlbw_use_hazard(); + FLUSH_ITLB_VM(vma); EXIT_CRITICAL(flags); } diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index e7149290d1cb..4ec0964b8394 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -893,6 +893,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l, case CPU_4KSC: case CPU_20KC: case CPU_25KF: + case CPU_LOONGSON2: tlbw(p); break; @@ -1276,7 +1277,8 @@ static void __init build_r4000_tlb_refill_handler(void) * need three, with the second nop'ed and the third being * unused. */ -#ifdef CONFIG_32BIT + /* Loongson2 ebase is different than r4k, we have more space */ +#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2) if ((p - tlb_handler) > 64) panic("TLB refill handler space exceeded"); #else @@ -1289,7 +1291,7 @@ static void __init build_r4000_tlb_refill_handler(void) /* * Now fold the handler in the TLB refill handler space. */ -#ifdef CONFIG_32BIT +#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2) f = final_handler; /* Simplest case, just copy the handler. */ copy_handler(relocs, labels, tlb_handler, p, f); @@ -1336,7 +1338,7 @@ static void __init build_r4000_tlb_refill_handler(void) final_len); f = final_handler; -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2) if (final_len > 32) final_len = 64; else diff --git a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h index c4a1ec31ff6a..df7f2deb3b56 100644 --- a/include/asm-mips/cacheops.h +++ b/include/asm-mips/cacheops.h @@ -20,7 +20,11 @@ #define Index_Load_Tag_D 0x05 #define Index_Store_Tag_I 0x08 #define Index_Store_Tag_D 0x09 +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else #define Hit_Invalidate_I 0x10 +#endif #define Hit_Invalidate_D 0x11 #define Hit_Writeback_Inv_D 0x15 diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 49c1f0011863..a3623954dad1 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -89,6 +89,8 @@ #define PRID_IMP_34K 0x9500 #define PRID_IMP_24KE 0x9600 #define PRID_IMP_74K 0x9700 +#define PRID_IMP_LOONGSON1 0x4200 +#define PRID_IMP_LOONGSON2 0x6300 /* * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE @@ -211,7 +213,10 @@ #define CPU_SB1A 62 #define CPU_74K 63 #define CPU_R14000 64 -#define CPU_LAST 64 +#define CPU_LOONGSON1 65 +#define CPU_LOONGSON2 66 + +#define CPU_LAST 66 /* * ISA Level encodings diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h index c5ef324fd69f..de6d09ebbd80 100644 --- a/include/asm-mips/module.h +++ b/include/asm-mips/module.h @@ -112,6 +112,8 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "RM9000 " #elif defined CONFIG_CPU_SB1 #define MODULE_PROC_FAMILY "SB1 " +#elif defined CONFIG_CPU_LOONGSON2 +#define MODULE_PROC_FAMILY "LOONGSON2 " #else #error MODULE_PROC_FAMILY undefined for your processor configuration #endif From 42d226c7248a28ff8c478c06b7e9bd9ef5d73574 Mon Sep 17 00:00:00 2001 From: Songmao Tian Date: Wed, 6 Jun 2007 14:52:38 +0800 Subject: [PATCH 504/551] [MIPS] New files for lemote fulong mini-PC support Signed-off-by: Fuxin Zhang Signed-off-by: Songmao Tian Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 23 + arch/mips/Makefile | 7 + arch/mips/configs/fulong_defconfig | 1767 ++++++++++++++++++ arch/mips/lemote/lm2e/Makefile | 7 + arch/mips/lemote/lm2e/bonito-irq.c | 74 + arch/mips/lemote/lm2e/dbg_io.c | 146 ++ arch/mips/lemote/lm2e/irq.c | 145 ++ arch/mips/lemote/lm2e/mem.c | 23 + arch/mips/lemote/lm2e/pci.c | 93 + arch/mips/lemote/lm2e/prom.c | 104 ++ arch/mips/lemote/lm2e/reset.c | 41 + arch/mips/lemote/lm2e/setup.c | 134 ++ arch/mips/pci/Makefile | 1 + arch/mips/pci/fixup-lm2e.c | 242 +++ arch/mips/pci/ops-bonito64.c | 90 +- include/asm-mips/bootinfo.h | 6 + include/asm-mips/mach-lemote/dma-coherence.h | 42 + include/asm-mips/mach-lemote/mc146818rtc.h | 36 + include/asm-mips/mips-boards/bonito64.h | 7 +- 19 files changed, 2931 insertions(+), 57 deletions(-) create mode 100644 arch/mips/configs/fulong_defconfig create mode 100644 arch/mips/lemote/lm2e/Makefile create mode 100644 arch/mips/lemote/lm2e/bonito-irq.c create mode 100644 arch/mips/lemote/lm2e/dbg_io.c create mode 100644 arch/mips/lemote/lm2e/irq.c create mode 100644 arch/mips/lemote/lm2e/mem.c create mode 100644 arch/mips/lemote/lm2e/pci.c create mode 100644 arch/mips/lemote/lm2e/prom.c create mode 100644 arch/mips/lemote/lm2e/reset.c create mode 100644 arch/mips/lemote/lm2e/setup.c create mode 100644 arch/mips/pci/fixup-lm2e.c create mode 100644 include/asm-mips/mach-lemote/dma-coherence.h create mode 100644 include/asm-mips/mach-lemote/mc146818rtc.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c8d954d6f2c4..3994f611ec26 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -15,6 +15,29 @@ choice prompt "System type" default SGI_IP22 +config LEMOTE_FULONG + bool "Lemote Fulong mini-PC" + select ARCH_SPARSEMEM_ENABLE + select SYS_HAS_CPU_LOONGSON2 + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select CPU_HAS_WB + help + Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and + an FPGA northbridge + config MACH_ALCHEMY bool "Alchemy processor based machines" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 1e4579cc54ef..6642ee5fdc46 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -290,6 +290,13 @@ core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/ cflags-$(CONFIG_WR_PPMC) += -Iinclude/asm-mips/mach-wrppmc load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 +# +# lemote fulong mini-PC board +# +core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/ +load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000 +cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote + # # For all MIPS, Inc. eval boards # diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig new file mode 100644 index 000000000000..549f61b5896a --- /dev/null +++ b/arch/mips/configs/fulong_defconfig @@ -0,0 +1,1767 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22-rc4 +# Mon Jun 11 00:23:51 2007 +# +CONFIG_MIPS=y + +# +# Machine selection +# +CONFIG_LEMOTE_FULONG=y +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +CONFIG_CPU_LOONGSON2=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_LOONGSON2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_VPE_LOADER is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="lm32" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ISA=y +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +# CONFIG_BUILD_ELF64 is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK_ENABLED is not set +# CONFIG_NF_CONNTRACK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_CRYPT_CCMP is not set +# CONFIG_IEEE80211_CRYPT_TKIP is not set +# CONFIG_IEEE80211_SOFTMAC is not set +# CONFIG_RFKILL is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x1fc00000 +CONFIG_MTD_PHYSMAP_LEN=0x80000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m + +# +# Misc devices +# +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_BLINK is not set +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +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=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDESCSI=y +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_ATA is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_FIXED_PHY is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=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=y +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# 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_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +CONFIG_I2C_VIAPRO=m +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set +# CONFIG_HWMON is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +# CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_W9968CF is not set +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +# CONFIG_USB_ZR364XX is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_RADEON=y +# CONFIG_FB_RADEON_I2C is not set +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_SMIVGX is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_RTCTIMER=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=m +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# ALSA MIPS devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT2_FS_XIP=y +CONFIG_FS_XIP=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS 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=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp936" +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DEBUG2=y +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +# 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=y +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile new file mode 100644 index 000000000000..fb1b48c48cb3 --- /dev/null +++ b/arch/mips/lemote/lm2e/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Lemote Fulong mini-PC board. +# + +obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o +EXTRA_AFLAGS := $(CFLAGS) + diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/lemote/lm2e/bonito-irq.c new file mode 100644 index 000000000000..8fc3bce7075b --- /dev/null +++ b/arch/mips/lemote/lm2e/bonito-irq.c @@ -0,0 +1,74 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include + +#include + + +static inline void bonito_irq_enable(unsigned int irq) +{ + BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE)); + mmiowb(); +} + +static inline void bonito_irq_disable(unsigned int irq) +{ + BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + mmiowb(); +} + +static struct irq_chip bonito_irq_type = { + .name = "bonito_irq", + .ack = bonito_irq_disable, + .mask = bonito_irq_disable, + .mask_ack = bonito_irq_disable, + .unmask = bonito_irq_enable, +}; + +static struct irqaction dma_timeout_irqaction = { + .handler = no_action, + .name = "dma_timeout", +}; + +void bonito_irq_init(void) +{ + u32 i; + + for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) { + set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); + } + + setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); +} diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c new file mode 100644 index 000000000000..6c95da3ca76f --- /dev/null +++ b/arch/mips/lemote/lm2e/dbg_io.c @@ -0,0 +1,146 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include + +#include + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ +#ifdef CONFIG_64BIT +#define BASE (0xffffffffbfd003f8) +#else +#define BASE (0xbfd003f8) +#endif + +#define MAX_BAUD BASE_BAUD +/* === END OF CONFIG === */ + +#define REG_OFFSET 1 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) readb((char *)BASE + (y)) +#define UART16550_WRITE(y, z) writeb(z, (char *)BASE + (y)) + +void debugInit(u32 baud, u8 data, u8 parity, u8 stop) +{ + u32 divisor; + + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized; + +u8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ; + return UART16550_READ(OFS_RCV_BUFFER); +} + +int putDebugChar(u8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + /* + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); */ + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ; + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c new file mode 100644 index 000000000000..05693bceaeaf --- /dev/null +++ b/arch/mips/lemote/lm2e/irq.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +/* + * the first level int-handler will jump here if it is a bonito irq + */ +static void bonito_irqdispatch(void) +{ + u32 int_status; + int i; + + /* workaround the IO dma problem: let cpu looping to allow DMA finish */ + int_status = BONITO_INTISR; + if (int_status & (1 << 10)) { + while (int_status & (1 << 10)) { + udelay(1); + int_status = BONITO_INTISR; + } + } + + /* Get pending sources, masked by current enables */ + int_status = BONITO_INTISR & BONITO_INTEN; + + if (int_status != 0) { + i = __ffs(int_status); + int_status &= ~(1 << i); + do_IRQ(BONITO_IRQ_BASE + i); + } +} + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = i8259_irq(); + if (irq >= 0) { + do_IRQ(irq); + } else { + spurious_interrupt(); + } + +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) { + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + } else if (pending & CAUSEF_IP5) { + i8259_irqdispatch(); + } else if (pending & CAUSEF_IP2) { + bonito_irqdispatch(); + } else { + spurious_interrupt(); + } +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "cascade", +}; + +void __init arch_init_irq(void) +{ + extern void bonito_irq_init(void); + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* most bonito irq should be level triggered */ + BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR | + BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES; + BONITO_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + BONITO_INTENCLR = ~0; + + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* + printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE); + printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n", + BONITO_INTEN, BONITO_INTENSET, + BONITO_INTENCLR, BONITO_INTISR); + */ + + /* bonito irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); + /* 8259 irq at IP5 */ + setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); + +} diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/lemote/lm2e/mem.c new file mode 100644 index 000000000000..16cd21587d34 --- /dev/null +++ b/arch/mips/lemote/lm2e/mem.c @@ -0,0 +1,23 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +/* override of arch/mips/mm/cache.c: __uncached_access */ +int __uncached_access(struct file *file, unsigned long addr) +{ + if (file->f_flags & O_SYNC) + return 1; + + /* + * On the Lemote Loongson 2e system, the peripheral registers + * reside between 0x1000:0000 and 0x2000:0000. + */ + return addr >= __pa(high_memory) || + ((addr >= 0x10000000) && (addr < 0x20000000)); +} diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c new file mode 100644 index 000000000000..1ade1cef3899 --- /dev/null +++ b/arch/mips/lemote/lm2e/pci.c @@ -0,0 +1,93 @@ +/* + * pci.c + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include + +extern struct pci_ops bonito64_pci_ops; + +static struct resource loongson2e_pci_mem_resource = { + .name = "LOONGSON2E PCI MEM", + .start = 0x14000000UL, + .end = 0x1fffffffUL, + .flags = IORESOURCE_MEM, +}; + +static struct resource loongson2e_pci_io_resource = { + .name = "LOONGSON2E PCI IO MEM", + .start = 0x00004000UL, + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller loongson2e_pci_controller = { + .pci_ops = &bonito64_pci_ops, + .io_resource = &loongson2e_pci_io_resource, + .mem_resource = &loongson2e_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, +}; + +static void __init ict_pcimap(void) +{ + /* + * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON + * + * CPU address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M] + * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0 + */ + /* 1,00 0110 ,0001 01,00 0000 */ + BONITO_PCIMAP = 0x46140; + + /* 1, 00 0010, 0000,01, 00 0000 */ + /* BONITO_PCIMAP = 0x42040; */ + + /* + * PCI to local mapping: [2G,2G+256M] -> [0,256M] + */ + BONITO_PCIBASE0 = 0x80000000; + BONITO_PCIBASE1 = 0x00800000; + BONITO_PCIBASE2 = 0x90000000; + +} + +static int __init pcibios_init(void) +{ + extern int pci_probe_only; + pci_probe_only = 0; + + ict_pcimap(); + register_pci_controller(&loongson2e_pci_controller); + + return 0; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c new file mode 100644 index 000000000000..67312d7acf2a --- /dev/null +++ b/arch/mips/lemote/lm2e/prom.c @@ -0,0 +1,104 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include + +extern unsigned long bus_clock; +extern unsigned long cpu_clock; +extern unsigned int memsize, highmemsize; +extern int putDebugChar(unsigned char byte); + +static int argc; +/* pmon passes arguments in 32bit pointers */ +static int *arg; +static int *env; + +const char *get_system_type(void) +{ + return "lemote-fulong"; +} + +void __init prom_init_cmdline(void) +{ + int i; + long l; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + l = (long)arg[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } +} + +void __init prom_init(void) +{ + long l; + argc = fw_arg0; + arg = (int *)fw_arg1; + env = (int *)fw_arg2; + + mips_machgroup = MACH_GROUP_LEMOTE; + mips_machtype = MACH_LEMOTE_FULONG; + + prom_init_cmdline(); + + if ((strstr(arcs_cmdline, "console=")) == NULL) + strcat(arcs_cmdline, " console=ttyS0,115200"); + if ((strstr(arcs_cmdline, "root=")) == NULL) + strcat(arcs_cmdline, " root=/dev/hda1"); + +#define parse_even_earlier(res, option, p) \ +do { \ + if (strncmp(option, (char *)p, strlen(option)) == 0) \ + res = simple_strtol((char *)p + strlen(option"="), \ + NULL, 10); \ +} while (0) + + l = (long)*env; + while (l != 0) { + parse_even_earlier(bus_clock, "busclock", l); + parse_even_earlier(cpu_clock, "cpuclock", l); + parse_even_earlier(memsize, "memsize", l); + parse_even_earlier(highmemsize, "highmemsize", l); + env++; + l = (long)*env; + } + if (memsize == 0) + memsize = 256; + + pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n", + bus_clock, cpu_clock, memsize, highmemsize); +} + +void __init prom_free_prom_memory(void) +{ +} + +void prom_putchar(char c) +{ + putDebugChar(c); +} diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c new file mode 100644 index 000000000000..099387a3827a --- /dev/null +++ b/arch/mips/lemote/lm2e/reset.c @@ -0,0 +1,41 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + */ +#include + +#include + +static void loongson2e_restart(char *command) +{ +#ifdef CONFIG_32BIT + *(unsigned long *)0xbfe00104 &= ~(1 << 2); + *(unsigned long *)0xbfe00104 |= (1 << 2); +#else + *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2); + *(unsigned long *)0xffffffffbfe00104 |= (1 << 2); +#endif + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +static void loongson2e_halt(void) +{ + while (1) ; +} + +static void loongson2e_power_off(void) +{ + loongson2e_halt(); +} + +void mips_reboot_setup(void) +{ + _machine_restart = loongson2e_restart; + _machine_halt = loongson2e_halt; + pm_power_off = loongson2e_power_off; +} diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c new file mode 100644 index 000000000000..0e4d1fa572b5 --- /dev/null +++ b/arch/mips/lemote/lm2e/setup.c @@ -0,0 +1,134 @@ +/* + * BRIEF MODULE DESCRIPTION + * setup.c - board dependent boot routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_VT +#include +#include +#endif + +extern void mips_reboot_setup(void); + +#ifdef CONFIG_64BIT +#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p))) +#else +#define PTR_PAD(p) (p) +#endif + +unsigned long cpu_clock; +unsigned long bus_clock; +unsigned int memsize; +unsigned int highmemsize = 0; + +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(MIPS_CPU_IRQ_BASE + 7, irq); +} + +static void __init loongson2e_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock / 2; +} + +static unsigned long __init mips_rtc_get_time(void) +{ + return mc146818_get_cmos_time(); +} + +void (*__wbflush)(void); +EXPORT_SYMBOL(__wbflush); + +static void wbflush_loongson2e(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void __init plat_mem_setup(void) +{ + set_io_port_base(PTR_PAD(0xbfd00000)); + + mips_reboot_setup(); + + board_time_init = loongson2e_time_init; + rtc_mips_get_time = mips_rtc_get_time; + + __wbflush = wbflush_loongson2e; + + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +#ifdef CONFIG_64BIT + if (highmemsize > 0) { + add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM); + } +#endif + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + VIDEO_TYPE_VGAC, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif + +} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index a3e741e190f2..276a10b06bb5 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o +obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-lm2e.c new file mode 100644 index 000000000000..e18ae4f574c1 --- /dev/null +++ b/arch/mips/pci/fixup-lm2e.c @@ -0,0 +1,242 @@ +/* + * fixup-lm2e.c + * + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, ICT CAS + * lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include + +/* South bridge slot number is set by the pci probe process */ +static u8 sb_slot = 5; + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = 0; + + if (slot == sb_slot) { + switch (PCI_FUNC(dev->devfn)) { + case 2: + irq = 10; + break; + case 3: + irq = 11; + break; + case 5: + irq = 9; + break; + } + } else { + irq = BONITO_IRQ_BASE + 25 + pin; + } + return irq; + +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static void __init loongson2e_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + /* Configues port 1, 2, 3, 4 to be validate*/ + pci_read_config_dword(pdev, 0xe0, &val); + pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4); + + /* System clock is 48-MHz Oscillator. */ + pci_write_config_dword(pdev, 0xe4, 1 << 5); +} + +static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) +{ + unsigned char c; + + sb_slot = PCI_SLOT(pdev->devfn); + + printk(KERN_INFO "via686b fix: ISA bridge\n"); + + /* Enable I/O Recovery time */ + pci_write_config_byte(pdev, 0x40, 0x08); + + /* Enable ISA refresh */ + pci_write_config_byte(pdev, 0x41, 0x01); + + /* disable ISA line buffer */ + pci_write_config_byte(pdev, 0x45, 0x00); + + /* Gate INTR, and flush line buffer */ + pci_write_config_byte(pdev, 0x46, 0xe0); + + /* Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */ + /* pci_write_config_byte(pdev, 0x47, 0x20); */ + + /* + * enable PCI Delay Transaction, Enable EISA ports 4D0/4D1. + * enable time-out timer + */ + pci_write_config_byte(pdev, 0x47, 0xe6); + + /* + * enable level trigger on pci irqs: 9,10,11,13 + * important! without this PCI interrupts won't work + */ + outb(0x2e, 0x4d1); + + /* 512 K PCI Decode */ + pci_write_config_byte(pdev, 0x48, 0x01); + + /* Wait for PGNT before grant to ISA Master/DMA */ + pci_write_config_byte(pdev, 0x4a, 0x84); + + /* + * Plug'n'Play + * + * Parallel DRQ 3, Floppy DRQ 2 (default) + */ + pci_write_config_byte(pdev, 0x50, 0x0e); + + /* + * IRQ Routing for Floppy and Parallel port + * + * IRQ 6 for floppy, IRQ 7 for parallel port + */ + pci_write_config_byte(pdev, 0x51, 0x76); + + /* IRQ Routing for serial ports (take IRQ 3 and 4) */ + pci_write_config_byte(pdev, 0x52, 0x34); + + /* All IRQ's level triggered. */ + pci_write_config_byte(pdev, 0x54, 0x00); + + /* route PIRQA-D irq */ + pci_write_config_byte(pdev, 0x55, 0x90); /* bit 7-4, PIRQA */ + pci_write_config_byte(pdev, 0x56, 0xba); /* bit 7-4, PIRQC; */ + /* 3-0, PIRQB */ + pci_write_config_byte(pdev, 0x57, 0xd0); /* bit 7-4, PIRQD */ + + /* enable function 5/6, audio/modem */ + pci_read_config_byte(pdev, 0x85, &c); + c &= ~(0x3 << 2); + pci_write_config_byte(pdev, 0x85, c); + + printk(KERN_INFO"via686b fix: ISA bridge done\n"); +} + +static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) +{ + printk(KERN_INFO"via686b fix: IDE\n"); + + /* Modify IDE controller setup */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48); + pci_write_config_byte(pdev, PCI_COMMAND, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + pci_write_config_byte(pdev, 0x40, 0x0b); + /* legacy mode */ + pci_write_config_byte(pdev, 0x42, 0x09); + +#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */ + /* disable read prefetch/write post buffers */ + pci_write_config_byte(pdev, 0x41, 0x02); + + /* use 3/4 as fifo thresh hold */ + pci_write_config_byte(pdev, 0x43, 0x0a); + pci_write_config_byte(pdev, 0x44, 0x00); + + pci_write_config_byte(pdev, 0x45, 0x00); +#else + pci_write_config_byte(pdev, 0x41, 0xc2); + pci_write_config_byte(pdev, 0x43, 0x35); + pci_write_config_byte(pdev, 0x44, 0x1c); + + pci_write_config_byte(pdev, 0x45, 0x10); +#endif + + printk(KERN_INFO"via686b fix: IDE done\n"); +} + +static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev) +{ + /* irq routing */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); +} + +static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev) +{ + /* irq routing */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); +} + +static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev) +{ + unsigned int val; + unsigned char c; + + /* enable IO */ + pci_write_config_byte(pdev, PCI_COMMAND, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + pci_read_config_dword(pdev, 0x4, &val); + pci_write_config_dword(pdev, 0x4, val | 1); + + /* route ac97 IRQ */ + pci_write_config_byte(pdev, 0x3c, 9); + + pci_read_config_byte(pdev, 0x8, &c); + + /* link control: enable link & SGD PCM output */ + pci_write_config_byte(pdev, 0x41, 0xcc); + + /* disable game port, FM, midi, sb, enable write to reg2c-2f */ + pci_write_config_byte(pdev, 0x42, 0x20); + + /* we are using Avance logic codec */ + pci_write_config_word(pdev, 0x2c, 0x1005); + pci_write_config_word(pdev, 0x2e, 0x4710); + pci_read_config_dword(pdev, 0x2c, &val); + + pci_write_config_byte(pdev, 0x42, 0x0); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, + loongson2e_686b_func0_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, + loongson2e_686b_func1_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, + loongson2e_686b_func2_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, + loongson2e_686b_func3_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, + loongson2e_686b_func5_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + loongson2e_nec_fixup); diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c index dc35270b65a2..f742c51acf0d 100644 --- a/arch/mips/pci/ops-bonito64.c +++ b/arch/mips/pci/ops-bonito64.c @@ -29,83 +29,60 @@ #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -/* - * PCI configuration cycle AD bus definition - */ -/* Type 0 */ -#define PCI_CFG_TYPE0_REG_SHF 0 -#define PCI_CFG_TYPE0_FUNC_SHF 8 +#ifdef CONFIG_LEMOTE_FULONG +#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset)) +#define ID_SEL_BEGIN 11 +#else +#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset)) +#define ID_SEL_BEGIN 10 +#endif +#define MAX_DEV_NUM (31 - ID_SEL_BEGIN) -/* Type 1 */ -#define PCI_CFG_TYPE1_REG_SHF 0 -#define PCI_CFG_TYPE1_FUNC_SHF 8 -#define PCI_CFG_TYPE1_DEV_SHF 11 -#define PCI_CFG_TYPE1_BUS_SHF 16 static int bonito64_pcibios_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, int where, u32 * data) { - unsigned char busnum = bus->number; + u32 busnum = bus->number; + u32 addr, type; u32 dummy; - u64 pci_addr; - - /* Algorithmics Bonito64 system controller. */ - - if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) { - /* We number bus 0 devices from 0..21 */ - return -1; - } - - /* Clear cause register bits */ - BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR); - - /* - * Setup pattern to be used as PCI "address" for - * Type 0 cycle - */ - if (busnum == 0) { - /* IDSEL */ - pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10); - } else { - /* Bus number */ - pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF; - - /* Device number */ - pci_addr |= - PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF; - } - - /* Function (same for Type 0/1) */ - pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF; - - /* Register number (same for Type 0/1) */ - pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; if (busnum == 0) { - /* Type 0 */ - BONITO_PCIMAP_CFG = pci_addr >> 16; + /* Type 0 configuration for onboard PCI bus */ + if (device > MAX_DEV_NUM) + return -1; + + addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg; + type = 0; } else { - /* Type 1 */ - BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; + /* Type 1 configuration for offboard PCI bus */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; } - pci_addr &= 0xffff; + /* Clear aborts */ + BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR; + + BONITO_PCIMAP_CFG = (addr >> 16) | type; /* Flush Bonito register block */ dummy = BONITO_PCIMAP_CFG; - iob(); /* sync */ + mmiowb(); - /* Perform access */ + addrp = CFG_SPACE_REG(addr & 0xffff); if (access_type == PCI_ACCESS_WRITE) { - *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data; - + writel(cpu_to_le32(*data), addrp); +#ifndef CONFIG_LEMOTE_FULONG /* Wait till done */ while (BONITO_PCIMSTAT & 0xF); +#endif } else { - *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr); + *data = le32_to_cpu(readl(addrp)); } /* Detect Master/Target abort */ @@ -121,6 +98,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type, } return 0; + } diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 8b76e7602425..12f9d7139ebf 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -207,6 +207,12 @@ #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ +/* + * Valid machtype for group LEMOTE + */ +#define MACH_GROUP_LEMOTE 27 +#define MACH_LEMOTE_FULONG 0 + #define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); diff --git a/include/asm-mips/mach-lemote/dma-coherence.h b/include/asm-mips/mach-lemote/dma-coherence.h new file mode 100644 index 000000000000..7e914777ebc4 --- /dev/null +++ b/include/asm-mips/mach-lemote/dma-coherence.h @@ -0,0 +1,42 @@ +/* + * 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) 2006, 07 Ralf Baechle + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + */ +#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H +#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H + +struct device; + +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) +{ + return virt_to_phys(addr) | 0x80000000; +} + +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) +{ + return page_to_phys(page) | 0x80000000; +} + +static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) +{ + return dma_addr & 0x7fffffff; +} + +static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) +{ +} + +static inline int plat_device_is_coherent(struct device *dev) +{ + return 0; +} + +#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */ diff --git a/include/asm-mips/mach-lemote/mc146818rtc.h b/include/asm-mips/mach-lemote/mc146818rtc.h new file mode 100644 index 000000000000..ed5147e11085 --- /dev/null +++ b/include/asm-mips/mach-lemote/mc146818rtc.h @@ -0,0 +1,36 @@ +/* + * 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) + * + * RTC routines for PC style attached Dallas chip. + */ +#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H +#define __ASM_MACH_LEMOTE_MC146818RTC_H + +#include + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +static inline unsigned char CMOS_READ(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return inb_p(RTC_PORT(1)); +} + +static inline void CMOS_WRITE(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + outb_p(data, RTC_PORT(1)); +} + +#define RTC_ALWAYS_BCD 0 + +#ifndef mc146818_decode_year +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#endif + +#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */ diff --git a/include/asm-mips/mips-boards/bonito64.h b/include/asm-mips/mips-boards/bonito64.h index cd7125610100..dc3fc32eedd8 100644 --- a/include/asm-mips/mips-boards/bonito64.h +++ b/include/asm-mips/mips-boards/bonito64.h @@ -26,7 +26,12 @@ /* offsets from base register */ #define BONITO(x) (x) -#else /* !__ASSEMBLY__ */ +#elif defined(CONFIG_LEMOTE_FULONG) + +#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x))) +#define BONITO_IRQ_BASE 32 + +#else /* * Algorithmics Bonito64 system controller register base. From a4b156d47d204904fa104c3e585b4c67b89195f3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Jun 2007 22:27:04 +0200 Subject: [PATCH 505/551] [MIPS] Removes the few leftovers of the MOMENCO_JAGUAR_ATX removal. Signed-off-by: Adrian Bunk Signed-off-by: Ralf Baechle --- drivers/net/Kconfig | 2 +- include/asm-mips/war.h | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 62a1390458c3..3d5db2597b88 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2307,7 +2307,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "MV-643XX Ethernet support" - depends on MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) + depends on MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) select MII help This driver supports the gigabit Ethernet on the Marvell MV643XX diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index 4396b2fb5e2d..c507f1b8014e 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -169,10 +169,9 @@ /* * On the RM9000 there is a problem which makes the CreateDirtyExclusive - * cache operation unusable on SMP systems. + * eache operation unusable on SMP systems. */ -#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_PMC_YOSEMITE) || \ - defined(CONFIG_BASLER_EXCITE) +#if defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_BASLER_EXCITE) #define RM9000_CDEX_SMP_WAR 1 #endif @@ -182,11 +181,10 @@ * I-cache line worth of instructions being fetched may case spurious * exceptions. */ -#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MOMENCO_JAGUAR_ATX) || \ - defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) || \ - defined(CONFIG_MOMENCO_OCELOT) || defined(CONFIG_MOMENCO_OCELOT_3) || \ - defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_SGI_IP32) || \ - defined(CONFIG_WR_PPMC) +#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MIPS_ATLAS) || \ + defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MOMENCO_OCELOT) || \ + defined(CONFIG_MOMENCO_OCELOT_3) || defined(CONFIG_PMC_YOSEMITE) || \ + defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC) #define ICACHE_REFILLS_WORKAROUND_WAR 1 #endif From 35832e26f95ba14a6b6f0519441c5cb64cca6bf9 Mon Sep 17 00:00:00 2001 From: Marc St-Jean Date: Thu, 14 Jun 2007 15:54:47 -0600 Subject: [PATCH 506/551] [MIPS] PMC MSP71xx core platform Patch to add core platform support for the PMC-Sierra MSP71xx devices. Signed-off-by: Marc St-Jean Signed-off-by: Ralf Baechle --- arch/mips/pmc-sierra/msp71xx/Makefile | 11 + arch/mips/pmc-sierra/msp71xx/msp_elb.c | 46 ++ arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c | 179 +++++ arch/mips/pmc-sierra/msp71xx/msp_irq.c | 124 ++++ arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c | 134 ++++ arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c | 109 +++ arch/mips/pmc-sierra/msp71xx/msp_prom.c | 566 +++++++++++++++ arch/mips/pmc-sierra/msp71xx/msp_setup.c | 256 +++++++ arch/mips/pmc-sierra/msp71xx/msp_time.c | 94 +++ arch/mips/pmc-sierra/msp71xx/msp_usb.c | 150 ++++ .../asm-mips/pmc-sierra/msp71xx/msp_cic_int.h | 151 ++++ include/asm-mips/pmc-sierra/msp71xx/msp_int.h | 43 ++ .../asm-mips/pmc-sierra/msp71xx/msp_prom.h | 176 +++++ .../asm-mips/pmc-sierra/msp71xx/msp_regops.h | 236 +++++++ .../asm-mips/pmc-sierra/msp71xx/msp_regs.h | 667 ++++++++++++++++++ .../asm-mips/pmc-sierra/msp71xx/msp_slp_int.h | 141 ++++ 16 files changed, 3083 insertions(+) create mode 100644 arch/mips/pmc-sierra/msp71xx/Makefile create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_elb.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_irq.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_prom.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_setup.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_time.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_usb.c create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_int.h create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_prom.h create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_regops.h create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_regs.h create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile new file mode 100644 index 000000000000..4bba79c1cc79 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the PMC-Sierra MSP SOCs +# +obj-y += msp_prom.o msp_setup.o msp_irq.o \ + msp_time.o msp_serial.o msp_elb.o +obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o +obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o +obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o +obj-$(CONFIG_PCI) += msp_pci.o +obj-$(CONFIG_MSPETH) += msp_eth.o +obj-$(CONFIG_USB_MSP71XX) += msp_usb.o diff --git a/arch/mips/pmc-sierra/msp71xx/msp_elb.c b/arch/mips/pmc-sierra/msp71xx/msp_elb.c new file mode 100644 index 000000000000..3e9641007216 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_elb.c @@ -0,0 +1,46 @@ +/* + * Sets up the proper Chip Select configuration registers. It is assumed that + * PMON sets up the ADDR and MASK registers properly. + * + * Copyright 2005-2006 PMC-Sierra, Inc. + * Author: Marc St-Jean, Marc_St-Jean@pmc-sierra.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +static int __init msp_elb_setup(void) +{ +#if defined(CONFIG_PMC_MSP7120_GW) \ + || defined(CONFIG_PMC_MSP7120_EVAL) + /* + * Force all CNFG to be identical and equal to CS0, + * according to OPS doc + */ + *CS1_CNFG_REG = *CS2_CNFG_REG = *CS3_CNFG_REG = *CS0_CNFG_REG; +#endif + return 0; +} + +subsys_initcall(msp_elb_setup); diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c new file mode 100644 index 000000000000..6fa85728158b --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c @@ -0,0 +1,179 @@ +/* + * Sets up interrupt handlers for various hardware switches which are + * connected to interrupt lines. + * + * Copyright 2005-2207 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include +#include +#include +#ifdef CONFIG_PMCTWILED +#include +#endif + +/* For hwbutton_interrupt->initial_state */ +#define HWBUTTON_HI 0x1 +#define HWBUTTON_LO 0x2 + +/* + * This struct describes a hardware button + */ +struct hwbutton_interrupt { + char *name; /* Name of button */ + int irq; /* Actual LINUX IRQ */ + int eirq; /* Extended IRQ number (0-7) */ + int initial_state; /* The "normal" state of the switch */ + void (*handle_hi)(void *); /* Handler: switch input has gone HI */ + void (*handle_lo)(void *); /* Handler: switch input has gone LO */ + void *data; /* Optional data to pass to handler */ +}; + +#ifdef CONFIG_PMC_MSP7120_GW +extern void msp_restart(char *); + +static void softreset_push(void *data) +{ + printk(KERN_WARNING "SOFTRESET switch was pushed\n"); + + /* + * In the future you could move this to the release handler, + * timing the difference between the 'push' and 'release', and only + * doing this ungraceful restart if the button has been down for + * a certain amount of time; otherwise doing a graceful restart. + */ + + msp_restart(NULL); +} + +static void softreset_release(void *data) +{ + printk(KERN_WARNING "SOFTRESET switch was released\n"); + + /* Do nothing */ +} + +static void standby_on(void *data) +{ + printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n"); + + /* TODO: Put board in standby mode */ +#ifdef CONFIG_PMCTWILED + msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN); + msp_led_turn_on(MSP_LED_PWRSTANDBY_RED); +#endif +} + +static void standby_off(void *data) +{ + printk(KERN_WARNING + "STANDBY switch was set to OFF (not implemented)\n"); + + /* TODO: Take out of standby mode */ +#ifdef CONFIG_PMCTWILED + msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN); + msp_led_turn_off(MSP_LED_PWRSTANDBY_RED); +#endif +} + +static struct hwbutton_interrupt softreset_sw = { + .name = "Softreset button", + .irq = MSP_INT_EXT0, + .eirq = 0, + .initial_state = HWBUTTON_HI, + .handle_hi = softreset_release, + .handle_lo = softreset_push, + .data = NULL, +}; + +static struct hwbutton_interrupt standby_sw = { + .name = "Standby switch", + .irq = MSP_INT_EXT1, + .eirq = 1, + .initial_state = HWBUTTON_HI, + .handle_hi = standby_off, + .handle_lo = standby_on, + .data = NULL, +}; +#endif /* CONFIG_PMC_MSP7120_GW */ + +static irqreturn_t hwbutton_handler(int irq, void *data) +{ + struct hwbutton_interrupt *hirq = data; + unsigned long cic_ext = *CIC_EXT_CFG_REG; + + if (irq != hirq->irq) + return IRQ_NONE; + + if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) { + /* Interrupt: pin is now HI */ + CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq); + hirq->handle_hi(hirq->data); + } else { + /* Interrupt: pin is now LO */ + CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq); + hirq->handle_lo(hirq->data); + } + + /* + * Invert the POLARITY of this level interrupt to ack the interrupt + * Thus next state change will invoke the opposite message + */ + *CIC_EXT_CFG_REG = cic_ext; + + return IRQ_HANDLED; +} + +static int msp_hwbutton_register(struct hwbutton_interrupt *hirq) +{ + unsigned long cic_ext; + + if (hirq->handle_hi == NULL || hirq->handle_lo == NULL) + return -EINVAL; + + cic_ext = *CIC_EXT_CFG_REG; + CIC_EXT_SET_TRIGGER_LEVEL(cic_ext, hirq->eirq); + if (hirq->initial_state == HWBUTTON_HI) + CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq); + else + CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq); + *CIC_EXT_CFG_REG = cic_ext; + + return request_irq(hirq->irq, hwbutton_handler, SA_INTERRUPT, + hirq->name, (void *)hirq); +} + +static int __init msp_hwbutton_setup(void) +{ +#ifdef CONFIG_PMC_MSP7120_GW + msp_hwbutton_register(&softreset_sw); + msp_hwbutton_register(&standby_sw); +#endif + return 0; +} + +subsys_initcall(msp_hwbutton_setup); diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c new file mode 100644 index 000000000000..734d598a2e3a --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c @@ -0,0 +1,124 @@ +/* + * IRQ vector handles + * + * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +extern void msp_int_handle(void); + +/* SLP bases systems */ +extern void msp_slp_irq_init(void); +extern void msp_slp_irq_dispatch(void); + +/* CIC based systems */ +extern void msp_cic_irq_init(void); +extern void msp_cic_irq_dispatch(void); + +/* + * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded + * hierarchical system. The first level are the direct MIPS interrupts + * and are assigned the interrupt range 0-7. The second level is the SLM + * interrupt controller and is assigned the range 8-39. The third level + * comprises the Peripherial block, the PCI block, the PCI MSI block and + * the SLP. The PCI interrupts and the SLP errors are handled by the + * relevant subsystems so the core interrupt code needs only concern + * itself with the Peripheral block. These are assigned interrupts in + * the range 40-71. + */ + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + u32 pending; + + pending = read_c0_status() & read_c0_cause(); + + /* + * jump to the correct interrupt routine + * These are arranged in priority order and the timer + * comes first! + */ + +#ifdef CONFIG_IRQ_MSP_CIC /* break out the CIC stuff for now */ + if (pending & C_IRQ4) /* do the peripherals first, that's the timer */ + msp_cic_irq_dispatch(); + + else if (pending & C_IRQ0) + do_IRQ(MSP_INT_MAC0); + + else if (pending & C_IRQ1) + do_IRQ(MSP_INT_MAC1); + + else if (pending & C_IRQ2) + do_IRQ(MSP_INT_USB); + + else if (pending & C_IRQ3) + do_IRQ(MSP_INT_SAR); + + else if (pending & C_IRQ5) + do_IRQ(MSP_INT_SEC); + +#else + if (pending & C_IRQ5) + do_IRQ(MSP_INT_TIMER); + + else if (pending & C_IRQ0) + do_IRQ(MSP_INT_MAC0); + + else if (pending & C_IRQ1) + do_IRQ(MSP_INT_MAC1); + + else if (pending & C_IRQ3) + do_IRQ(MSP_INT_VE); + + else if (pending & C_IRQ4) + msp_slp_irq_dispatch(); +#endif + + else if (pending & C_SW0) /* do software after hardware */ + do_IRQ(MSP_INT_SW0); + + else if (pending & C_SW1) + do_IRQ(MSP_INT_SW1); +} + +static struct irqaction cascade_msp = { + .handler = no_action, + .name = "MSP cascade" +}; + + +void __init arch_init_irq(void) +{ + /* initialize the 1st-level CPU based interrupt controller */ + mips_cpu_irq_init(); + +#ifdef CONFIG_IRQ_MSP_CIC + msp_cic_irq_init(); + + /* setup the cascaded interrupts */ + setup_irq(MSP_INT_CIC, &cascade_msp); + setup_irq(MSP_INT_PER, &cascade_msp); +#else + /* setup the 2nd-level SLP register based interrupt controller */ + msp_slp_irq_init(); + + /* setup the cascaded SLP/PER interrupts */ + setup_irq(MSP_INT_SLP, &cascade_msp); + setup_irq(MSP_INT_PER, &cascade_msp); +#endif +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c new file mode 100644 index 000000000000..5175357d0a25 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c @@ -0,0 +1,134 @@ +/* + * This file define the irq handler for MSP SLM subsystem interrupts. + * + * Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c + * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include + +#include +#include + +/* + * NOTE: We are only enabling support for VPE0 right now. + */ + +static inline void unmask_msp_cic_irq(unsigned int irq) +{ + + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE)); + else + *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); +} + +static inline void mask_msp_cic_irq(unsigned int irq) +{ + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE)); + else + *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE)); +} + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for msp_cic_irq_end. + */ +static inline void ack_msp_cic_irq(unsigned int irq) +{ + mask_msp_cic_irq(irq); + + /* + * only really necessary for 18, 16-14 and sometimes 3:0 (since + * these can be edge sensitive) but it doesn't hurt for the others. + */ + + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE)); + else + *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE)); +} + +static struct irq_chip msp_cic_irq_controller = { + .name = "MSP_CIC", + .ack = ack_msp_cic_irq, + .mask = ack_msp_cic_irq, + .mask_ack = ack_msp_cic_irq, + .unmask = unmask_msp_cic_irq, +}; + + +void __init msp_cic_irq_init(void) +{ + int i; + + /* Mask/clear interrupts. */ + *CIC_VPE0_MSK_REG = 0x00000000; + *PER_INT_MSK_REG = 0x00000000; + *CIC_STS_REG = 0xFFFFFFFF; + *PER_INT_STS_REG = 0xFFFFFFFF; + +#if defined(CONFIG_PMC_MSP7120_GW) || \ + defined(CONFIG_PMC_MSP7120_EVAL) + /* + * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. + * These inputs map to EXT_INT_POL[6:4] inside the CIC. + * They are to be active low, level sensitive. + */ + *CIC_EXT_CFG_REG &= 0xFFFF8F8F; +#endif + + /* initialize all the IRQ descriptors */ + for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++) + set_irq_chip_and_handler(i, &msp_cic_irq_controller, + handle_level_irq); +} + +void msp_cic_irq_dispatch(void) +{ + u32 pending; + int intbase; + + intbase = MSP_CIC_INTBASE; + pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG; + + /* check for PER interrupt */ + if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { + intbase = MSP_PER_INTBASE; + pending = *PER_INT_STS_REG & *PER_INT_MSK_REG; + } + + /* check for spurious interrupt */ + if (pending == 0x00000000) { + printk(KERN_ERR + "Spurious %s interrupt? status %08x, mask %08x\n", + (intbase == MSP_CIC_INTBASE) ? "CIC" : "PER", + (intbase == MSP_CIC_INTBASE) ? + *CIC_STS_REG : *PER_INT_STS_REG, + (intbase == MSP_CIC_INTBASE) ? + *CIC_VPE0_MSK_REG : *PER_INT_MSK_REG); + return; + } + + /* check for the timer and dispatch it first */ + if ((intbase == MSP_CIC_INTBASE) && + (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE)))) + do_IRQ(MSP_INT_VPE0_TIMER); + else + do_IRQ(ffs(pending) + intbase - 1); +} + diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c new file mode 100644 index 000000000000..f5f1b8d2bb9a --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c @@ -0,0 +1,109 @@ +/* + * This file define the irq handler for MSP SLM subsystem interrupts. + * + * Copyright 2005-2006 PMC-Sierra, Inc, derived from irq_cpu.c + * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +static inline void unmask_msp_slp_irq(unsigned int irq) +{ + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE)); + else + *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); +} + +static inline void mask_msp_slp_irq(unsigned int irq) +{ + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE)); + else + *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE)); +} + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for msp_slp_irq_end. + */ +static inline void ack_msp_slp_irq(unsigned int irq) +{ + mask_slp_irq(irq); + + /* + * only really necessary for 18, 16-14 and sometimes 3:0 (since + * these can be edge sensitive) but it doesn't hurt for the others. + */ + + /* check for PER interrupt range */ + if (irq < MSP_PER_INTBASE) + *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE)); + else + *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE)); +} + +static struct irq_chip msp_slp_irq_controller = { + .name = "MSP_SLP", + .ack = ack_msp_slp_irq, + .mask = ack_msp_slp_irq, + .mask_ack = ack_msp_slp_irq, + .unmask = unmask_msp_slp_irq, +}; + +void __init msp_slp_irq_init(void) +{ + int i; + + /* Mask/clear interrupts. */ + *SLP_INT_MSK_REG = 0x00000000; + *PER_INT_MSK_REG = 0x00000000; + *SLP_INT_STS_REG = 0xFFFFFFFF; + *PER_INT_STS_REG = 0xFFFFFFFF; + + /* initialize all the IRQ descriptors */ + for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++) + set_irq_chip_and_handler(i, &msp_slp_irq_controller + handle_level_irq); +} + +void msp_slp_irq_dispatch(void) +{ + u32 pending; + int intbase; + + intbase = MSP_SLP_INTBASE; + pending = *SLP_INT_STS_REG & *SLP_INT_MSK_REG; + + /* check for PER interrupt */ + if (pending == (1 << (MSP_INT_PER - MSP_SLP_INTBASE))) { + intbase = MSP_PER_INTBASE; + pending = *PER_INT_STS_REG & *PER_INT_MSK_REG; + } + + /* check for spurious interrupt */ + if (pending == 0x00000000) { + printk(KERN_ERR "Spurious %s interrupt?\n", + (intbase == MSP_SLP_INTBASE) ? "SLP" : "PER"); + return; + } + + /* dispatch the irq */ + do_IRQ(ffs(pending) + intbase - 1); +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c new file mode 100644 index 000000000000..e5bd5481d8db --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_prom.c @@ -0,0 +1,566 @@ +/* + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, assuming a version of + * pmon is the boot code. + * + * Copyright 2000,2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CRAMFS +#include +#endif +#ifdef CONFIG_SQUASHFS +#include +#endif + +#include +#include +#include +#include + +#include +#include + +/* global PROM environment variables and pointers */ +int prom_argc; +char **prom_argv, **prom_envp; +int *prom_vec; + +/* debug flag */ +int init_debug = 1; + +/* memory blocks */ +struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; + +/* default feature sets */ +static char msp_default_features[] = +#if defined(CONFIG_PMC_MSP4200_EVAL) \ + || defined(CONFIG_PMC_MSP4200_GW) + "ERER"; +#elif defined(CONFIG_PMC_MSP7120_EVAL) \ + || defined(CONFIG_PMC_MSP7120_GW) + "EMEMSP"; +#elif defined(CONFIG_PMC_MSP7120_FPGA) + "EMEM"; +#endif + +/* conversion functions */ +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline int str2eaddr(unsigned char *ea, unsigned char *str) +{ + int index = 0; + unsigned char num = 0; + + while (*str != '\0') { + if ((*str == '.') || (*str == ':')) { + ea[index++] = num; + num = 0; + str++; + } else { + num = num << 4; + num |= str2hexnum(*str++); + } + } + + if (index == 5) { + ea[index++] = num; + return 0; + } else + return -1; +} +EXPORT_SYMBOL(str2eaddr); + +static inline unsigned long str2hex(unsigned char *str) +{ + int value = 0; + + while (*str) { + value = value << 4; + value |= str2hexnum(*str++); + } + + return value; +} + +/* function to query the system information */ +const char *get_system_type(void) +{ +#if defined(CONFIG_PMC_MSP4200_EVAL) + return "PMC-Sierra MSP4200 Eval Board"; +#elif defined(CONFIG_PMC_MSP4200_GW) + return "PMC-Sierra MSP4200 VoIP Gateway"; +#elif defined(CONFIG_PMC_MSP7120_EVAL) + return "PMC-Sierra MSP7120 Eval Board"; +#elif defined(CONFIG_PMC_MSP7120_GW) + return "PMC-Sierra MSP7120 Residential Gateway"; +#elif defined(CONFIG_PMC_MSP7120_FPGA) + return "PMC-Sierra MSP7120 FPGA"; +#else + #error "What is the type of *your* MSP?" +#endif +} + +int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv(ethaddr_name); + if (!ethaddr_str) { + printk(KERN_WARNING "%s not set in boot prom\n", ethaddr_name); + return -1; + } + + if (str2eaddr(ethernet_addr, ethaddr_str) == -1) { + printk(KERN_WARNING "%s badly formatted-<%s>\n", + ethaddr_name, ethaddr_str); + return -1; + } + + if (init_debug > 1) { + int i; + printk(KERN_DEBUG "get_ethernet_addr: for %s ", ethaddr_name); + for (i = 0; i < 5; i++) + printk(KERN_DEBUG "%02x:", + (unsigned char)*(ethernet_addr+i)); + printk(KERN_DEBUG "%02x\n", *(ethernet_addr+i)); + } + + return 0; +} +EXPORT_SYMBOL(get_ethernet_addr); + +static char *get_features(void) +{ + char *feature = prom_getenv(FEATURES); + + if (feature == NULL) { + /* default features based on MACHINE_TYPE */ + feature = msp_default_features; + } + + return feature; +} + +static char test_feature(char c) +{ + char *feature = get_features(); + + while (*feature) { + if (*feature++ == c) + return *feature; + feature++; + } + + return FEATURE_NOEXIST; +} + +unsigned long get_deviceid(void) +{ + char *deviceid = prom_getenv(DEVICEID); + + if (deviceid == NULL) + return *DEV_ID_REG; + else + return str2hex(deviceid); +} + +char identify_pci(void) +{ + return test_feature(PCI_KEY); +} +EXPORT_SYMBOL(identify_pci); + +char identify_pcimux(void) +{ + return test_feature(PCIMUX_KEY); +} + +char identify_sec(void) +{ + return test_feature(SEC_KEY); +} +EXPORT_SYMBOL(identify_sec); + +char identify_spad(void) +{ + return test_feature(SPAD_KEY); +} +EXPORT_SYMBOL(identify_spad); + +char identify_tdm(void) +{ + return test_feature(TDM_KEY); +} +EXPORT_SYMBOL(identify_tdm); + +char identify_zsp(void) +{ + return test_feature(ZSP_KEY); +} +EXPORT_SYMBOL(identify_zsp); + +static char identify_enetfeature(char key, unsigned long interface_num) +{ + char *feature = get_features(); + + while (*feature) { + if (*feature++ == key && interface_num-- == 0) + return *feature; + feature++; + } + + return FEATURE_NOEXIST; +} + +char identify_enet(unsigned long interface_num) +{ + return identify_enetfeature(ENET_KEY, interface_num); +} +EXPORT_SYMBOL(identify_enet); + +char identify_enetTxD(unsigned long interface_num) +{ + return identify_enetfeature(ENETTXD_KEY, interface_num); +} +EXPORT_SYMBOL(identify_enetTxD); + +unsigned long identify_family(void) +{ + unsigned long deviceid; + + deviceid = get_deviceid(); + + return deviceid & CPU_DEVID_FAMILY; +} +EXPORT_SYMBOL(identify_family); + +unsigned long identify_revision(void) +{ + unsigned long deviceid; + + deviceid = get_deviceid(); + + return deviceid & CPU_DEVID_REVISION; +} +EXPORT_SYMBOL(identify_revision); + +/* PROM environment functions */ +char *prom_getenv(char *env_name) +{ + /* + * Return a pointer to the given environment variable. prom_envp + * points to a null terminated array of pointers to variables. + * Environment variables are stored in the form of "memsize=64" + */ + + char **var = prom_envp; + int i = strlen(env_name); + + while (*var) { + if (strncmp(env_name, *var, i) == 0) { + return (*var + strlen(env_name) + 1); + } + var++; + } + + return NULL; +} + +/* PROM commandline functions */ +char *prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} +EXPORT_SYMBOL(prom_getcmdline); + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while (actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +/* memory allocation functions */ +static int __init prom_memtype_classify(unsigned int type) +{ + switch (type) { + case yamon_free: + return BOOT_MEM_RAM; + case yamon_prom: + return BOOT_MEM_ROM_DATA; + default: + return BOOT_MEM_RESERVED; + } +} + +void __init prom_meminit(void) +{ + struct prom_pmemblock *p; + + p = prom_getmdesc(); + + while (p->size) { + long type; + unsigned long base, size; + + type = prom_memtype_classify(p->type); + base = p->base; + size = p->size; + + add_memory_region(base, size, type); + p++; + } +} + +void __init prom_free_prom_memory(void) +{ + int argc; + char **argv; + char **envp; + char *ptr; + int len = 0; + int i; + unsigned long addr; + + /* + * preserve environment variables and command line from pmon/bbload + * first preserve the command line + */ + for (argc = 0; argc < prom_argc; argc++) { + len += sizeof(char *); /* length of pointer */ + len += strlen(prom_argv[argc]) + 1; /* length of string */ + } + len += sizeof(char *); /* plus length of null pointer */ + + argv = kmalloc(len, GFP_KERNEL); + ptr = (char *) &argv[prom_argc + 1]; /* strings follow array */ + + for (argc = 0; argc < prom_argc; argc++) { + argv[argc] = ptr; + strcpy(ptr, prom_argv[argc]); + ptr += strlen(prom_argv[argc]) + 1; + } + argv[prom_argc] = NULL; /* end array with null pointer */ + prom_argv = argv; + + /* next preserve the environment variables */ + len = 0; + i = 0; + for (envp = prom_envp; *envp != NULL; envp++) { + i++; /* count number of environment variables */ + len += sizeof(char *); /* length of pointer */ + len += strlen(*envp) + 1; /* length of string */ + } + len += sizeof(char *); /* plus length of null pointer */ + + envp = kmalloc(len, GFP_KERNEL); + ptr = (char *) &envp[i+1]; + + for (argc = 0; argc < i; argc++) { + envp[argc] = ptr; + strcpy(ptr, prom_envp[argc]); + ptr += strlen(prom_envp[argc]) + 1; + } + envp[i] = NULL; /* end array with null pointer */ + prom_envp = envp; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) + continue; + + addr = boot_mem_map.map[i].addr; + free_init_pages("prom memory", + addr, addr + boot_mem_map.map[i].size); + } +} + +struct prom_pmemblock *__init prom_getmdesc(void) +{ + static char memsz_env[] __initdata = "memsize"; + static char heaptop_env[] __initdata = "heaptop"; + char *str; + unsigned int memsize; + unsigned int heaptop; +#ifdef CONFIG_MTD_PMC_MSP_RAMROOT + void *ramroot_start; + unsigned long ramroot_size; +#endif + int i; + + str = prom_getenv(memsz_env); + if (!str) { + ppfinit("memsize not set in boot prom, " + "set to default (32Mb)\n"); + memsize = 0x02000000; + } else { + memsize = simple_strtol(str, NULL, 0); + + if (memsize == 0) { + /* if memsize is a bad size, use reasonable default */ + memsize = 0x02000000; + } + + /* convert to physical address (removing caching bits, etc) */ + memsize = CPHYSADDR(memsize); + } + + str = prom_getenv(heaptop_env); + if (!str) { + heaptop = CPHYSADDR((u32)&_text); + ppfinit("heaptop not set in boot prom, " + "set to default 0x%08x\n", heaptop); + } else { + heaptop = simple_strtol(str, NULL, 16); + if (heaptop == 0) { + /* heaptop conversion bad, might have 0xValue */ + heaptop = simple_strtol(str, NULL, 0); + + if (heaptop == 0) { + /* heaptop still bad, use reasonable default */ + heaptop = CPHYSADDR((u32)&_text); + } + } + + /* convert to physical address (removing caching bits, etc) */ + heaptop = CPHYSADDR((u32)heaptop); + } + + /* the base region */ + i = 0; + mdesc[i].type = BOOT_MEM_RESERVED; + mdesc[i].base = 0x00000000; + mdesc[i].size = PAGE_ALIGN(0x300 + 0x80); + /* jtag interrupt vector + sizeof vector */ + + /* PMON data */ + if (heaptop > mdesc[i].base + mdesc[i].size) { + i++; /* 1 */ + mdesc[i].type = BOOT_MEM_ROM_DATA; + mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size; + mdesc[i].size = heaptop - mdesc[i].base; + } + + /* end of PMON data to start of kernel -- probably zero .. */ + if (heaptop != CPHYSADDR((u32)_text)) { + i++; /* 2 */ + mdesc[i].type = BOOT_MEM_RAM; + mdesc[i].base = heaptop; + mdesc[i].size = CPHYSADDR((u32)_text) - mdesc[i].base; + } + + /* kernel proper */ + i++; /* 3 */ + mdesc[i].type = BOOT_MEM_RESERVED; + mdesc[i].base = CPHYSADDR((u32)_text); +#ifdef CONFIG_MTD_PMC_MSP_RAMROOT + if (get_ramroot(&ramroot_start, &ramroot_size)) { + /* + * Rootfs in RAM -- follows kernel + * Combine rootfs image with kernel block so a + * page (4k) isn't wasted between memory blocks + */ + mdesc[i].size = CPHYSADDR(PAGE_ALIGN( + (u32)ramroot_start + ramroot_size)) - mdesc[i].base; + } else +#endif + mdesc[i].size = CPHYSADDR(PAGE_ALIGN( + (u32)_end)) - mdesc[i].base; + + /* Remainder of RAM -- under memsize */ + i++; /* 5 */ + mdesc[i].type = yamon_free; + mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size; + mdesc[i].size = memsize - mdesc[i].base; + + return &mdesc[0]; +} + +/* rootfs functions */ +#ifdef CONFIG_MTD_PMC_MSP_RAMROOT +bool get_ramroot(void **start, unsigned long *size) +{ + extern char _end[]; + + /* Check for start following the end of the kernel */ + void *check_start = (void *)_end; + + /* Check for supported rootfs types */ +#ifdef CONFIG_CRAMFS + if (*(__u32 *)check_start == CRAMFS_MAGIC) { + /* Get CRAMFS size */ + *start = check_start; + *size = PAGE_ALIGN(((struct cramfs_super *) + check_start)->size); + + return true; + } +#endif +#ifdef CONFIG_SQUASHFS + if (*((unsigned int *)check_start) == SQUASHFS_MAGIC) { + /* Get SQUASHFS size */ + *start = check_start; + *size = PAGE_ALIGN(((struct squashfs_super_block *) + check_start)->bytes_used); + + return true; + } +#endif + + return false; +} +EXPORT_SYMBOL(get_ramroot); +#endif diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c new file mode 100644 index 000000000000..8f69b789be90 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c @@ -0,0 +1,256 @@ +/* + * The generic setup file for PMC-Sierra MSP processors + * + * Copyright 2005-2007 PMC-Sierra, Inc, + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#if defined(CONFIG_PMC_MSP7120_GW) +#include +#include +#define MSP_BOARD_RESET_GPIO 9 +#endif + +extern void msp_timer_init(void); +extern void msp_serial_setup(void); +extern void pmctwiled_setup(void); + +#if defined(CONFIG_PMC_MSP7120_EVAL) || \ + defined(CONFIG_PMC_MSP7120_GW) || \ + defined(CONFIG_PMC_MSP7120_FPGA) +/* + * Performs the reset for MSP7120-based boards + */ +void msp7120_reset(void) +{ + void *start, *end, *iptr; + register int i; + + /* Diasble all interrupts */ + local_irq_disable(); +#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING + dvpe(); +#endif + + /* Cache the reset code of this function */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips3 \n" + " la %0,startpoint \n" + " la %1,endpoint \n" + " .set pop \n" + : "=r" (start), "=r" (end) + : + ); + + for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1)); + iptr < end; iptr += L1_CACHE_BYTES) + cache_op(Fill, iptr); + + __asm__ __volatile__ ( + "startpoint: \n" + ); + + /* Put the DDRC into self-refresh mode */ + DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16); + + /* + * IMPORTANT! + * DO NOT do anything from here on out that might even + * think about fetching from RAM - i.e., don't call any + * non-inlined functions, and be VERY sure that any inline + * functions you do call do NOT access any sort of RAM + * anywhere! + */ + + /* Wait a bit for the DDRC to settle */ + for (i = 0; i < 100000000; i++); + +#if defined(CONFIG_PMC_MSP7120_GW) + /* + * Set GPIO 9 HI, (tied to board reset logic) + * GPIO 9 is the 4th GPIO of register 3 + * + * NOTE: We cannot use the higher-level msp_gpio_mode()/out() + * as GPIO char driver may not be enabled and it would look up + * data inRAM! + */ + set_value_reg32(GPIO_CFG3_REG, + basic_mode_mask(MSP_BOARD_RESET_GPIO), + basic_mode(MSP_GPIO_OUTPUT, MSP_BOARD_RESET_GPIO)); + set_reg32(GPIO_DATA3_REG, + basic_data_mask(MSP_BOARD_RESET_GPIO)); + + /* + * In case GPIO9 doesn't reset the board (jumper configurable!) + * fallback to device reset below. + */ +#endif + /* Set bit 1 of the MSP7120 reset register */ + *RST_SET_REG = 0x00000001; + + __asm__ __volatile__ ( + "endpoint: \n" + ); +} +#endif + +void msp_restart(char *command) +{ + printk(KERN_WARNING "Now rebooting .......\n"); + +#if defined(CONFIG_PMC_MSP7120_EVAL) || \ + defined(CONFIG_PMC_MSP7120_GW) || \ + defined(CONFIG_PMC_MSP7120_FPGA) + msp7120_reset(); +#else + /* No chip-specific reset code, just jump to the ROM reset vector */ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +#endif +} + +void msp_halt(void) +{ + printk(KERN_WARNING "\n** You can safely turn off the power\n"); + while (1) + /* If possible call official function to get CPU WARs */ + if (cpu_wait) + (*cpu_wait)(); + else + __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); +} + +void msp_power_off(void) +{ + msp_halt(); +} + +void __init plat_mem_setup(void) +{ + _machine_restart = msp_restart; + _machine_halt = msp_halt; + pm_power_off = msp_power_off; + + board_time_init = msp_timer_init; +} + +void __init prom_init(void) +{ + unsigned long family; + unsigned long revision; + + prom_argc = fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; + + /* + * Someday we can use this with PMON2000 to get a + * platform call prom routines for output etc. without + * having to use grody hacks. For now it's unused. + * + * struct callvectors *cv = (struct callvectors *) fw_arg3; + */ + family = identify_family(); + revision = identify_revision(); + + switch (family) { + case FAMILY_FPGA: + if (FPGA_IS_MSP4200(revision)) { + /* Old-style revision ID */ + mips_machgroup = MACH_GROUP_MSP; + mips_machtype = MACH_MSP4200_FPGA; + } else { + mips_machgroup = MACH_GROUP_MSP; + mips_machtype = MACH_MSP_OTHER; + } + break; + + case FAMILY_MSP4200: + mips_machgroup = MACH_GROUP_MSP; +#if defined(CONFIG_PMC_MSP4200_EVAL) + mips_machtype = MACH_MSP4200_EVAL; +#elif defined(CONFIG_PMC_MSP4200_GW) + mips_machtype = MACH_MSP4200_GW; +#else + mips_machtype = MACH_MSP_OTHER; +#endif + break; + + case FAMILY_MSP4200_FPGA: + mips_machgroup = MACH_GROUP_MSP; + mips_machtype = MACH_MSP4200_FPGA; + break; + + case FAMILY_MSP7100: + mips_machgroup = MACH_GROUP_MSP; +#if defined(CONFIG_PMC_MSP7120_EVAL) + mips_machtype = MACH_MSP7120_EVAL; +#elif defined(CONFIG_PMC_MSP7120_GW) + mips_machtype = MACH_MSP7120_GW; +#else + mips_machtype = MACH_MSP_OTHER; +#endif + break; + + case FAMILY_MSP7100_FPGA: + mips_machgroup = MACH_GROUP_MSP; + mips_machtype = MACH_MSP7120_FPGA; + break; + + default: + /* we don't recognize the machine */ + mips_machgroup = MACH_GROUP_UNKNOWN; + mips_machtype = MACH_UNKNOWN; + break; + } + + /* make sure we have the right initialization routine - sanity */ + if (mips_machgroup != MACH_GROUP_MSP) { + ppfinit("Unknown machine group in a " + "MSP initialization routine\n"); + panic("***Bogosity factor five***, exiting\n"); + } + + prom_init_cmdline(); + + prom_meminit(); + + /* + * Sub-system setup follows. + * Setup functions can either be called here or using the + * subsys_initcall mechanism (i.e. see msp_pci_setup). The + * order in which they are called can be changed by using the + * link order in arch/mips/pmc-sierra/msp71xx/Makefile. + * + * NOTE: Please keep sub-system specific initialization code + * in separate specific files. + */ + msp_serial_setup(); + +#ifdef CONFIG_PMCTWILED + /* + * Setup LED states before the subsys_initcall loads other + * dependant drivers/modules. + */ + pmctwiled_setup(); +#endif +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c new file mode 100644 index 000000000000..2a2beac5a4f8 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c @@ -0,0 +1,94 @@ +/* + * Setting up the clock on MSP SOCs. No RTC typically. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +void __init msp_timer_init(void) +{ + char *endp, *s; + unsigned long cpu_rate = 0; + + if (cpu_rate == 0) { + s = prom_getenv("clkfreqhz"); + cpu_rate = simple_strtoul(s, &endp, 10); + if (endp != NULL && *endp != 0) { + printk(KERN_ERR + "Clock rate in Hz parse error: %s\n", s); + cpu_rate = 0; + } + } + + if (cpu_rate == 0) { + s = prom_getenv("clkfreq"); + cpu_rate = 1000 * simple_strtoul(s, &endp, 10); + if (endp != NULL && *endp != 0) { + printk(KERN_ERR + "Clock rate in MHz parse error: %s\n", s); + cpu_rate = 0; + } + } + + if (cpu_rate == 0) { +#if defined(CONFIG_PMC_MSP7120_EVAL) \ + || defined(CONFIG_PMC_MSP7120_GW) + cpu_rate = 400000000; +#elif defined(CONFIG_PMC_MSP7120_FPGA) + cpu_rate = 25000000; +#else + cpu_rate = 150000000; +#endif + printk(KERN_ERR + "Failed to determine CPU clock rate, " + "assuming %ld hz ...\n", cpu_rate); + } + + printk(KERN_WARNING "Clock rate set to %ld\n", cpu_rate); + + /* timer frequency is 1/2 clock rate */ + mips_hpt_frequency = cpu_rate/2; +} + + +void __init plat_timer_setup(struct irqaction *irq) +{ +#ifdef CONFIG_IRQ_MSP_CIC + /* we are using the vpe0 counter for timer interrupts */ + setup_irq(MSP_INT_VPE0_TIMER, irq); +#else + /* we are using the mips counter for timer interrupts */ + setup_irq(MSP_INT_TIMER, irq); +#endif +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c new file mode 100644 index 000000000000..21f9c70b6923 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c @@ -0,0 +1,150 @@ +/* + * The setup file for USB related hardware on PMC-Sierra MSP processors. + * + * Copyright 2006-2007 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#if defined(CONFIG_USB_EHCI_HCD) +static struct resource msp_usbhost_resources [] = { + [0] = { + .start = MSP_USB_BASE_START, + .end = MSP_USB_BASE_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_USB, + .end = MSP_INT_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 msp_usbhost_dma_mask = DMA_32BIT_MASK; + +static struct platform_device msp_usbhost_device = { + .name = "pmcmsp-ehci", + .id = 0, + .dev = { + .dma_mask = &msp_usbhost_dma_mask, + .coherent_dma_mask = DMA_32BIT_MASK, + }, + .num_resources = ARRAY_SIZE (msp_usbhost_resources), + .resource = msp_usbhost_resources, +}; +#endif /* CONFIG_USB_EHCI_HCD */ + +#if defined(CONFIG_USB_GADGET) +static struct resource msp_usbdev_resources [] = { + [0] = { + .start = MSP_USB_BASE, + .end = MSP_USB_BASE_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_USB, + .end = MSP_INT_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 msp_usbdev_dma_mask = DMA_32BIT_MASK; + +static struct platform_device msp_usbdev_device = { + .name = "msp71xx_udc", + .id = 0, + .dev = { + .dma_mask = &msp_usbdev_dma_mask, + .coherent_dma_mask = DMA_32BIT_MASK, + }, + .num_resources = ARRAY_SIZE (msp_usbdev_resources), + .resource = msp_usbdev_resources, +}; +#endif /* CONFIG_USB_GADGET */ + +#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) +static struct platform_device *msp_devs[1]; +#endif + + +static int __init msp_usb_setup(void) +{ +#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) + char *strp; + char envstr[32]; + unsigned int val = 0; + int result = 0; + + /* + * construct environment name usbmode + * set usbmode as pmon environment var + */ + snprintf((char *)&envstr[0], sizeof(envstr), "usbmode"); + +#if defined(CONFIG_USB_EHCI_HCD) + /* default to host mode */ + val = 1; +#endif + + /* get environment string */ + strp = prom_getenv((char *)&envstr[0]); + if (strp) { + if (!strcmp(strp, "device")) + val = 0; + } + + if (val) { +#if defined(CONFIG_USB_EHCI_HCD) + /* get host mode device */ + msp_devs[0] = &msp_usbhost_device; + ppfinit("platform add USB HOST done %s.\n", + msp_devs[0]->name); + + result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs)); +#endif /* CONFIG_USB_EHCI_HCD */ + } +#if defined(CONFIG_USB_GADGET) + else { + /* get device mode structure */ + msp_devs[0] = &msp_usbdev_device; + ppfinit("platform add USB DEVICE done %s.\n", + msp_devs[0]->name); + + result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs)); + } +#endif /* CONFIG_USB_GADGET */ +#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */ + + return result; +} + +subsys_initcall(msp_usb_setup); diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h new file mode 100644 index 000000000000..c84bcf9570b1 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h @@ -0,0 +1,151 @@ +/* + * Defines for the MSP interrupt controller. + * + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. + * Author: Carsten Langgaard, carstenl@mips.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 _MSP_CIC_INT_H +#define _MSP_CIC_INT_H + +/* + * The PMC-Sierra CIC interrupts are all centrally managed by the + * CIC sub-system. + * We attempt to keep the interrupt numbers as consistent as possible + * across all of the MSP devices, but some differences will creep in ... + * The interrupts which are directly forwarded to the MIPS core interrupts + * are assigned interrupts in the range 0-7, interrupts cascaded through + * the CIC are assigned interrupts 8-39. The cascade occurs on C_IRQ4 + * (MSP_INT_CIC). Currently we don't really distinguish between VPE1 + * and VPE0 (or thread contexts for that matter). Will have to fix. + * The PER interrupts are assigned interrupts in the range 40-71. +*/ + + +/* + * IRQs directly forwarded to the CPU + */ +#define MSP_MIPS_INTBASE 0 +#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */ +#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */ +#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */ +#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */ +#define MSP_INT_USB 4 /* IRQ for USB, C_IRQ2 */ +#define MSP_INT_SAR 5 /* IRQ for ADSL2+ SAR, C_IRQ3 */ +#define MSP_INT_CIC 6 /* IRQ for CIC block, C_IRQ4 */ +#define MSP_INT_SEC 7 /* IRQ for Sec engine, C_IRQ5 */ + +/* + * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4) + * These defines should be tied to the register definitions for the CIC + * interrupt routine. For now, just use hard-coded values. + */ +#define MSP_CIC_INTBASE (MSP_MIPS_INTBASE + 8) +#define MSP_INT_EXT0 (MSP_CIC_INTBASE + 0) + /* External interrupt 0 */ +#define MSP_INT_EXT1 (MSP_CIC_INTBASE + 1) + /* External interrupt 1 */ +#define MSP_INT_EXT2 (MSP_CIC_INTBASE + 2) + /* External interrupt 2 */ +#define MSP_INT_EXT3 (MSP_CIC_INTBASE + 3) + /* External interrupt 3 */ +#define MSP_INT_CPUIF (MSP_CIC_INTBASE + 4) + /* CPU interface interrupt */ +#define MSP_INT_EXT4 (MSP_CIC_INTBASE + 5) + /* External interrupt 4 */ +#define MSP_INT_CIC_USB (MSP_CIC_INTBASE + 6) + /* Cascaded IRQ for USB */ +#define MSP_INT_MBOX (MSP_CIC_INTBASE + 7) + /* Sec engine mailbox IRQ */ +#define MSP_INT_EXT5 (MSP_CIC_INTBASE + 8) + /* External interrupt 5 */ +#define MSP_INT_TDM (MSP_CIC_INTBASE + 9) + /* TDM interrupt */ +#define MSP_INT_CIC_MAC0 (MSP_CIC_INTBASE + 10) + /* Cascaded IRQ for MAC 0 */ +#define MSP_INT_CIC_MAC1 (MSP_CIC_INTBASE + 11) + /* Cascaded IRQ for MAC 1 */ +#define MSP_INT_CIC_SEC (MSP_CIC_INTBASE + 12) + /* Cascaded IRQ for sec engine */ +#define MSP_INT_PER (MSP_CIC_INTBASE + 13) + /* Peripheral interrupt */ +#define MSP_INT_TIMER0 (MSP_CIC_INTBASE + 14) + /* SLP timer 0 */ +#define MSP_INT_TIMER1 (MSP_CIC_INTBASE + 15) + /* SLP timer 1 */ +#define MSP_INT_TIMER2 (MSP_CIC_INTBASE + 16) + /* SLP timer 2 */ +#define MSP_INT_VPE0_TIMER (MSP_CIC_INTBASE + 17) + /* VPE0 MIPS timer */ +#define MSP_INT_BLKCP (MSP_CIC_INTBASE + 18) + /* Block Copy */ +#define MSP_INT_UART0 (MSP_CIC_INTBASE + 19) + /* UART 0 */ +#define MSP_INT_PCI (MSP_CIC_INTBASE + 20) + /* PCI subsystem */ +#define MSP_INT_EXT6 (MSP_CIC_INTBASE + 21) + /* External interrupt 5 */ +#define MSP_INT_PCI_MSI (MSP_CIC_INTBASE + 22) + /* PCI Message Signal */ +#define MSP_INT_CIC_SAR (MSP_CIC_INTBASE + 23) + /* Cascaded ADSL2+ SAR IRQ */ +#define MSP_INT_DSL (MSP_CIC_INTBASE + 24) + /* ADSL2+ IRQ */ +#define MSP_INT_CIC_ERR (MSP_CIC_INTBASE + 25) + /* SLP error condition */ +#define MSP_INT_VPE1_TIMER (MSP_CIC_INTBASE + 26) + /* VPE1 MIPS timer */ +#define MSP_INT_VPE0_PC (MSP_CIC_INTBASE + 27) + /* VPE0 Performance counter */ +#define MSP_INT_VPE1_PC (MSP_CIC_INTBASE + 28) + /* VPE1 Performance counter */ +#define MSP_INT_EXT7 (MSP_CIC_INTBASE + 29) + /* External interrupt 5 */ +#define MSP_INT_VPE0_SW (MSP_CIC_INTBASE + 30) + /* VPE0 Software interrupt */ +#define MSP_INT_VPE1_SW (MSP_CIC_INTBASE + 31) + /* VPE0 Software interrupt */ + +/* + * IRQs cascaded on CIC PER interrupt (MSP_INT_PER) + */ +#define MSP_PER_INTBASE (MSP_CIC_INTBASE + 32) +/* Reserved 0-1 */ +#define MSP_INT_UART1 (MSP_PER_INTBASE + 2) + /* UART 1 */ +/* Reserved 3-5 */ +#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6) + /* 2-wire */ +#define MSP_INT_TM0 (MSP_PER_INTBASE + 7) + /* Peripheral timer block out 0 */ +#define MSP_INT_TM1 (MSP_PER_INTBASE + 8) + /* Peripheral timer block out 1 */ +/* Reserved 9 */ +#define MSP_INT_SPRX (MSP_PER_INTBASE + 10) + /* SPI RX complete */ +#define MSP_INT_SPTX (MSP_PER_INTBASE + 11) + /* SPI TX complete */ +#define MSP_INT_GPIO (MSP_PER_INTBASE + 12) + /* GPIO */ +#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13) + /* Peripheral error */ +/* Reserved 14-31 */ + +#endif /* !_MSP_CIC_INT_H */ diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_int.h new file mode 100644 index 000000000000..1d9f05474820 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_int.h @@ -0,0 +1,43 @@ +/* + * Defines for the MSP interrupt handlers. + * + * Copyright (C) 2005, PMC-Sierra, Inc. All rights reserved. + * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 _MSP_INT_H +#define _MSP_INT_H + +/* + * The PMC-Sierra MSP product line has at least two different interrupt + * controllers, the SLP register based scheme and the CIC interrupt + * controller block mechanism. This file distinguishes between them + * so that devices see a uniform interface. + */ + +#if defined(CONFIG_IRQ_MSP_SLP) + #include "msp_slp_int.h" +#elif defined(CONFIG_IRQ_MSP_CIC) + #include "msp_cic_int.h" +#else + #error "What sort of interrupt controller does *your* MSP have?" +#endif + +#endif /* !_MSP_INT_H */ diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h b/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h new file mode 100644 index 000000000000..14ca7dc382a8 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h @@ -0,0 +1,176 @@ +/* + * MIPS boards bootprom interface for the Linux kernel. + * + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Author: Carsten Langgaard, carstenl@mips.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + */ + +#ifndef _ASM_MSP_PROM_H +#define _ASM_MSP_PROM_H + +#include + +#define DEVICEID "deviceid" +#define FEATURES "features" +#define PROM_ENV "prom_env" +#define PROM_ENV_FILE "/proc/"PROM_ENV +#define PROM_ENV_SIZE 256 + +#define CPU_DEVID_FAMILY 0x0000ff00 +#define CPU_DEVID_REVISION 0x000000ff + +#define FPGA_IS_POLO(revision) \ + (((revision >= 0xb0) && (revision < 0xd0))) +#define FPGA_IS_5000(revision) \ + ((revision >= 0x80) && (revision <= 0x90)) +#define FPGA_IS_ZEUS(revision) ((revision < 0x7f)) +#define FPGA_IS_DUET(revision) \ + (((revision >= 0xa0) && (revision < 0xb0))) +#define FPGA_IS_MSP4200(revision) ((revision >= 0xd0)) +#define FPGA_IS_MSP7100(revision) ((revision >= 0xd0)) + +#define MACHINE_TYPE_POLO "POLO" +#define MACHINE_TYPE_DUET "DUET" +#define MACHINE_TYPE_ZEUS "ZEUS" +#define MACHINE_TYPE_MSP2000REVB "MSP2000REVB" +#define MACHINE_TYPE_MSP5000 "MSP5000" +#define MACHINE_TYPE_MSP4200 "MSP4200" +#define MACHINE_TYPE_MSP7120 "MSP7120" +#define MACHINE_TYPE_MSP7130 "MSP7130" +#define MACHINE_TYPE_OTHER "OTHER" + +#define MACHINE_TYPE_POLO_FPGA "POLO-FPGA" +#define MACHINE_TYPE_DUET_FPGA "DUET-FPGA" +#define MACHINE_TYPE_ZEUS_FPGA "ZEUS_FPGA" +#define MACHINE_TYPE_MSP2000REVB_FPGA "MSP2000REVB-FPGA" +#define MACHINE_TYPE_MSP5000_FPGA "MSP5000-FPGA" +#define MACHINE_TYPE_MSP4200_FPGA "MSP4200-FPGA" +#define MACHINE_TYPE_MSP7100_FPGA "MSP7100-FPGA" +#define MACHINE_TYPE_OTHER_FPGA "OTHER-FPGA" + +/* Device Family definitions */ +#define FAMILY_FPGA 0x0000 +#define FAMILY_ZEUS 0x1000 +#define FAMILY_POLO 0x2000 +#define FAMILY_DUET 0x4000 +#define FAMILY_TRIAD 0x5000 +#define FAMILY_MSP4200 0x4200 +#define FAMILY_MSP4200_FPGA 0x4f00 +#define FAMILY_MSP7100 0x7100 +#define FAMILY_MSP7100_FPGA 0x7f00 + +/* Device Type definitions */ +#define TYPE_MSP7120 0x7120 +#define TYPE_MSP7130 0x7130 + +#define ENET_KEY 'E' +#define ENETTXD_KEY 'e' +#define PCI_KEY 'P' +#define PCIMUX_KEY 'p' +#define SEC_KEY 'S' +#define SPAD_KEY 'D' +#define TDM_KEY 'T' +#define ZSP_KEY 'Z' + +#define FEATURE_NOEXIST '-' +#define FEATURE_EXIST '+' + +#define ENET_MII 'M' +#define ENET_RMII 'R' + +#define ENETTXD_FALLING 'F' +#define ENETTXD_RISING 'R' + +#define PCI_HOST 'H' +#define PCI_PERIPHERAL 'P' + +#define PCIMUX_FULL 'F' +#define PCIMUX_SINGLE 'S' + +#define SEC_DUET 'D' +#define SEC_POLO 'P' +#define SEC_SLOW 'S' +#define SEC_TRIAD 'T' + +#define SPAD_POLO 'P' + +#define TDM_DUET 'D' /* DUET TDMs might exist */ +#define TDM_POLO 'P' /* POLO TDMs might exist */ +#define TDM_TRIAD 'T' /* TRIAD TDMs might exist */ + +#define ZSP_DUET 'D' /* one DUET zsp engine */ +#define ZSP_TRIAD 'T' /* two TRIAD zsp engines */ + +extern char *prom_getcmdline(void); +extern char *prom_getenv(char *name); +extern void prom_init_cmdline(void); +extern void prom_meminit(void); +extern void prom_fixup_mem_map(unsigned long start_mem, + unsigned long end_mem); + +#ifdef CONFIG_MTD_PMC_MSP_RAMROOT +extern bool get_ramroot(void **start, unsigned long *size); +#endif + +extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr); +extern unsigned long get_deviceid(void); +extern char identify_enet(unsigned long interface_num); +extern char identify_enetTxD(unsigned long interface_num); +extern char identify_pci(void); +extern char identify_sec(void); +extern char identify_spad(void); +extern char identify_sec(void); +extern char identify_tdm(void); +extern char identify_zsp(void); +extern unsigned long identify_family(void); +extern unsigned long identify_revision(void); + +/* + * The following macro calls prom_printf and puts the format string + * into an init section so it can be reclaimed. + */ +#define ppfinit(f, x...) \ + do { \ + static char _f[] __initdata = KERN_INFO f; \ + printk(_f, ## x); \ + } while (0) + +/* Memory descriptor management. */ +#define PROM_MAX_PMEMBLOCKS 7 /* 6 used */ + +enum yamon_memtypes { + yamon_dontuse, + yamon_prom, + yamon_free, +}; + +struct prom_pmemblock { + unsigned long base; /* Within KSEG0. */ + unsigned int size; /* In bytes. */ + unsigned int type; /* free or prom memory */ +}; + +extern int prom_argc; +extern char **prom_argv; +extern char **prom_envp; +extern int *prom_vec; +extern struct prom_pmemblock *prom_getmdesc(void); + +#endif /* !_ASM_MSP_PROM_H */ diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h new file mode 100644 index 000000000000..60a5a38dd5b2 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h @@ -0,0 +1,236 @@ +/* + * SMP/VPE-safe functions to access "registers" (see note). + * + * NOTES: +* - These macros use ll/sc instructions, so it is your responsibility to + * ensure these are available on your platform before including this file. + * - The MIPS32 spec states that ll/sc results are undefined for uncached + * accesses. This means they can't be used on HW registers accessed + * through kseg1. Code which requires these macros for this purpose must + * front-end the registers with cached memory "registers" and have a single + * thread update the actual HW registers. + * - A maximum of 2k of code can be inserted between ll and sc. Every + * memory accesses between the instructions will increase the chance of + * sc failing and having to loop. + * - When using custom_read_reg32/custom_write_reg32 only perform the + * necessary logical operations on the register value in between these + * two calls. All other logic should be performed before the first call. + * - There is a bug on the R10000 chips which has a workaround. If you + * are affected by this bug, make sure to define the symbol 'R10000_LLSC_WAR' + * to be non-zero. If you are using this header from within linux, you may + * include before including this file to have this defined + * appropriately for you. + * + * Copyright 2005-2007 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASM_REGOPS_H__ +#define __ASM_REGOPS_H__ + +#include + +#include + +#ifndef R10000_LLSC_WAR +#define R10000_LLSC_WAR 0 +#endif + +#if R10000_LLSC_WAR == 1 +#define __beqz "beqzl " +#else +#define __beqz "beqz " +#endif + +#ifndef _LINUX_TYPES_H +typedef unsigned int u32; +#endif + +/* + * Sets all the masked bits to the corresponding value bits + */ +static inline void set_value_reg32(volatile u32 *const addr, + u32 const mask, + u32 const value) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set mips3 \n" + "1: ll %0, %1 # set_value_reg32 \n" + " and %0, %2 \n" + " or %0, %3 \n" + " sc %0, %1 \n" + " "__beqz"%0, 1b \n" + " nop \n" + " .set pop \n" + : "=&r" (temp), "=m" (*addr) + : "ir" (~mask), "ir" (value), "m" (*addr)); +} + +/* + * Sets all the masked bits to '1' + */ +static inline void set_reg32(volatile u32 *const addr, + u32 const mask) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set mips3 \n" + "1: ll %0, %1 # set_reg32 \n" + " or %0, %2 \n" + " sc %0, %1 \n" + " "__beqz"%0, 1b \n" + " nop \n" + " .set pop \n" + : "=&r" (temp), "=m" (*addr) + : "ir" (mask), "m" (*addr)); +} + +/* + * Sets all the masked bits to '0' + */ +static inline void clear_reg32(volatile u32 *const addr, + u32 const mask) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set mips3 \n" + "1: ll %0, %1 # clear_reg32 \n" + " and %0, %2 \n" + " sc %0, %1 \n" + " "__beqz"%0, 1b \n" + " nop \n" + " .set pop \n" + : "=&r" (temp), "=m" (*addr) + : "ir" (~mask), "m" (*addr)); +} + +/* + * Toggles all masked bits from '0' to '1' and '1' to '0' + */ +static inline void toggle_reg32(volatile u32 *const addr, + u32 const mask) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set mips3 \n" + "1: ll %0, %1 # toggle_reg32 \n" + " xor %0, %2 \n" + " sc %0, %1 \n" + " "__beqz"%0, 1b \n" + " nop \n" + " .set pop \n" + : "=&r" (temp), "=m" (*addr) + : "ir" (mask), "m" (*addr)); +} + +/* + * Read all masked bits others are returned as '0' + */ +static inline u32 read_reg32(volatile u32 *const addr, + u32 const mask) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " lw %0, %1 # read \n" + " and %0, %2 # mask \n" + " .set pop \n" + : "=&r" (temp) + : "m" (*addr), "ir" (mask)); + + return temp; +} + +/* + * blocking_read_reg32 - Read address with blocking load + * + * Uncached writes need to be read back to ensure they reach RAM. + * The returned value must be 'used' to prevent from becoming a + * non-blocking load. + */ +static inline u32 blocking_read_reg32(volatile u32 *const addr) +{ + u32 temp; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " lw %0, %1 # read \n" + " move %0, %0 # block \n" + " .set pop \n" + : "=&r" (temp) + : "m" (*addr)); + + return temp; +} + +/* + * For special strange cases only: + * + * If you need custom processing within a ll/sc loop, use the following macros + * VERY CAREFULLY: + * + * u32 tmp; <-- Define a variable to hold the data + * + * custom_read_reg32(address, tmp); <-- Reads the address and put the value + * in the 'tmp' variable given + * + * From here on out, you are (basicly) atomic, so don't do anything too + * fancy! + * Also, this code may loop if the end of this block fails to write + * everything back safely due do the other CPU, so do NOT do anything + * with side-effects! + * + * custom_write_reg32(address, tmp); <-- Writes back 'tmp' safely. + */ +#define custom_read_reg32(address, tmp) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set mips3 \n" \ + "1: ll %0, %1 #custom_read_reg32 \n" \ + " .set pop \n" \ + : "=r" (tmp), "=m" (*address) \ + : "m" (*address)) + +#define custom_write_reg32(address, tmp) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set mips3 \n" \ + " sc %0, %1 #custom_write_reg32 \n" \ + " "__beqz"%0, 1b \n" \ + " nop \n" \ + " .set pop \n" \ + : "=&r" (tmp), "=m" (*address) \ + : "0" (tmp), "m" (*address)) + +#endif /* __ASM_REGOPS_H__ */ diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h new file mode 100644 index 000000000000..0b56f55206c6 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h @@ -0,0 +1,667 @@ +/* + * Defines for the address space, registers and register configuration + * (bit masks, access macros etc) for the PMC-Sierra line of MSP products. + * This file contains addess maps for all the devices in the line of + * products but only has register definitions and configuration masks for + * registers which aren't definitely associated with any device. Things + * like clock settings, reset access, the ELB etc. Individual device + * drivers will reference the appropriate XXX_BASE value defined here + * and have individual registers offset from that. + * + * Copyright (C) 2005-2007 PMC-Sierra, Inc. All rights reserved. + * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +#ifndef _ASM_MSP_REGS_H +#define _ASM_MSP_REGS_H + +/* + ######################################################################## + # Address space and device base definitions # + ######################################################################## + */ + +/* + *************************************************************************** + * System Logic and Peripherals (ELB, UART0, etc) device address space * + *************************************************************************** + */ +#define MSP_SLP_BASE 0x1c000000 + /* System Logic and Peripherals */ +#define MSP_RST_BASE (MSP_SLP_BASE + 0x10) + /* System reset register base */ +#define MSP_RST_SIZE 0x0C /* System reset register space */ + +#define MSP_WTIMER_BASE (MSP_SLP_BASE + 0x04C) + /* watchdog timer base */ +#define MSP_ITIMER_BASE (MSP_SLP_BASE + 0x054) + /* internal timer base */ +#define MSP_UART0_BASE (MSP_SLP_BASE + 0x100) + /* UART0 controller base */ +#define MSP_BCPY_CTRL_BASE (MSP_SLP_BASE + 0x120) + /* Block Copy controller base */ +#define MSP_BCPY_DESC_BASE (MSP_SLP_BASE + 0x160) + /* Block Copy descriptor base */ + +/* + *************************************************************************** + * PCI address space * + *************************************************************************** + */ +#define MSP_PCI_BASE 0x19000000 + +/* + *************************************************************************** + * MSbus device address space * + *************************************************************************** + */ +#define MSP_MSB_BASE 0x18000000 + /* MSbus address start */ +#define MSP_PER_BASE (MSP_MSB_BASE + 0x400000) + /* Peripheral device registers */ +#define MSP_MAC0_BASE (MSP_MSB_BASE + 0x600000) + /* MAC A device registers */ +#define MSP_MAC1_BASE (MSP_MSB_BASE + 0x700000) + /* MAC B device registers */ +#define MSP_MAC_SIZE 0xE0 /* MAC register space */ + +#define MSP_SEC_BASE (MSP_MSB_BASE + 0x800000) + /* Security Engine registers */ +#define MSP_MAC2_BASE (MSP_MSB_BASE + 0x900000) + /* MAC C device registers */ +#define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000) + /* ADSL2 device registers */ +#define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000) + /* USB device registers */ +#define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100) + /* USB device registers */ +#define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF) + /* USB device registers */ +#define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000) + /* CPU interface registers */ + +/* Devices within the MSbus peripheral block */ +#define MSP_UART1_BASE (MSP_PER_BASE + 0x030) + /* UART1 controller base */ +#define MSP_SPI_BASE (MSP_PER_BASE + 0x058) + /* SPI/MPI control registers */ +#define MSP_TWI_BASE (MSP_PER_BASE + 0x090) + /* Two-wire control registers */ +#define MSP_PTIMER_BASE (MSP_PER_BASE + 0x0F0) + /* Programmable timer control */ + +/* + *************************************************************************** + * Physical Memory configuration address space * + *************************************************************************** + */ +#define MSP_MEM_CFG_BASE 0x17f00000 + +#define MSP_MEM_INDIRECT_CTL_10 0x10 + +/* + * Notes: + * 1) The SPI registers are split into two blocks, one offset from the + * MSP_SPI_BASE by 0x00 and the other offset from the MSP_SPI_BASE by + * 0x68. The SPI driver definitions for the register must be aware + * of this. + * 2) The block copy engine register are divided into two regions, one + * for the control/configuration of the engine proper and one for the + * values of the descriptors used in the copy process. These have + * different base defines (CTRL_BASE vs DESC_BASE) + * 3) These constants are for physical addresses which means that they + * work correctly with "ioremap" and friends. This means that device + * drivers will need to remap these addresses using ioremap and perhaps + * the readw/writew macros. Or they could use the regptr() macro + * defined below, but the readw/writew calls are the correct thing. + * 4) The UARTs have an additional status register offset from the base + * address. This register isn't used in the standard 8250 driver but + * may be used in other software. Consult the hardware datasheet for + * offset details. + * 5) For some unknown reason the security engine (MSP_SEC_BASE) registers + * start at an offset of 0x84 from the base address but the block of + * registers before this is reserved for the security engine. The + * driver will have to be aware of this but it makes the register + * definitions line up better with the documentation. + */ + +/* + ######################################################################## + # System register definitions. Not associated with a specific device # + ######################################################################## + */ + +/* + * This macro maps the physical register number into uncached space + * and (for C code) casts it into a u32 pointer so it can be dereferenced + * Normally these would be accessed with ioremap and readX/writeX, but + * these are convenient for a lot of internal kernel code. + */ +#ifdef __ASSEMBLER__ + #define regptr(addr) (KSEG1ADDR(addr)) +#else + #define regptr(addr) ((volatile u32 *const)(KSEG1ADDR(addr))) +#endif + +/* + *************************************************************************** + * System Logic and Peripherals (RESET, ELB, etc) registers * + *************************************************************************** + */ + +/* System Control register definitions */ +#define DEV_ID_REG regptr(MSP_SLP_BASE + 0x00) + /* Device-ID RO */ +#define FWR_ID_REG regptr(MSP_SLP_BASE + 0x04) + /* Firmware-ID Register RW */ +#define SYS_ID_REG0 regptr(MSP_SLP_BASE + 0x08) + /* System-ID Register-0 RW */ +#define SYS_ID_REG1 regptr(MSP_SLP_BASE + 0x0C) + /* System-ID Register-1 RW */ + +/* System Reset register definitions */ +#define RST_STS_REG regptr(MSP_SLP_BASE + 0x10) + /* System Reset Status RO */ +#define RST_SET_REG regptr(MSP_SLP_BASE + 0x14) + /* System Set Reset WO */ +#define RST_CLR_REG regptr(MSP_SLP_BASE + 0x18) + /* System Clear Reset WO */ + +/* System Clock Registers */ +#define PCI_SLP_REG regptr(MSP_SLP_BASE + 0x1C) + /* PCI clock generator RW */ +#define URT_SLP_REG regptr(MSP_SLP_BASE + 0x20) + /* UART clock generator RW */ +/* reserved (MSP_SLP_BASE + 0x24) */ +/* reserved (MSP_SLP_BASE + 0x28) */ +#define PLL1_SLP_REG regptr(MSP_SLP_BASE + 0x2C) + /* PLL1 clock generator RW */ +#define PLL0_SLP_REG regptr(MSP_SLP_BASE + 0x30) + /* PLL0 clock generator RW */ +#define MIPS_SLP_REG regptr(MSP_SLP_BASE + 0x34) + /* MIPS clock generator RW */ +#define VE_SLP_REG regptr(MSP_SLP_BASE + 0x38) + /* Voice Eng clock generator RW */ +/* reserved (MSP_SLP_BASE + 0x3C) */ +#define MSB_SLP_REG regptr(MSP_SLP_BASE + 0x40) + /* MS-Bus clock generator RW */ +#define SMAC_SLP_REG regptr(MSP_SLP_BASE + 0x44) + /* Sec & MAC clock generator RW */ +#define PERF_SLP_REG regptr(MSP_SLP_BASE + 0x48) + /* Per & TDM clock generator RW */ + +/* Interrupt Controller Registers */ +#define SLP_INT_STS_REG regptr(MSP_SLP_BASE + 0x70) + /* Interrupt status register RW */ +#define SLP_INT_MSK_REG regptr(MSP_SLP_BASE + 0x74) + /* Interrupt enable/mask RW */ +#define SE_MBOX_REG regptr(MSP_SLP_BASE + 0x78) + /* Security Engine mailbox RW */ +#define VE_MBOX_REG regptr(MSP_SLP_BASE + 0x7C) + /* Voice Engine mailbox RW */ + +/* ELB Controller Registers */ +#define CS0_CNFG_REG regptr(MSP_SLP_BASE + 0x80) + /* ELB CS0 Configuration Reg */ +#define CS0_ADDR_REG regptr(MSP_SLP_BASE + 0x84) + /* ELB CS0 Base Address Reg */ +#define CS0_MASK_REG regptr(MSP_SLP_BASE + 0x88) + /* ELB CS0 Mask Register */ +#define CS0_ACCESS_REG regptr(MSP_SLP_BASE + 0x8C) + /* ELB CS0 access register */ + +#define CS1_CNFG_REG regptr(MSP_SLP_BASE + 0x90) + /* ELB CS1 Configuration Reg */ +#define CS1_ADDR_REG regptr(MSP_SLP_BASE + 0x94) + /* ELB CS1 Base Address Reg */ +#define CS1_MASK_REG regptr(MSP_SLP_BASE + 0x98) + /* ELB CS1 Mask Register */ +#define CS1_ACCESS_REG regptr(MSP_SLP_BASE + 0x9C) + /* ELB CS1 access register */ + +#define CS2_CNFG_REG regptr(MSP_SLP_BASE + 0xA0) + /* ELB CS2 Configuration Reg */ +#define CS2_ADDR_REG regptr(MSP_SLP_BASE + 0xA4) + /* ELB CS2 Base Address Reg */ +#define CS2_MASK_REG regptr(MSP_SLP_BASE + 0xA8) + /* ELB CS2 Mask Register */ +#define CS2_ACCESS_REG regptr(MSP_SLP_BASE + 0xAC) + /* ELB CS2 access register */ + +#define CS3_CNFG_REG regptr(MSP_SLP_BASE + 0xB0) + /* ELB CS3 Configuration Reg */ +#define CS3_ADDR_REG regptr(MSP_SLP_BASE + 0xB4) + /* ELB CS3 Base Address Reg */ +#define CS3_MASK_REG regptr(MSP_SLP_BASE + 0xB8) + /* ELB CS3 Mask Register */ +#define CS3_ACCESS_REG regptr(MSP_SLP_BASE + 0xBC) + /* ELB CS3 access register */ + +#define CS4_CNFG_REG regptr(MSP_SLP_BASE + 0xC0) + /* ELB CS4 Configuration Reg */ +#define CS4_ADDR_REG regptr(MSP_SLP_BASE + 0xC4) + /* ELB CS4 Base Address Reg */ +#define CS4_MASK_REG regptr(MSP_SLP_BASE + 0xC8) + /* ELB CS4 Mask Register */ +#define CS4_ACCESS_REG regptr(MSP_SLP_BASE + 0xCC) + /* ELB CS4 access register */ + +#define CS5_CNFG_REG regptr(MSP_SLP_BASE + 0xD0) + /* ELB CS5 Configuration Reg */ +#define CS5_ADDR_REG regptr(MSP_SLP_BASE + 0xD4) + /* ELB CS5 Base Address Reg */ +#define CS5_MASK_REG regptr(MSP_SLP_BASE + 0xD8) + /* ELB CS5 Mask Register */ +#define CS5_ACCESS_REG regptr(MSP_SLP_BASE + 0xDC) + /* ELB CS5 access register */ + +/* reserved 0xE0 - 0xE8 */ +#define ELB_1PC_EN_REG regptr(MSP_SLP_BASE + 0xEC) + /* ELB single PC card detect */ + +/* reserved 0xF0 - 0xF8 */ +#define ELB_CLK_CFG_REG regptr(MSP_SLP_BASE + 0xFC) + /* SDRAM read/ELB timing Reg */ + +/* Extended UART status registers */ +#define UART0_STATUS_REG regptr(MSP_UART0_BASE + 0x0c0) + /* UART Status Register 0 */ +#define UART1_STATUS_REG regptr(MSP_UART1_BASE + 0x170) + /* UART Status Register 1 */ + +/* Performance monitoring registers */ +#define PERF_MON_CTRL_REG regptr(MSP_SLP_BASE + 0x140) + /* Performance monitor control */ +#define PERF_MON_CLR_REG regptr(MSP_SLP_BASE + 0x144) + /* Performance monitor clear */ +#define PERF_MON_CNTH_REG regptr(MSP_SLP_BASE + 0x148) + /* Perf monitor counter high */ +#define PERF_MON_CNTL_REG regptr(MSP_SLP_BASE + 0x14C) + /* Perf monitor counter low */ + +/* System control registers */ +#define SYS_CTRL_REG regptr(MSP_SLP_BASE + 0x150) + /* System control register */ +#define SYS_ERR1_REG regptr(MSP_SLP_BASE + 0x154) + /* System Error status 1 */ +#define SYS_ERR2_REG regptr(MSP_SLP_BASE + 0x158) + /* System Error status 2 */ +#define SYS_INT_CFG_REG regptr(MSP_SLP_BASE + 0x15C) + /* System Interrupt config */ + +/* Voice Engine Memory configuration */ +#define VE_MEM_REG regptr(MSP_SLP_BASE + 0x17C) + /* Voice engine memory config */ + +/* CPU/SLP Error Status registers */ +#define CPU_ERR1_REG regptr(MSP_SLP_BASE + 0x180) + /* CPU/SLP Error status 1 */ +#define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184) + /* CPU/SLP Error status 1 */ + +#define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188) + /* Extended GPIO register */ + +/* System Error registers */ +#define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190) + /* Int status for SLP errors */ +#define SLP_ERR_MSK_REG regptr(MSP_SLP_BASE + 0x194) + /* Int mask for SLP errors */ +#define SLP_ELB_ERST_REG regptr(MSP_SLP_BASE + 0x198) + /* External ELB reset */ +#define SLP_BOOT_STS_REG regptr(MSP_SLP_BASE + 0x19C) + /* Boot Status */ + +/* Extended ELB addressing */ +#define CS0_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A0) + /* CS0 Extended address */ +#define CS1_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A4) + /* CS1 Extended address */ +#define CS2_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A8) + /* CS2 Extended address */ +#define CS3_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1AC) + /* CS3 Extended address */ +/* reserved 0x1B0 */ +#define CS5_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1B4) + /* CS5 Extended address */ + +/* PLL Adjustment registers */ +#define PLL_LOCK_REG regptr(MSP_SLP_BASE + 0x200) + /* PLL0 lock status */ +#define PLL_ARST_REG regptr(MSP_SLP_BASE + 0x204) + /* PLL Analog reset status */ +#define PLL0_ADJ_REG regptr(MSP_SLP_BASE + 0x208) + /* PLL0 Adjustment value */ +#define PLL1_ADJ_REG regptr(MSP_SLP_BASE + 0x20C) + /* PLL1 Adjustment value */ + +/* + *************************************************************************** + * Peripheral Register definitions * + *************************************************************************** + */ + +/* Peripheral status */ +#define PER_CTRL_REG regptr(MSP_PER_BASE + 0x50) + /* Peripheral control register */ +#define PER_STS_REG regptr(MSP_PER_BASE + 0x54) + /* Peripheral status register */ + +/* SPI/MPI Registers */ +#define SMPI_TX_SZ_REG regptr(MSP_PER_BASE + 0x58) + /* SPI/MPI Tx Size register */ +#define SMPI_RX_SZ_REG regptr(MSP_PER_BASE + 0x5C) + /* SPI/MPI Rx Size register */ +#define SMPI_CTL_REG regptr(MSP_PER_BASE + 0x60) + /* SPI/MPI Control register */ +#define SMPI_MS_REG regptr(MSP_PER_BASE + 0x64) + /* SPI/MPI Chip Select reg */ +#define SMPI_CORE_DATA_REG regptr(MSP_PER_BASE + 0xC0) + /* SPI/MPI Core Data reg */ +#define SMPI_CORE_CTRL_REG regptr(MSP_PER_BASE + 0xC4) + /* SPI/MPI Core Control reg */ +#define SMPI_CORE_STAT_REG regptr(MSP_PER_BASE + 0xC8) + /* SPI/MPI Core Status reg */ +#define SMPI_CORE_SSEL_REG regptr(MSP_PER_BASE + 0xCC) + /* SPI/MPI Core Ssel reg */ +#define SMPI_FIFO_REG regptr(MSP_PER_BASE + 0xD0) + /* SPI/MPI Data FIFO reg */ + +/* Peripheral Block Error Registers */ +#define PER_ERR_STS_REG regptr(MSP_PER_BASE + 0x70) + /* Error Bit Status Register */ +#define PER_ERR_MSK_REG regptr(MSP_PER_BASE + 0x74) + /* Error Bit Mask Register */ +#define PER_HDR1_REG regptr(MSP_PER_BASE + 0x78) + /* Error Header 1 Register */ +#define PER_HDR2_REG regptr(MSP_PER_BASE + 0x7C) + /* Error Header 2 Register */ + +/* Peripheral Block Interrupt Registers */ +#define PER_INT_STS_REG regptr(MSP_PER_BASE + 0x80) + /* Interrupt status register */ +#define PER_INT_MSK_REG regptr(MSP_PER_BASE + 0x84) + /* Interrupt Mask Register */ +#define GPIO_INT_STS_REG regptr(MSP_PER_BASE + 0x88) + /* GPIO interrupt status reg */ +#define GPIO_INT_MSK_REG regptr(MSP_PER_BASE + 0x8C) + /* GPIO interrupt MASK Reg */ + +/* POLO GPIO registers */ +#define POLO_GPIO_DAT1_REG regptr(MSP_PER_BASE + 0x0E0) + /* Polo GPIO[8:0] data reg */ +#define POLO_GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x0E4) + /* Polo GPIO[7:0] config reg */ +#define POLO_GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x0E8) + /* Polo GPIO[15:8] config reg */ +#define POLO_GPIO_OD1_REG regptr(MSP_PER_BASE + 0x0EC) + /* Polo GPIO[31:0] output drive */ +#define POLO_GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x170) + /* Polo GPIO[23:16] config reg */ +#define POLO_GPIO_DAT2_REG regptr(MSP_PER_BASE + 0x174) + /* Polo GPIO[15:9] data reg */ +#define POLO_GPIO_DAT3_REG regptr(MSP_PER_BASE + 0x178) + /* Polo GPIO[23:16] data reg */ +#define POLO_GPIO_DAT4_REG regptr(MSP_PER_BASE + 0x17C) + /* Polo GPIO[31:24] data reg */ +#define POLO_GPIO_DAT5_REG regptr(MSP_PER_BASE + 0x180) + /* Polo GPIO[39:32] data reg */ +#define POLO_GPIO_DAT6_REG regptr(MSP_PER_BASE + 0x184) + /* Polo GPIO[47:40] data reg */ +#define POLO_GPIO_DAT7_REG regptr(MSP_PER_BASE + 0x188) + /* Polo GPIO[54:48] data reg */ +#define POLO_GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C) + /* Polo GPIO[31:24] config reg */ +#define POLO_GPIO_CFG5_REG regptr(MSP_PER_BASE + 0x190) + /* Polo GPIO[39:32] config reg */ +#define POLO_GPIO_CFG6_REG regptr(MSP_PER_BASE + 0x194) + /* Polo GPIO[47:40] config reg */ +#define POLO_GPIO_CFG7_REG regptr(MSP_PER_BASE + 0x198) + /* Polo GPIO[54:48] config reg */ +#define POLO_GPIO_OD2_REG regptr(MSP_PER_BASE + 0x19C) + /* Polo GPIO[54:32] output drive */ + +/* Generic GPIO registers */ +#define GPIO_DATA1_REG regptr(MSP_PER_BASE + 0x170) + /* GPIO[1:0] data register */ +#define GPIO_DATA2_REG regptr(MSP_PER_BASE + 0x174) + /* GPIO[5:2] data register */ +#define GPIO_DATA3_REG regptr(MSP_PER_BASE + 0x178) + /* GPIO[9:6] data register */ +#define GPIO_DATA4_REG regptr(MSP_PER_BASE + 0x17C) + /* GPIO[15:10] data register */ +#define GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x180) + /* GPIO[1:0] config register */ +#define GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x184) + /* GPIO[5:2] config register */ +#define GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x188) + /* GPIO[9:6] config register */ +#define GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C) + /* GPIO[15:10] config register */ +#define GPIO_OD_REG regptr(MSP_PER_BASE + 0x190) + /* GPIO[15:0] output drive */ + +/* + *************************************************************************** + * CPU Interface register definitions * + *************************************************************************** + */ +#define PCI_FLUSH_REG regptr(MSP_CPUIF_BASE + 0x00) + /* PCI-SDRAM queue flush trigger */ +#define OCP_ERR1_REG regptr(MSP_CPUIF_BASE + 0x04) + /* OCP Error Attribute 1 */ +#define OCP_ERR2_REG regptr(MSP_CPUIF_BASE + 0x08) + /* OCP Error Attribute 2 */ +#define OCP_STS_REG regptr(MSP_CPUIF_BASE + 0x0C) + /* OCP Error Status */ +#define CPUIF_PM_REG regptr(MSP_CPUIF_BASE + 0x10) + /* CPU policy configuration */ +#define CPUIF_CFG_REG regptr(MSP_CPUIF_BASE + 0x10) + /* Misc configuration options */ + +/* Central Interrupt Controller Registers */ +#define MSP_CIC_BASE (MSP_CPUIF_BASE + 0x8000) + /* Central Interrupt registers */ +#define CIC_EXT_CFG_REG regptr(MSP_CIC_BASE + 0x00) + /* External interrupt config */ +#define CIC_STS_REG regptr(MSP_CIC_BASE + 0x04) + /* CIC Interrupt Status */ +#define CIC_VPE0_MSK_REG regptr(MSP_CIC_BASE + 0x08) + /* VPE0 Interrupt Mask */ +#define CIC_VPE1_MSK_REG regptr(MSP_CIC_BASE + 0x0C) + /* VPE1 Interrupt Mask */ +#define CIC_TC0_MSK_REG regptr(MSP_CIC_BASE + 0x10) + /* Thread Context 0 Int Mask */ +#define CIC_TC1_MSK_REG regptr(MSP_CIC_BASE + 0x14) + /* Thread Context 1 Int Mask */ +#define CIC_TC2_MSK_REG regptr(MSP_CIC_BASE + 0x18) + /* Thread Context 2 Int Mask */ +#define CIC_TC3_MSK_REG regptr(MSP_CIC_BASE + 0x18) + /* Thread Context 3 Int Mask */ +#define CIC_TC4_MSK_REG regptr(MSP_CIC_BASE + 0x18) + /* Thread Context 4 Int Mask */ +#define CIC_PCIMSI_STS_REG regptr(MSP_CIC_BASE + 0x18) +#define CIC_PCIMSI_MSK_REG regptr(MSP_CIC_BASE + 0x18) +#define CIC_PCIFLSH_REG regptr(MSP_CIC_BASE + 0x18) +#define CIC_VPE0_SWINT_REG regptr(MSP_CIC_BASE + 0x08) + + +/* + *************************************************************************** + * Memory controller registers * + *************************************************************************** + */ +#define MEM_CFG1_REG regptr(MSP_MEM_CFG_BASE + 0x00) +#define MEM_SS_ADDR regptr(MSP_MEM_CFG_BASE + 0x00) +#define MEM_SS_DATA regptr(MSP_MEM_CFG_BASE + 0x04) +#define MEM_SS_WRITE regptr(MSP_MEM_CFG_BASE + 0x08) + +/* + *************************************************************************** + * PCI controller registers * + *************************************************************************** + */ +#define PCI_BASE_REG regptr(MSP_PCI_BASE + 0x00) +#define PCI_CONFIG_SPACE_REG regptr(MSP_PCI_BASE + 0x800) +#define PCI_JTAG_DEVID_REG regptr(MSP_SLP_BASE + 0x13c) + +/* + ######################################################################## + # Register content & macro definitions # + ######################################################################## + */ + +/* + *************************************************************************** + * DEV_ID defines * + *************************************************************************** + */ +#define DEV_ID_PCI_DIS (1 << 26) /* Set if PCI disabled */ +#define DEV_ID_PCI_HOST (1 << 20) /* Set if PCI host */ +#define DEV_ID_SINGLE_PC (1 << 19) /* Set if single PC Card */ +#define DEV_ID_FAMILY (0xff << 8) /* family ID code */ +#define POLO_ZEUS_SUB_FAMILY (0x7 << 16) /* sub family for Polo/Zeus */ + +#define MSPFPGA_ID (0x00 << 8) /* you are on your own here */ +#define MSP5000_ID (0x50 << 8) +#define MSP4F00_ID (0x4f << 8) /* FPGA version of MSP4200 */ +#define MSP4E00_ID (0x4f << 8) /* FPGA version of MSP7120 */ +#define MSP4200_ID (0x42 << 8) +#define MSP4000_ID (0x40 << 8) +#define MSP2XXX_ID (0x20 << 8) +#define MSPZEUS_ID (0x10 << 8) + +#define MSP2004_SUB_ID (0x0 << 16) +#define MSP2005_SUB_ID (0x1 << 16) +#define MSP2006_SUB_ID (0x1 << 16) +#define MSP2007_SUB_ID (0x2 << 16) +#define MSP2010_SUB_ID (0x3 << 16) +#define MSP2015_SUB_ID (0x4 << 16) +#define MSP2020_SUB_ID (0x5 << 16) +#define MSP2100_SUB_ID (0x6 << 16) + +/* + *************************************************************************** + * RESET defines * + *************************************************************************** + */ +#define MSP_GR_RST (0x01 << 0) /* Global reset bit */ +#define MSP_MR_RST (0x01 << 1) /* MIPS reset bit */ +#define MSP_PD_RST (0x01 << 2) /* PVC DMA reset bit */ +#define MSP_PP_RST (0x01 << 3) /* PVC reset bit */ +/* reserved */ +#define MSP_EA_RST (0x01 << 6) /* Mac A reset bit */ +#define MSP_EB_RST (0x01 << 7) /* Mac B reset bit */ +#define MSP_SE_RST (0x01 << 8) /* Security Eng reset bit */ +#define MSP_PB_RST (0x01 << 9) /* Per block reset bit */ +#define MSP_EC_RST (0x01 << 10) /* Mac C reset bit */ +#define MSP_TW_RST (0x01 << 11) /* TWI reset bit */ +#define MSP_SPI_RST (0x01 << 12) /* SPI/MPI reset bit */ +#define MSP_U1_RST (0x01 << 13) /* UART1 reset bit */ +#define MSP_U0_RST (0x01 << 14) /* UART0 reset bit */ + +/* + *************************************************************************** + * UART defines * + *************************************************************************** + */ +#ifndef CONFIG_MSP_FPGA +#define MSP_BASE_BAUD 25000000 +#else +#define MSP_BASE_BAUD 6000000 +#endif +#define MSP_UART_REG_LEN 0x20 + +/* + *************************************************************************** + * ELB defines * + *************************************************************************** + */ +#define PCCARD_32 0x02 /* Set if is PCCARD 32 (Cardbus) */ +#define SINGLE_PCCARD 0x01 /* Set to enable single PC card */ + +/* + *************************************************************************** + * CIC defines * + *************************************************************************** + */ + +/* CIC_EXT_CFG_REG */ +#define EXT_INT_POL(eirq) (1 << (eirq + 8)) +#define EXT_INT_EDGE(eirq) (1 << eirq) + +#define CIC_EXT_SET_TRIGGER_LEVEL(reg, eirq) (reg &= ~EXT_INT_EDGE(eirq)) +#define CIC_EXT_SET_TRIGGER_EDGE(reg, eirq) (reg |= EXT_INT_EDGE(eirq)) +#define CIC_EXT_SET_ACTIVE_HI(reg, eirq) (reg |= EXT_INT_POL(eirq)) +#define CIC_EXT_SET_ACTIVE_LO(reg, eirq) (reg &= ~EXT_INT_POL(eirq)) +#define CIC_EXT_SET_ACTIVE_RISING CIC_EXT_SET_ACTIVE_HI +#define CIC_EXT_SET_ACTIVE_FALLING CIC_EXT_SET_ACTIVE_LO + +#define CIC_EXT_IS_TRIGGER_LEVEL(reg, eirq) \ + ((reg & EXT_INT_EDGE(eirq)) == 0) +#define CIC_EXT_IS_TRIGGER_EDGE(reg, eirq) (reg & EXT_INT_EDGE(eirq)) +#define CIC_EXT_IS_ACTIVE_HI(reg, eirq) (reg & EXT_INT_POL(eirq)) +#define CIC_EXT_IS_ACTIVE_LO(reg, eirq) \ + ((reg & EXT_INT_POL(eirq)) == 0) +#define CIC_EXT_IS_ACTIVE_RISING CIC_EXT_IS_ACTIVE_HI +#define CIC_EXT_IS_ACTIVE_FALLING CIC_EXT_IS_ACTIVE_LO + +/* + *************************************************************************** + * Memory Controller defines * + *************************************************************************** + */ + +/* Indirect memory controller registers */ +#define DDRC_CFG(n) (n) +#define DDRC_DEBUG(n) (0x04 + n) +#define DDRC_CTL(n) (0x40 + n) + +/* Macro to perform DDRC indirect write */ +#define DDRC_INDIRECT_WRITE(reg, mask, value) \ +({ \ + *MEM_SS_ADDR = (((mask) & 0xf) << 8) | ((reg) & 0xff); \ + *MEM_SS_DATA = (value); \ + *MEM_SS_WRITE = 1; \ +}) + +/* + *************************************************************************** + * SPI/MPI Mode * + *************************************************************************** + */ +#define SPI_MPI_RX_BUSY 0x00008000 /* SPI/MPI Receive Busy */ +#define SPI_MPI_FIFO_EMPTY 0x00004000 /* SPI/MPI Fifo Empty */ +#define SPI_MPI_TX_BUSY 0x00002000 /* SPI/MPI Transmit Busy */ +#define SPI_MPI_FIFO_FULL 0x00001000 /* SPI/MPU FIFO full */ + +/* + *************************************************************************** + * SPI/MPI Control Register * + *************************************************************************** + */ +#define SPI_MPI_RX_START 0x00000004 /* Start receive command */ +#define SPI_MPI_FLUSH_Q 0x00000002 /* Flush SPI/MPI Queue */ +#define SPI_MPI_TX_START 0x00000001 /* Start Transmit Command */ + +#endif /* !_ASM_MSP_REGS_H */ diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h new file mode 100644 index 000000000000..96d4c8ce8c83 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h @@ -0,0 +1,141 @@ +/* + * Defines for the MSP interrupt controller. + * + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. + * Author: Carsten Langgaard, carstenl@mips.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 _MSP_SLP_INT_H +#define _MSP_SLP_INT_H + +/* + * The PMC-Sierra SLP interrupts are arranged in a 3 level cascaded + * hierarchical system. The first level are the direct MIPS interrupts + * and are assigned the interrupt range 0-7. The second level is the SLM + * interrupt controller and is assigned the range 8-39. The third level + * comprises the Peripherial block, the PCI block, the PCI MSI block and + * the SLP. The PCI interrupts and the SLP errors are handled by the + * relevant subsystems so the core interrupt code needs only concern + * itself with the Peripheral block. These are assigned interrupts in + * the range 40-71. + */ + +/* + * IRQs directly connected to CPU + */ +#define MSP_MIPS_INTBASE 0 +#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */ +#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */ +#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */ +#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */ +#define MSP_INT_C_IRQ2 4 /* Wired off, C_IRQ2 */ +#define MSP_INT_VE 5 /* IRQ for Voice Engine, C_IRQ3 */ +#define MSP_INT_SLP 6 /* IRQ for SLM block, C_IRQ4 */ +#define MSP_INT_TIMER 7 /* IRQ for the MIPS timer, C_IRQ5 */ + +/* + * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4) + * These defines should be tied to the register definition for the SLM + * interrupt routine. For now, just use hard-coded values. + */ +#define MSP_SLP_INTBASE (MSP_MIPS_INTBASE + 8) +#define MSP_INT_EXT0 (MSP_SLP_INTBASE + 0) + /* External interrupt 0 */ +#define MSP_INT_EXT1 (MSP_SLP_INTBASE + 1) + /* External interrupt 1 */ +#define MSP_INT_EXT2 (MSP_SLP_INTBASE + 2) + /* External interrupt 2 */ +#define MSP_INT_EXT3 (MSP_SLP_INTBASE + 3) + /* External interrupt 3 */ +/* Reserved 4-7 */ + +/* + ************************************************************************* + * DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER * + * Some MSP produces have this interrupt labelled as Voice and some are * + * SEC mbox ... * + ************************************************************************* + */ +#define MSP_INT_SLP_VE (MSP_SLP_INTBASE + 8) + /* Cascaded IRQ for Voice Engine*/ +#define MSP_INT_SLP_TDM (MSP_SLP_INTBASE + 9) + /* TDM interrupt */ +#define MSP_INT_SLP_MAC0 (MSP_SLP_INTBASE + 10) + /* Cascaded IRQ for MAC 0 */ +#define MSP_INT_SLP_MAC1 (MSP_SLP_INTBASE + 11) + /* Cascaded IRQ for MAC 1 */ +#define MSP_INT_SEC (MSP_SLP_INTBASE + 12) + /* IRQ for security engine */ +#define MSP_INT_PER (MSP_SLP_INTBASE + 13) + /* Peripheral interrupt */ +#define MSP_INT_TIMER0 (MSP_SLP_INTBASE + 14) + /* SLP timer 0 */ +#define MSP_INT_TIMER1 (MSP_SLP_INTBASE + 15) + /* SLP timer 1 */ +#define MSP_INT_TIMER2 (MSP_SLP_INTBASE + 16) + /* SLP timer 2 */ +#define MSP_INT_SLP_TIMER (MSP_SLP_INTBASE + 17) + /* Cascaded MIPS timer */ +#define MSP_INT_BLKCP (MSP_SLP_INTBASE + 18) + /* Block Copy */ +#define MSP_INT_UART0 (MSP_SLP_INTBASE + 19) + /* UART 0 */ +#define MSP_INT_PCI (MSP_SLP_INTBASE + 20) + /* PCI subsystem */ +#define MSP_INT_PCI_DBELL (MSP_SLP_INTBASE + 21) + /* PCI doorbell */ +#define MSP_INT_PCI_MSI (MSP_SLP_INTBASE + 22) + /* PCI Message Signal */ +#define MSP_INT_PCI_BC0 (MSP_SLP_INTBASE + 23) + /* PCI Block Copy 0 */ +#define MSP_INT_PCI_BC1 (MSP_SLP_INTBASE + 24) + /* PCI Block Copy 1 */ +#define MSP_INT_SLP_ERR (MSP_SLP_INTBASE + 25) + /* SLP error condition */ +#define MSP_INT_MAC2 (MSP_SLP_INTBASE + 26) + /* IRQ for MAC2 */ +/* Reserved 26-31 */ + +/* + * IRQs cascaded on SLP PER interrupt (MSP_INT_PER) + */ +#define MSP_PER_INTBASE (MSP_SLP_INTBASE + 32) +/* Reserved 0-1 */ +#define MSP_INT_UART1 (MSP_PER_INTBASE + 2) + /* UART 1 */ +/* Reserved 3-5 */ +#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6) + /* 2-wire */ +#define MSP_INT_TM0 (MSP_PER_INTBASE + 7) + /* Peripheral timer block out 0 */ +#define MSP_INT_TM1 (MSP_PER_INTBASE + 8) + /* Peripheral timer block out 1 */ +/* Reserved 9 */ +#define MSP_INT_SPRX (MSP_PER_INTBASE + 10) + /* SPI RX complete */ +#define MSP_INT_SPTX (MSP_PER_INTBASE + 11) + /* SPI TX complete */ +#define MSP_INT_GPIO (MSP_PER_INTBASE + 12) + /* GPIO */ +#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13) + /* Peripheral error */ +/* Reserved 14-31 */ + +#endif /* !_MSP_SLP_INT_H */ From 9267a30d1dc7dcd7cadb5eb6a5bbfed703feeefa Mon Sep 17 00:00:00 2001 From: Marc St-Jean Date: Thu, 14 Jun 2007 15:55:31 -0600 Subject: [PATCH 507/551] [MIPS] PMC MSP71xx mips common Patch to add mips common support for the PMC-Sierra MSP71xx devices. Signed-off-by: Marc St-Jean Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 35 +++++++++++++++++++++++++++ arch/mips/Makefile | 11 ++++++++- arch/mips/kernel/cpu-probe.c | 20 ++++++++++++++++ arch/mips/kernel/head.S | 5 +++- arch/mips/kernel/traps.c | 6 +++++ arch/mips/pmc-sierra/Kconfig | 46 ++++++++++++++++++++++++++++++++++++ include/asm-mips/bootinfo.h | 12 ++++++++++ include/asm-mips/cpu.h | 2 ++ include/asm-mips/mipsregs.h | 33 ++++++++++++++++++++++++++ include/asm-mips/war.h | 11 +++++++++ 10 files changed, 179 insertions(+), 2 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3994f611ec26..2076d472ea99 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -250,6 +250,7 @@ config MIPS_SIM select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select IRQ_CPU + select BOOT_RAW select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_EARLY_PRINTK @@ -333,6 +334,27 @@ config MACH_VR41XX select SYS_HAS_CPU_VR41XX select GENERIC_HARDIRQS_NO__DO_IRQ +config PMC_MSP + bool "PMC-Sierra MSP chipsets" + depends on EXPERIMENTAL + select DMA_NONCOHERENT + select SWAP_IO_SPACE + select NO_EXCEPT_FILL + select BOOT_RAW + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB + select IRQ_CPU + select SERIAL_8250 + select SERIAL_8250_CONSOLE + help + This adds support for the PMC-Sierra family of Multi-Service + Processor System-On-A-Chips. These parts include a number + of integrated peripherals, interfaces and DSPs in addition to + a variety of MIPS cores. + config PMC_YOSEMITE bool "PMC-Sierra Yosemite eval board" select DMA_COHERENT @@ -706,6 +728,9 @@ config ARC config ARCH_MAY_HAVE_PC_FDC bool +config BOOT_RAW + bool + config DMA_COHERENT bool @@ -812,6 +837,12 @@ config IRQ_CPU_RM7K config IRQ_CPU_RM9K bool +config IRQ_MSP_SLP + bool + +config IRQ_MSP_CIC + bool + config IRQ_MV64340 bool @@ -825,6 +856,9 @@ config MIPS_BOARDS_GEN config PCI_GT64XXX_PCI0 bool +config NO_EXCEPT_FILL + bool + config MIPS_TX3927 bool select HAS_TXX9_SERIAL @@ -886,6 +920,7 @@ config MIPS_L1_CACHE_SHIFT int default "4" if MACH_DECSTATION || SNI_RM default "7" if SGI_IP27 + default "4" if PMC_MSP4200_EVAL default "5" config HAVE_STD_PC_SERIAL_PORT diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6642ee5fdc46..2b9af2fd5507 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -342,6 +342,14 @@ core-$(CONFIG_MOMENCO_OCELOT) += arch/mips/gt64120/common/ \ cflags-$(CONFIG_MOMENCO_OCELOT) += -Iinclude/asm-mips/mach-ocelot load-$(CONFIG_MOMENCO_OCELOT) += 0xffffffff80100000 +# +# PMC-Sierra MSP SOCs +# +core-$(CONFIG_PMC_MSP) += arch/mips/pmc-sierra/msp71xx/ +cflags-$(CONFIG_PMC_MSP) += -Iinclude/asm-mips/pmc-sierra/msp71xx \ + -mno-branch-likely +load-$(CONFIG_PMC_MSP) += 0xffffffff80100000 + # # PMC-Sierra Yosemite # @@ -595,7 +603,8 @@ JIFFIES = jiffies_64 endif AFLAGS += $(cflags-y) -CFLAGS += $(cflags-y) +CFLAGS += $(cflags-y) \ + -D"VMLINUX_LOAD_ADDRESS=$(load-y)" LDFLAGS += -m $(ld-emul) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 23d8a3b7dd75..c6b8b074a81a 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -186,9 +186,29 @@ static inline void check_wait(void) } } +static inline void check_errata(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + switch (c->cputype) { + case CPU_34K: + /* + * Erratum "RPS May Cause Incorrect Instruction Execution" + * This code only handles VPE0, any SMP/SMTC/RTOS code + * making use of VPE1 will be responsable for that VPE. + */ + if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2) + write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS); + break; + default: + break; + } +} + void __init check_bugs32(void) { check_wait(); + check_errata(); } /* diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 1f096aa35bc0..f78538eceef7 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -129,16 +130,18 @@ #endif .endm +#ifndef CONFIG_NO_EXCEPT_FILL /* * Reserved space for exception handlers. * Necessary for machines which link their kernels at KSEG0. */ .fill 0x400 +#endif EXPORT(stext) # used for profiling EXPORT(_stext) -#ifndef CONFIG_MIPS_SIM +#ifdef CONFIG_BOOT_RAW /* * Give us a fighting chance of running if execution beings at the * kernel load address. This is needed because this platform does diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9b19a84d11ef..80ea4fa95bd9 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -69,6 +69,7 @@ extern asmlinkage void handle_reserved(void); extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, int has_fpu); +void (*board_watchpoint_handler)(struct pt_regs *regs); void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); void (*board_nmi_handler_setup)(void); @@ -833,6 +834,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs) asmlinkage void do_watch(struct pt_regs *regs) { + if (board_watchpoint_handler) { + (*board_watchpoint_handler)(regs); + return; + } + /* * We use the watch exception where available to detect stack * overflows. diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig index 24d514c9dff9..abbd0bbfabd7 100644 --- a/arch/mips/pmc-sierra/Kconfig +++ b/arch/mips/pmc-sierra/Kconfig @@ -1,3 +1,49 @@ +choice + prompt "PMC-Sierra MSP SOC type" + depends on PMC_MSP + +config PMC_MSP4200_EVAL + bool "PMC-Sierra MSP4200 Eval Board" + select IRQ_MSP_SLP + select HW_HAS_PCI + +config PMC_MSP4200_GW + bool "PMC-Sierra MSP4200 VoIP Gateway" + select IRQ_MSP_SLP + select HW_HAS_PCI + +config PMC_MSP7120_EVAL + bool "PMC-Sierra MSP7120 Eval Board" + select SYS_SUPPORTS_MULTITHREADING + select IRQ_MSP_CIC + select HW_HAS_PCI + +config PMC_MSP7120_GW + bool "PMC-Sierra MSP7120 Residential Gateway" + select SYS_SUPPORTS_MULTITHREADING + select IRQ_MSP_CIC + select HW_HAS_PCI + +config PMC_MSP7120_FPGA + bool "PMC-Sierra MSP7120 FPGA" + select SYS_SUPPORTS_MULTITHREADING + select IRQ_MSP_CIC + select HW_HAS_PCI + +endchoice + +menu "Options for PMC-Sierra MSP chipsets" + depends on PMC_MSP + +config PMC_MSP_EMBEDDED_ROOTFS + bool "Root filesystem embedded in kernel image" + select MTD + select MTD_BLOCK + select MTD_PMC_MSP_RAMROOT + select MTD_RAM + +endmenu + config HYPERTRANSPORT bool "Hypertransport Support for PMC-Sierra Yosemite" depends on PMC_YOSEMITE diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 12f9d7139ebf..94fc9be1aab6 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -213,6 +213,18 @@ #define MACH_GROUP_LEMOTE 27 #define MACH_LEMOTE_FULONG 0 +/* + * Valid machtype for group PMC-MSP + */ +#define MACH_GROUP_MSP 26 /* PMC-Sierra MSP boards/CPUs */ +#define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */ +#define MACH_MSP4200_GW 1 /* PMC-Sierra MSP4200 Gateway demo */ +#define MACH_MSP4200_FPGA 2 /* PMC-Sierra MSP4200 Emulation */ +#define MACH_MSP7120_EVAL 3 /* PMC-Sierra MSP7120 Evaluation */ +#define MACH_MSP7120_GW 4 /* PMC-Sierra MSP7120 Residential GW */ +#define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */ +#define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */ + #define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index a3623954dad1..3857358fb6de 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -109,6 +109,7 @@ * Definitions for 7:0 on legacy processors */ +#define PRID_REV_MASK 0x00ff #define PRID_REV_TX4927 0x0022 #define PRID_REV_TX4937 0x0030 @@ -125,6 +126,7 @@ #define PRID_REV_VR4122 0x0070 #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ #define PRID_REV_VR4130 0x0080 +#define PRID_REV_34K_V1_0_2 0x0022 /* * Older processors used to encode processor version and revision in two diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 668db02c2804..706b3691f57e 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -15,6 +15,7 @@ #include #include +#include /* * The following macros are especially useful for __asm__ @@ -537,6 +538,9 @@ #define MIPS_CONF7_WII (_ULCAST_(1) << 31) +#define MIPS_CONF7_RPS (_ULCAST_(1) << 2) + + /* * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. */ @@ -1298,10 +1302,39 @@ static inline void tlb_probe(void) static inline void tlb_read(void) { +#if MIPS34K_MISSED_ITLB_WAR + int res = 0; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41610001 # dvpe $1 \n" + " move %0, $1 \n" + " ehb \n" + " .set pop \n" + : "=r" (res)); + + instruction_hazard(); +#endif + __asm__ __volatile__( ".set noreorder\n\t" "tlbr\n\t" ".set reorder"); + +#if MIPS34K_MISSED_ITLB_WAR + if ((res & _ULCAST_(1))) + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41600021 # evpe \n" + " ehb \n" + " .set pop \n"); +#endif } static inline void tlb_write_indexed(void) diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index c507f1b8014e..45cb82724830 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -197,6 +197,14 @@ #define R10000_LLSC_WAR 1 #endif +/* + * 34K core erratum: "Problems Executing the TLBR Instruction" + */ +#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \ + defined(CONFIG_PMC_MSP7120_FPGA) +#define MIPS34K_MISSED_ITLB_WAR 1 +#endif + /* * Workarounds default to off */ @@ -236,5 +244,8 @@ #ifndef R10000_LLSC_WAR #define R10000_LLSC_WAR 0 #endif +#ifndef MIPS34K_MISSED_ITLB_WAR +#define MIPS34K_MISSED_ITLB_WAR 0 +#endif #endif /* _ASM_WAR_H */ From 6f95e60acf404e39d14030572c9033ddaca6f4de Mon Sep 17 00:00:00 2001 From: Marc St-Jean Date: Thu, 14 Jun 2007 15:56:23 -0600 Subject: [PATCH 508/551] [MIPS] PMC MSP71xx PCI support Patch to add PCI support for the PMC-Sierra MSP71xx devices. Signed-off-by: Marc St-Jean Signed-off-by: Ralf Baechle --- arch/mips/pci/Makefile | 3 + arch/mips/pci/fixup-pmcmsp.c | 216 ++++ arch/mips/pci/ops-pmcmsp.c | 994 ++++++++++++++++++ arch/mips/pmc-sierra/msp71xx/msp_pci.c | 50 + include/asm-mips/pmc-sierra/msp71xx/msp_pci.h | 205 ++++ 5 files changed, 1468 insertions(+) create mode 100644 arch/mips/pci/fixup-pmcmsp.c create mode 100644 arch/mips/pci/ops-pmcmsp.c create mode 100644 arch/mips/pmc-sierra/msp71xx/msp_pci.c create mode 100644 include/asm-mips/pmc-sierra/msp71xx/msp_pci.h diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 276a10b06bb5..c5845db55984 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -32,6 +32,9 @@ obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o +obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o +obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o +obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ pci-yosemite.o obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c new file mode 100644 index 000000000000..00261211dbfa --- /dev/null +++ b/arch/mips/pci/fixup-pmcmsp.c @@ -0,0 +1,216 @@ +/* + * PMC-Sierra MSP board specific pci fixups. + * + * Copyright 2001 MontaVista Software Inc. + * Copyright 2005-2007 PMC-Sierra, Inc + * + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef CONFIG_PCI + +#include +#include +#include +#include + +#include + +#include +#include + +/* PCI interrupt pins */ +#define IRQ4 MSP_INT_EXT4 +#define IRQ5 MSP_INT_EXT5 +#define IRQ6 MSP_INT_EXT6 + +#if defined(CONFIG_PMC_MSP7120_GW) +/* Garibaldi Board IRQ wiring to PCI slots */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */ + {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */ + {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */ + {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */ + {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */ + {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */ + {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */ + {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */ + {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */ + {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */ + {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */ + {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */ + {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */ + {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */ + {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */ + {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */ + {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */ + {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */ + {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */ + {0, IRQ4, IRQ4, 0, 0 }, /* 18 (AD[28]): slot 0 */ + {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */ + {0, IRQ5, IRQ5, 0, 0 }, /* 20 (AD[30]): slot 1 */ + {0, IRQ6, IRQ6, 0, 0 } /* 21 (AD[31]): slot 2 */ +}; + +#elif defined(CONFIG_PMC_MSP7120_EVAL) + +/* MSP7120 Eval Board IRQ wiring to PCI slots */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */ + {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */ + {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */ + {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */ + {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */ + {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */ + {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */ + {0, IRQ6, IRQ6, 0, 0 }, /* 6 (AD[16]): slot 3 (mini) */ + {0, IRQ5, IRQ5, 0, 0 }, /* 7 (AD[17]): slot 2 (mini) */ + {0, IRQ4, IRQ4, IRQ4, IRQ4}, /* 8 (AD[18]): slot 0 (PCI) */ + {0, IRQ5, IRQ5, IRQ5, IRQ5}, /* 9 (AD[19]): slot 1 (PCI) */ + {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */ + {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */ + {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */ + {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */ + {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */ + {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */ + {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */ + {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */ + {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */ + {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */ + {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */ + {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */ +}; + +#else + +/* Unknown board -- don't assign any IRQs */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */ + {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */ + {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */ + {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */ + {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */ + {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */ + {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */ + {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */ + {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */ + {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */ + {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */ + {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */ + {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */ + {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */ + {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */ + {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */ + {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */ + {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */ + {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */ + {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */ + {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */ + {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */ + {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */ + {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */ +}; +#endif + +/***************************************************************************** + * + * FUNCTION: pcibios_plat_dev_init + * _________________________________________________________________________ + * + * DESCRIPTION: Perform platform specific device initialization at + * pci_enable_device() time. + * None are needed for the MSP7120 PCI Controller. + * + * INPUTS: dev - structure describing the PCI device + * + * OUTPUTS: none + * + * RETURNS: PCIBIOS_SUCCESSFUL + * + ****************************************************************************/ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: pcibios_map_irq + * _________________________________________________________________________ + * + * DESCRIPTION: Perform board supplied PCI IRQ mapping routine. + * + * INPUTS: dev - unused + * slot - PCI slot. Identified by which bit of the AD[] bus + * drives the IDSEL line. AD[10] is 0, AD[31] is + * slot 21. + * pin - numbered using the scheme of the PCI_INTERRUPT_PIN + * field of the config header. + * + * OUTPUTS: none + * + * RETURNS: IRQ number + * + ****************************************************************************/ +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ +#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) + printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); +#endif + printk(KERN_WARNING "PCI: irq_tab returned %d for slot=%d pin=%d\n", + irq_tab[slot][pin], slot, pin); + + return irq_tab[slot][pin]; +} + +#endif /* CONFIG_PCI */ diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c new file mode 100644 index 000000000000..09fa007c1d1b --- /dev/null +++ b/arch/mips/pci/ops-pmcmsp.c @@ -0,0 +1,994 @@ +/* + * PMC-Sierra MSP board specific pci_ops + * + * Copyright 2001 MontaVista Software Inc. + * Copyright 2005-2007 PMC-Sierra, Inc + * + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven + * + * 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 PCI_COUNTERS 1 + +#include +#include +#include + +#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS) +#include +#include +#endif /* CONFIG_PROC_FS && PCI_COUNTERS */ + +#include +#include + +#include +#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) +#include +#endif + +#include +#include +#include +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS) +static char proc_init; +extern struct proc_dir_entry *proc_bus_pci_dir; +unsigned int pci_int_count[32]; + +static void pci_proc_init(void); + +/***************************************************************************** + * + * FUNCTION: read_msp_pci_counts + * _________________________________________________________________________ + * + * DESCRIPTION: Prints the count of how many times each PCI + * interrupt has asserted. Can be invoked by the + * /proc filesystem. + * + * INPUTS: page - part of STDOUT calculation + * off - part of STDOUT calculation + * count - part of STDOUT calculation + * data - unused + * + * OUTPUTS: start - new start location + * eof - end of file pointer + * + * RETURNS: len - STDOUT length + * + ****************************************************************************/ +static int read_msp_pci_counts(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int i; + int len = 0; + unsigned int intcount, total = 0; + + for (i = 0; i < 32; ++i) { + intcount = pci_int_count[i]; + if (intcount != 0) { + len += sprintf(page + len, "[%d] = %u\n", i, intcount); + total += intcount; + } + } + + len += sprintf(page + len, "total = %u\n", total); + if (len <= off+count) + *eof = 1; + + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + + return len; +} + +/***************************************************************************** + * + * FUNCTION: gen_pci_cfg_wr + * _________________________________________________________________________ + * + * DESCRIPTION: Generates a configuration write cycle for debug purposes. + * The IDSEL line asserted and location and data written are + * immaterial. Just want to be able to prove that a + * configuration write can be correctly generated on the + * PCI bus. Intent is that this function by invocable from + * the /proc filesystem. + * + * INPUTS: page - part of STDOUT calculation + * off - part of STDOUT calculation + * count - part of STDOUT calculation + * data - unused + * + * OUTPUTS: start - new start location + * eof - end of file pointer + * + * RETURNS: len - STDOUT length + * + ****************************************************************************/ +static int gen_pci_cfg_wr(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + unsigned char where = 0; /* Write to static Device/Vendor ID */ + unsigned char bus_num = 0; /* Bus 0 */ + unsigned char dev_fn = 0xF; /* Arbitrary device number */ + u32 wr_data = 0xFF00AA00; /* Arbitrary data */ + struct msp_pci_regs *preg = (void *)PCI_BASE_REG; + int len = 0; + unsigned long value; + int intr; + + len += sprintf(page + len, "PMC MSP PCI: Beginning\n"); + + if (proc_init == 0) { + pci_proc_init(); + proc_init = ~0; + } + + len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n"); + + /* + * Generate PCI Configuration Write Cycle + */ + + /* Clear cause register bits */ + preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); + + /* Setup address that is to appear on PCI bus */ + preg->config_addr = BPCI_CFGADDR_ENABLE | + (bus_num << BPCI_CFGADDR_BUSNUM_SHF) | + (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) | + (where & 0xFC); + + value = cpu_to_le32(wr_data); + + /* Launch the PCI configuration write cycle */ + *PCI_CONFIG_SPACE_REG = value; + + /* + * Check if the PCI configuration cycle (rd or wr) succeeded, by + * checking the status bits for errors like master or target abort. + */ + intr = preg->if_status; + + len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n"); + + /* Handle STDOUT calculations */ + if (len <= off+count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + + return len; +} + +/***************************************************************************** + * + * FUNCTION: pci_proc_init + * _________________________________________________________________________ + * + * DESCRIPTION: Create entries in the /proc filesystem for debug access. + * + * INPUTS: none + * + * OUTPUTS: none + * + * RETURNS: none + * + ****************************************************************************/ +static void pci_proc_init(void) +{ + create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL, + read_msp_pci_counts, NULL); + create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL, + gen_pci_cfg_wr, NULL); +} +#endif /* CONFIG_PROC_FS && PCI_COUNTERS */ + +spinlock_t bpci_lock = SPIN_LOCK_UNLOCKED; + +/***************************************************************************** + * + * STRUCT: pci_io_resource + * _________________________________________________________________________ + * + * DESCRIPTION: Defines the address range that pciauto() will use to + * assign to the I/O BARs of PCI devices. + * + * Use the start and end addresses of the MSP7120 PCI Host + * Controller I/O space, in the form that they appear on the + * PCI bus AFTER MSP7120 has performed address translation. + * + * For I/O accesses, MSP7120 ignores OATRAN and maps I/O + * accesses into the bottom 0xFFF region of address space, + * so that is the range to put into the pci_io_resource + * struct. + * + * In MSP4200, the start address was 0x04 instead of the + * expected 0x00. Will just assume there was a good reason + * for this! + * + * NOTES: Linux, by default, will assign I/O space to the lowest + * region of address space. Since MSP7120 and Linux, + * by default, have no offset in between how they map, the + * io_offset element of pci_controller struct should be set + * to zero. + * ELEMENTS: + * name - String used for a meaningful name. + * + * start - Start address of MSP7120's I/O space, as MSP7120 presents + * the address on the PCI bus. + * + * end - End address of MSP7120's I/O space, as MSP7120 presents + * the address on the PCI bus. + * + * flags - Attributes indicating the type of resource. In this case, + * indicate I/O space. + * + ****************************************************************************/ +static struct resource pci_io_resource = { + .name = "pci IO space", + .start = 0x04, + .end = 0x0FFF, + .flags = IORESOURCE_IO /* I/O space */ +}; + +/***************************************************************************** + * + * STRUCT: pci_mem_resource + * _________________________________________________________________________ + * + * DESCRIPTION: Defines the address range that pciauto() will use to + * assign to the memory BARs of PCI devices. + * + * The .start and .end values are dependent upon how address + * translation is performed by the OATRAN regiser. + * + * The values to use for .start and .end are the values + * in the form they appear on the PCI bus AFTER MSP7120 has + * performed OATRAN address translation. + * + * ELEMENTS: + * name - String used for a meaningful name. + * + * start - Start address of MSP7120's memory space, as MSP7120 presents + * the address on the PCI bus. + * + * end - End address of MSP7120's memory space, as MSP7120 presents + * the address on the PCI bus. + * + * flags - Attributes indicating the type of resource. In this case, + * indicate memory space. + * + ****************************************************************************/ +static struct resource pci_mem_resource = { + .name = "pci memory space", + .start = MSP_PCI_SPACE_BASE, + .end = MSP_PCI_SPACE_END, + .flags = IORESOURCE_MEM /* memory space */ +}; + +/***************************************************************************** + * + * FUNCTION: bpci_interrupt + * _________________________________________________________________________ + * + * DESCRIPTION: PCI status interrupt handler. Updates the count of how + * many times each status bit has been set, then clears + * the status bits. If the appropriate macros are defined, + * these counts can be viewed via the /proc filesystem. + * + * INPUTS: irq - unused + * dev_id - unused + * pt_regs - unused + * + * OUTPUTS: none + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * + ****************************************************************************/ +static int bpci_interrupt(int irq, void *dev_id) +{ + struct msp_pci_regs *preg = (void *)PCI_BASE_REG; + unsigned int stat = preg->if_status; + +#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS) + int i; + for (i = 0; i < 32; ++i) { + if ((1 << i) & stat) + ++pci_int_count[i]; + } +#endif /* PROC_FS && PCI_COUNTERS */ + + /* printk("PCI ISR: Status=%08X\n", stat); */ + + /* write to clear all asserted interrupts */ + preg->if_status = stat; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_config_access + * _________________________________________________________________________ + * + * DESCRIPTION: Performs a PCI configuration access (rd or wr), then + * checks that the access succeeded by querying MSP7120's + * PCI status bits. + * + * INPUTS: + * access_type - kind of PCI configuration cycle to perform + * (read or write). Legal values are + * PCI_ACCESS_WRITE and PCI_ACCESS_READ. + * + * bus - pointer to the bus number of the device to + * be targetted for the configuration cycle. + * The only element of the pci_bus structure + * used is bus->number. This argument determines + * if the configuration access will be Type 0 or + * Type 1. Since MSP7120 assumes itself to be the + * PCI Host, any non-zero bus->number generates + * a Type 1 access. + * + * devfn - this is an 8-bit field. The lower three bits + * specify the function number of the device to + * be targetted for the configuration cycle, with + * all three-bit combinations being legal. The + * upper five bits specify the device number, + * with legal values being 10 to 31. + * + * where - address within the Configuration Header + * space to access. + * + * data - for write accesses, contains the data to + * write. + * + * OUTPUTS: + * data - for read accesses, contains the value read. + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * -1 - access failure + * + ****************************************************************************/ +int msp_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, + unsigned char where, + u32 *data) +{ + struct msp_pci_regs *preg = (void *)PCI_BASE_REG; + unsigned char bus_num = bus->number; + unsigned char dev_fn = (unsigned char)devfn; + unsigned long flags; + unsigned long intr; + unsigned long value; + static char pciirqflag; +#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) + unsigned int vpe_status; +#endif + +#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS) + if (proc_init == 0) { + pci_proc_init(); + proc_init = ~0; + } +#endif /* CONFIG_PROC_FS && PCI_COUNTERS */ + + /* + * Just the first time this function invokes, allocate + * an interrupt line for PCI host status interrupts. The + * allocation assigns an interrupt handler to the interrupt. + */ + if (pciirqflag == 0) { + request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */ + bpci_interrupt, + SA_SHIRQ | SA_INTERRUPT, + "PMC MSP PCI Host", + preg); + pciirqflag = ~0; + } + +#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) + local_irq_save(flags); + vpe_status = dvpe(); +#else + spin_lock_irqsave(&bpci_lock, flags); +#endif + + /* + * Clear PCI cause register bits. + * + * In Polo, the PCI Host had a dedicated DMA called the + * Block Copy (not to be confused with the general purpose Block + * Copy Engine block). There appear to have been special interrupts + * for this Block Copy, called Block Copy 0 Fault (BC0F) and + * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this + * dedicated Block Copy block, so these two interrupts are now + * marked reserved. In case the Block Copy is resurrected in a + * future design, maintain the code that treats these two interrupts + * specially. + * + * Write to clear all interrupts in the PCI status register, aside + * from BC0F and BC1F. + */ + preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); + + /* Setup address that is to appear on PCI bus */ + preg->config_addr = BPCI_CFGADDR_ENABLE | + (bus_num << BPCI_CFGADDR_BUSNUM_SHF) | + (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) | + (where & 0xFC); + + /* IF access is a PCI configuration write */ + if (access_type == PCI_ACCESS_WRITE) { + value = cpu_to_le32(*data); + *PCI_CONFIG_SPACE_REG = value; + } else { + /* ELSE access is a PCI configuration read */ + value = le32_to_cpu(*PCI_CONFIG_SPACE_REG); + *data = value; + } + + /* + * Check if the PCI configuration cycle (rd or wr) succeeded, by + * checking the status bits for errors like master or target abort. + */ + intr = preg->if_status; + + /* Clear config access */ + preg->config_addr = 0; + + /* IF error occurred */ + if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) { + /* Clear status bits */ + preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F); + +#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) + evpe(vpe_status); + local_irq_restore(flags); +#else + spin_unlock_irqrestore(&bpci_lock, flags); +#endif + + return -1; + } + +#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) + evpe(vpe_status); + local_irq_restore(flags); +#else + spin_unlock_irqrestore(&bpci_lock, flags); +#endif + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_read_config_byte + * _________________________________________________________________________ + * + * DESCRIPTION: Read a byte from PCI configuration address spac + * Since the hardware can't address 8 bit chunks + * directly, read a 32-bit chunk, then mask off extraneous + * bits. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the read is destined for. + * devfn - device/function combination that the read is + * destined for. + * where - register within the Configuration Header space + * to access. + * + * OUTPUTS val - read data + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * -1 - read access failure + * + ****************************************************************************/ +static int +msp_pcibios_read_config_byte(struct pci_bus *bus, + unsigned int devfn, + int where, + u32 *val) +{ + u32 data = 0; + + /* + * If the config access did not complete normally (e.g., underwent + * master abort) do the PCI compliant thing, which is to supply an + * all ones value. + */ + if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) { + *val = 0xFFFFFFFF; + return -1; + } + + *val = (data >> ((where & 3) << 3)) & 0x0ff; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_read_config_word + * _________________________________________________________________________ + * + * DESCRIPTION: Read a word (16 bits) from PCI configuration address space. + * Since the hardware can't address 16 bit chunks + * directly, read a 32-bit chunk, then mask off extraneous + * bits. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the read is destined for. + * devfn - device/function combination that the read is + * destined for. + * where - register within the Configuration Header space + * to access. + * + * OUTPUTS val - read data + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * PCIBIOS_BAD_REGISTER_NUMBER - bad register address + * -1 - read access failure + * + ****************************************************************************/ +static int +msp_pcibios_read_config_word(struct pci_bus *bus, + unsigned int devfn, + int where, + u32 *val) +{ + u32 data = 0; + + /* if (where & 1) */ /* Commented out non-compliant code. + * Should allow word access to configuration + * registers, with only exception being when + * the word access would wrap around into + * the next dword. + */ + if ((where & 3) == 3) { + *val = 0xFFFFFFFF; + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + /* + * If the config access did not complete normally (e.g., underwent + * master abort) do the PCI compliant thing, which is to supply an + * all ones value. + */ + if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) { + *val = 0xFFFFFFFF; + return -1; + } + + *val = (data >> ((where & 3) << 3)) & 0x0ffff; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_read_config_dword + * _________________________________________________________________________ + * + * DESCRIPTION: Read a double word (32 bits) from PCI configuration + * address space. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the read is destined for. + * devfn - device/function combination that the read is + * destined for. + * where - register within the Configuration Header space + * to access. + * + * OUTPUTS val - read data + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * PCIBIOS_BAD_REGISTER_NUMBER - bad register address + * -1 - read access failure + * + ****************************************************************************/ +static int +msp_pcibios_read_config_dword(struct pci_bus *bus, + unsigned int devfn, + int where, + u32 *val) +{ + u32 data = 0; + + /* Address must be dword aligned. */ + if (where & 3) { + *val = 0xFFFFFFFF; + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + /* + * If the config access did not complete normally (e.g., underwent + * master abort) do the PCI compliant thing, which is to supply an + * all ones value. + */ + if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) { + *val = 0xFFFFFFFF; + return -1; + } + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_write_config_byte + * _________________________________________________________________________ + * + * DESCRIPTION: Write a byte to PCI configuration address space. + * Since the hardware can't address 8 bit chunks + * directly, a read-modify-write is performed. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the write is destined for. + * devfn - device/function combination that the write is + * destined for. + * where - register within the Configuration Header space + * to access. + * val - value to write + * + * OUTPUTS none + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * -1 - write access failure + * + ****************************************************************************/ +static int +msp_pcibios_write_config_byte(struct pci_bus *bus, + unsigned int devfn, + int where, + u8 val) +{ + u32 data = 0; + + /* read config space */ + if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + /* modify the byte within the dword */ + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + /* write back the full dword */ + if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, + where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_write_config_word + * _________________________________________________________________________ + * + * DESCRIPTION: Write a word (16-bits) to PCI configuration address space. + * Since the hardware can't address 16 bit chunks + * directly, a read-modify-write is performed. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the write is destined for. + * devfn - device/function combination that the write is + * destined for. + * where - register within the Configuration Header space + * to access. + * val - value to write + * + * OUTPUTS none + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * PCIBIOS_BAD_REGISTER_NUMBER - bad register address + * -1 - write access failure + * + ****************************************************************************/ +static int +msp_pcibios_write_config_word(struct pci_bus *bus, + unsigned int devfn, + int where, + u16 val) +{ + u32 data = 0; + + /* Fixed non-compliance: if (where & 1) */ + if ((where & 3) == 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* read config space */ + if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, + where, &data)) + return -1; + + /* modify the word within the dword */ + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + /* write back the full dword */ + if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, + where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_write_config_dword + * _________________________________________________________________________ + * + * DESCRIPTION: Write a double word (32-bits) to PCI configuration address + * space. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the write is destined for. + * devfn - device/function combination that the write is + * destined for. + * where - register within the Configuration Header space + * to access. + * val - value to write + * + * OUTPUTS none + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * PCIBIOS_BAD_REGISTER_NUMBER - bad register address + * -1 - write access failure + * + ****************************************************************************/ +static int +msp_pcibios_write_config_dword(struct pci_bus *bus, + unsigned int devfn, + int where, + u32 val) +{ + /* check that address is dword aligned */ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* perform write */ + if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, + where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_read_config + * _________________________________________________________________________ + * + * DESCRIPTION: Interface the PCI configuration read request with + * the appropriate function, based on how many bytes + * the read request is. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the write is destined for. + * devfn - device/function combination that the write is + * destined for. + * where - register within the Configuration Header space + * to access. + * size - in units of bytes, should be 1, 2, or 4. + * + * OUTPUTS val - value read, with any extraneous bytes masked + * to zero. + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * -1 - failure + * + ****************************************************************************/ +int +msp_pcibios_read_config(struct pci_bus *bus, + unsigned int devfn, + int where, + int size, + u32 *val) +{ + if (size == 1) { + if (msp_pcibios_read_config_byte(bus, devfn, where, val)) { + return -1; + } + } else if (size == 2) { + if (msp_pcibios_read_config_word(bus, devfn, where, val)) { + return -1; + } + } else if (size == 4) { + if (msp_pcibios_read_config_dword(bus, devfn, where, val)) { + return -1; + } + } else { + *val = 0xFFFFFFFF; + return -1; + } + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * FUNCTION: msp_pcibios_write_config + * _________________________________________________________________________ + * + * DESCRIPTION: Interface the PCI configuration write request with + * the appropriate function, based on how many bytes + * the read request is. + * + * INPUTS bus - structure containing attributes for the PCI bus + * that the write is destined for. + * devfn - device/function combination that the write is + * destined for. + * where - register within the Configuration Header space + * to access. + * size - in units of bytes, should be 1, 2, or 4. + * val - value to write + * + * OUTPUTS: none + * + * RETURNS: PCIBIOS_SUCCESSFUL - success + * -1 - failure + * + ****************************************************************************/ +int +msp_pcibios_write_config(struct pci_bus *bus, + unsigned int devfn, + int where, + int size, + u32 val) +{ + if (size == 1) { + if (msp_pcibios_write_config_byte(bus, devfn, + where, (u8)(0xFF & val))) { + return -1; + } + } else if (size == 2) { + if (msp_pcibios_write_config_word(bus, devfn, + where, (u16)(0xFFFF & val))) { + return -1; + } + } else if (size == 4) { + if (msp_pcibios_write_config_dword(bus, devfn, where, val)) { + return -1; + } + } else { + return -1; + } + + return PCIBIOS_SUCCESSFUL; +} + +/***************************************************************************** + * + * STRUCTURE: msp_pci_ops + * _________________________________________________________________________ + * + * DESCRIPTION: structure to abstract the hardware specific PCI + * configuration accesses. + * + * ELEMENTS: + * read - function for Linux to generate PCI Configuration reads. + * write - function for Linux to generate PCI Configuration writes. + * + ****************************************************************************/ +struct pci_ops msp_pci_ops = { + .read = msp_pcibios_read_config, + .write = msp_pcibios_write_config +}; + +/***************************************************************************** + * + * STRUCTURE: msp_pci_controller + * _________________________________________________________________________ + * + * Describes the attributes of the MSP7120 PCI Host Controller + * + * ELEMENTS: + * pci_ops - abstracts the hardware specific PCI configuration + * accesses. + * + * mem_resource - address range pciauto() uses to assign to PCI device + * memory BARs. + * + * mem_offset - offset between how MSP7120 outbound PCI memory + * transaction addresses appear on the PCI bus and how Linux + * wants to configure memory BARs of the PCI devices. + * MSP7120 does nothing funky, so just set to zero. + * + * io_resource - address range pciauto() uses to assign to PCI device + * I/O BARs. + * + * io_offset - offset between how MSP7120 outbound PCI I/O + * transaction addresses appear on the PCI bus and how + * Linux defaults to configure I/O BARs of the PCI devices. + * MSP7120 maps outbound I/O accesses into the bottom + * bottom 4K of PCI address space (and ignores OATRAN). + * Since the Linux default is to configure I/O BARs to the + * bottom 4K, no special offset is needed. Just set to zero. + * + ****************************************************************************/ +static struct pci_controller msp_pci_controller = { + .pci_ops = &msp_pci_ops, + .mem_resource = &pci_mem_resource, + .mem_offset = 0, + .io_resource = &pci_io_resource, + .io_offset = 0 +}; + +/***************************************************************************** + * + * FUNCTION: msp_pci_init + * _________________________________________________________________________ + * + * DESCRIPTION: Initialize the PCI Host Controller and register it with + * Linux so Linux can seize control of the PCI bus. + * + ****************************************************************************/ +void __init msp_pci_init(void) +{ + struct msp_pci_regs *preg = (void *)PCI_BASE_REG; + u32 id; + + /* Extract Device ID */ + id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12; + + /* Check if JTAG ID identifies MSP7120 */ + if (!MSP_HAS_PCI(id)) { + printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id); + goto no_pci; + } + + /* + * Enable flushing of the PCI-SDRAM queue upon a read + * of the SDRAM's Memory Configuration Register. + */ + *(unsigned long *)QFLUSH_REG_1 = 3; + + /* Configure PCI Host Controller. */ + preg->if_status = ~0; /* Clear cause register bits */ + preg->config_addr = 0; /* Clear config access */ + preg->oatran = MSP_PCI_OATRAN; /* PCI outbound addr translation */ + preg->if_mask = 0xF8BF87C0; /* Enable all PCI status interrupts */ + + /* configure so inb(), outb(), and family are functional */ + set_io_port_base(MSP_PCI_IOSPACE_BASE); + + /* Tell Linux the details of the MSP7120 PCI Host Controller */ + register_pci_controller(&msp_pci_controller); + + return; + +no_pci: + /* Disable PCI channel */ + printk(KERN_WARNING "PCI: no host PCI bus detected\n"); +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_pci.c b/arch/mips/pmc-sierra/msp71xx/msp_pci.c new file mode 100644 index 000000000000..f764fe7748d6 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_pci.c @@ -0,0 +1,50 @@ +/* + * The setup file for PCI related hardware on PMC-Sierra MSP processors. + * + * Copyright 2005-2006 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include + +extern void msp_pci_init(void); + +static int __init msp_pci_setup(void) +{ +#if 0 /* Linux 2.6 initialization code to be completed */ + if (getdeviceid() & DEV_ID_SINGLE_PC) { + /* If single card mode */ + slmRegs *sreg = (slmRegs *) SREG_BASE; + + sreg->single_pc_enable = SINGLE_PCCARD; + } +#endif + + msp_pci_init(); + + return 0; +} + +subsys_initcall(msp_pci_setup); diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h b/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h new file mode 100644 index 000000000000..415606903617 --- /dev/null +++ b/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2000-2006 PMC-Sierra INC. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + * 02139, USA. + * + * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS + * SOFTWARE. + */ + +#ifndef _MSP_PCI_H_ +#define _MSP_PCI_H_ + +#define MSP_HAS_PCI(ID) (((u32)(ID) <= 0x4236) && ((u32)(ID) >= 0x4220)) + +/* + * It is convenient to program the OATRAN register so that + * Athena virtual address space and PCI address space are + * the same. This is not a requirement, just a convenience. + * + * The only hard restrictions on the value of OATRAN is that + * OATRAN must not be programmed to allow translated memory + * addresses to fall within the lowest 512MB of + * PCI address space. This region is hardcoded + * for use as Athena PCI Host Controller target + * access memory space to the Athena's SDRAM. + * + * Note that OATRAN applies only to memory accesses, not + * to I/O accesses. + * + * To program OATRAN to make Athena virtual address space + * and PCI address space have the same values, OATRAN + * is to be programmed to 0xB8000000. The top seven + * bits of the value mimic the seven bits clipped off + * by the PCI Host controller. + * + * With OATRAN at the said value, when the CPU does + * an access to its virtual address at, say 0xB900_5000, + * the address appearing on the PCI bus will be + * 0xB900_5000. + * - Michael Penner + */ +#define MSP_PCI_OATRAN 0xB8000000UL + +#define MSP_PCI_SPACE_BASE (MSP_PCI_OATRAN + 0x1002000UL) +#define MSP_PCI_SPACE_SIZE (0x3000000UL - 0x2000) +#define MSP_PCI_SPACE_END \ + (MSP_PCI_SPACE_BASE + MSP_PCI_SPACE_SIZE - 1) +#define MSP_PCI_IOSPACE_BASE (MSP_PCI_OATRAN + 0x1001000UL) +#define MSP_PCI_IOSPACE_SIZE 0x1000 +#define MSP_PCI_IOSPACE_END \ + (MSP_PCI_IOSPACE_BASE + MSP_PCI_IOSPACE_SIZE - 1) + +/* IRQ for PCI status interrupts */ +#define PCI_STAT_IRQ 20 + +#define QFLUSH_REG_1 0xB7F40000 + +typedef volatile unsigned int pcireg; +typedef void * volatile ppcireg; + +struct pci_block_copy +{ + pcireg unused1; /* +0x00 */ + pcireg unused2; /* +0x04 */ + ppcireg unused3; /* +0x08 */ + ppcireg unused4; /* +0x0C */ + pcireg unused5; /* +0x10 */ + pcireg unused6; /* +0x14 */ + pcireg unused7; /* +0x18 */ + ppcireg unused8; /* +0x1C */ + ppcireg unused9; /* +0x20 */ + pcireg unusedA; /* +0x24 */ + ppcireg unusedB; /* +0x28 */ + ppcireg unusedC; /* +0x2C */ +}; + +enum +{ + config_device_vendor, /* 0 */ + config_status_command, /* 1 */ + config_class_revision, /* 2 */ + config_BIST_header_latency_cache, /* 3 */ + config_BAR0, /* 4 */ + config_BAR1, /* 5 */ + config_BAR2, /* 6 */ + config_not_used7, /* 7 */ + config_not_used8, /* 8 */ + config_not_used9, /* 9 */ + config_CIS, /* 10 */ + config_subsystem, /* 11 */ + config_not_used12, /* 12 */ + config_capabilities, /* 13 */ + config_not_used14, /* 14 */ + config_lat_grant_irq, /* 15 */ + config_message_control,/* 16 */ + config_message_addr, /* 17 */ + config_message_data, /* 18 */ + config_VPD_addr, /* 19 */ + config_VPD_data, /* 20 */ + config_maxregs /* 21 - number of registers */ +}; + +struct msp_pci_regs +{ + pcireg hop_unused_00; /* +0x00 */ + pcireg hop_unused_04; /* +0x04 */ + pcireg hop_unused_08; /* +0x08 */ + pcireg hop_unused_0C; /* +0x0C */ + pcireg hop_unused_10; /* +0x10 */ + pcireg hop_unused_14; /* +0x14 */ + pcireg hop_unused_18; /* +0x18 */ + pcireg hop_unused_1C; /* +0x1C */ + pcireg hop_unused_20; /* +0x20 */ + pcireg hop_unused_24; /* +0x24 */ + pcireg hop_unused_28; /* +0x28 */ + pcireg hop_unused_2C; /* +0x2C */ + pcireg hop_unused_30; /* +0x30 */ + pcireg hop_unused_34; /* +0x34 */ + pcireg if_control; /* +0x38 */ + pcireg oatran; /* +0x3C */ + pcireg reset_ctl; /* +0x40 */ + pcireg config_addr; /* +0x44 */ + pcireg hop_unused_48; /* +0x48 */ + pcireg msg_signaled_int_status; /* +0x4C */ + pcireg msg_signaled_int_mask; /* +0x50 */ + pcireg if_status; /* +0x54 */ + pcireg if_mask; /* +0x58 */ + pcireg hop_unused_5C; /* +0x5C */ + pcireg hop_unused_60; /* +0x60 */ + pcireg hop_unused_64; /* +0x64 */ + pcireg hop_unused_68; /* +0x68 */ + pcireg hop_unused_6C; /* +0x6C */ + pcireg hop_unused_70; /* +0x70 */ + + struct pci_block_copy pci_bc[2] __attribute__((aligned(64))); + + pcireg error_hdr1; /* +0xE0 */ + pcireg error_hdr2; /* +0xE4 */ + + pcireg config[config_maxregs] __attribute__((aligned(256))); + +}; + +#define BPCI_CFGADDR_BUSNUM_SHF 16 +#define BPCI_CFGADDR_FUNCTNUM_SHF 8 +#define BPCI_CFGADDR_REGNUM_SHF 2 +#define BPCI_CFGADDR_ENABLE (1<<31) + +#define BPCI_IFCONTROL_RTO (1<<20) /* Retry timeout */ +#define BPCI_IFCONTROL_HCE (1<<16) /* Host configuration enable */ +#define BPCI_IFCONTROL_CTO_SHF 12 /* Shift count for CTO bits */ +#define BPCI_IFCONTROL_SE (1<<5) /* Enable exceptions on errors */ +#define BPCI_IFCONTROL_BIST (1<<4) /* Use BIST in per. mode */ +#define BPCI_IFCONTROL_CAP (1<<3) /* Enable capabilities */ +#define BPCI_IFCONTROL_MMC_SHF 0 /* Shift count for MMC bits */ + +#define BPCI_IFSTATUS_MGT (1<<8) /* Master Grant timeout */ +#define BPCI_IFSTATUS_MTT (1<<9) /* Master TRDY timeout */ +#define BPCI_IFSTATUS_MRT (1<<10) /* Master retry timeout */ +#define BPCI_IFSTATUS_BC0F (1<<13) /* Block copy 0 fault */ +#define BPCI_IFSTATUS_BC1F (1<<14) /* Block copy 1 fault */ +#define BPCI_IFSTATUS_PCIU (1<<15) /* PCI unable to respond */ +#define BPCI_IFSTATUS_BSIZ (1<<16) /* PCI access with illegal size */ +#define BPCI_IFSTATUS_BADD (1<<17) /* PCI access with illegal addr */ +#define BPCI_IFSTATUS_RTO (1<<18) /* Retry time out */ +#define BPCI_IFSTATUS_SER (1<<19) /* System error */ +#define BPCI_IFSTATUS_PER (1<<20) /* Parity error */ +#define BPCI_IFSTATUS_LCA (1<<21) /* Local CPU abort */ +#define BPCI_IFSTATUS_MEM (1<<22) /* Memory prot. violation */ +#define BPCI_IFSTATUS_ARB (1<<23) /* Arbiter timed out */ +#define BPCI_IFSTATUS_STA (1<<27) /* Signaled target abort */ +#define BPCI_IFSTATUS_TA (1<<28) /* Target abort */ +#define BPCI_IFSTATUS_MA (1<<29) /* Master abort */ +#define BPCI_IFSTATUS_PEI (1<<30) /* Parity error as initiator */ +#define BPCI_IFSTATUS_PET (1<<31) /* Parity error as target */ + +#define BPCI_RESETCTL_PR (1<<0) /* True if reset asserted */ +#define BPCI_RESETCTL_RT (1<<4) /* Release time */ +#define BPCI_RESETCTL_CT (1<<8) /* Config time */ +#define BPCI_RESETCTL_PE (1<<12) /* PCI enabled */ +#define BPCI_RESETCTL_HM (1<<13) /* PCI host mode */ +#define BPCI_RESETCTL_RI (1<<14) /* PCI reset in */ + +extern struct msp_pci_regs msp_pci_regs + __attribute__((section(".register"))); +extern unsigned long msp_pci_config_space + __attribute__((section(".register"))); + +#endif /* !_MSP_PCI_H_ */ From 68bc00e31143ad8bfa435425e0a11e9b3998911d Mon Sep 17 00:00:00 2001 From: Marc St-Jean Date: Thu, 14 Jun 2007 15:57:11 -0600 Subject: [PATCH 509/551] [MIPS] PMC MSP71xx default configuration Patch to add default configuration for the PMC-Sierra MSP71xx devices. Signed-off-by: Marc St-Jean Signed-off-by: Ralf Baechle --- arch/mips/configs/msp71xx_defconfig | 1495 +++++++++++++++++++++++++++ 1 file changed, 1495 insertions(+) create mode 100644 arch/mips/configs/msp71xx_defconfig diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig new file mode 100644 index 000000000000..0d8a692d8826 --- /dev/null +++ b/arch/mips/configs/msp71xx_defconfig @@ -0,0 +1,1495 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.21-rc4 +# Thu Apr 26 18:11:29 2007 +# +CONFIG_MIPS=y + +# +# Machine selection +# +CONFIG_ZONE_DMA=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +CONFIG_PMC_MSP=y +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_PMC_MSP4200_EVAL is not set +# CONFIG_PMC_MSP4200_GW is not set +# CONFIG_PMC_MSP7120_EVAL is not set +CONFIG_PMC_MSP7120_GW=y +# CONFIG_PMC_MSP7120_FPGA is not set + +# +# Options for PMC-Sierra MSP chipsets +# +CONFIG_PMC_MSP_EMBEDDED_ROOTFS=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_BOOT_RAW=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_NO_EXCEPT_FILL=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_IRQ_MSP_CIC=y +CONFIG_MSP_USB=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_VPE_LOADER is not set +CONFIG_SYS_SUPPORTS_MULTITHREADING=y +# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +# CONFIG_PREEMPT_BKL is not set +# CONFIG_KEXEC is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="-pmc" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_SHMEM is not set +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +# CONFIG_PACKET is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NF_CONNTRACK_ENABLED is not set +CONFIG_NETFILTER_XTABLES=y +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# 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 +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PMC_MSP_EVM=y +CONFIG_MSP_FLASH_MAP_LIMIT_32M=y +CONFIG_MSP_FLASH_MAP_LIMIT=0x02000000 +CONFIG_MTD_PMC_MSP_RAMROOT=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MSPETH=y +CONFIG_MSPETH_NAPI=y +# CONFIG_MSPETH_SKB_RECYCLE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# 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 + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_PMCMSP_GPIO=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# 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_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PASEMI is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_I2C_PMCMSP=y + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +CONFIG_PMCTWILED=y +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR 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_SQUASHFS=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SQUASHFS_VMALLOC=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_KGDB is not set +CONFIG_SYS_SUPPORTS_KGDB=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y From 06cf5583fd9ac782cf34996cdabb48afdf478e37 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 20 Jun 2007 23:36:47 +0200 Subject: [PATCH 510/551] [MIPS] SNI RM updates - use RTC_CLASS instead of GEN_RTC - get rid of ds1216 in favour of a RTC_CLASS driver - use correct console device for older RM400 - use physical addresses for 82596 device - use 128 byte L1 cache line size (this is needed because most of the SNI caches are using 128 L2 cache lines) Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 +- arch/mips/sni/Makefile | 2 +- arch/mips/sni/a20r.c | 31 +++++++++++----- arch/mips/sni/ds1216.c | 81 ----------------------------------------- arch/mips/sni/pcimt.c | 26 +++++++++++-- arch/mips/sni/pcit.c | 26 +++++++++++-- arch/mips/sni/rm200.c | 32 +++++++++++----- arch/mips/sni/sniprom.c | 5 ++- include/asm-mips/sni.h | 3 -- 9 files changed, 95 insertions(+), 115 deletions(-) delete mode 100644 arch/mips/sni/ds1216.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2076d472ea99..24661d60bc8f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -918,8 +918,8 @@ config BOOT_ELF32 config MIPS_L1_CACHE_SHIFT int - default "4" if MACH_DECSTATION || SNI_RM - default "7" if SGI_IP27 + default "4" if MACH_DECSTATION + default "7" if SGI_IP27 || SNI_RM default "4" if PMC_MSP4200_EVAL default "5" diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index e5777b7e2bc9..471418e4f446 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile @@ -2,5 +2,5 @@ # Makefile for the SNI specific part of the kernel # -obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o +obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index 31ab80f1befa..6850a29defcd 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -15,7 +15,6 @@ #include #include -#include #define PORT(_base,_irq) \ { \ @@ -40,20 +39,34 @@ static struct platform_device a20r_serial8250_device = { }, }; +static struct resource a20r_ds1216_rsrc[] = { + { + .start = 0x1c081ffc, + .end = 0x1c081fff, + .flags = IORESOURCE_MEM + } +}; + +static struct platform_device a20r_ds1216_device = { + .name = "rtc-ds1216", + .num_resources = ARRAY_SIZE(a20r_ds1216_rsrc), + .resource = a20r_ds1216_rsrc +}; + static struct resource snirm_82596_rsrc[] = { { - .start = 0xb8000000, - .end = 0xb8000004, + .start = 0x18000000, + .end = 0x18000004, .flags = IORESOURCE_MEM }, { - .start = 0xb8010000, - .end = 0xb8010004, + .start = 0x18010000, + .end = 0x18010004, .flags = IORESOURCE_MEM }, { - .start = 0xbff00000, - .end = 0xbff00020, + .start = 0x1ff00000, + .end = 0x1ff00020, .flags = IORESOURCE_MEM }, { @@ -205,8 +218,7 @@ void __init sni_a20r_irq_init(void) void sni_a20r_init(void) { - ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE; - rtc_mips_get_time = ds1216_get_cmos_time; + /* FIXME, remove if not needed */ } static int __init snirm_a20r_setup_devinit(void) @@ -218,6 +230,7 @@ static int __init snirm_a20r_setup_devinit(void) platform_device_register(&snirm_53c710_pdev); platform_device_register(&sc26xx_pdev); platform_device_register(&a20r_serial8250_device); + platform_device_register(&a20r_ds1216_device); break; } diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c deleted file mode 100644 index 1d92732c14f1..000000000000 --- a/arch/mips/sni/ds1216.c +++ /dev/null @@ -1,81 +0,0 @@ - -#include -#include - -#include - -volatile unsigned char *ds1216_base; - -/* - * Read the 64 bit we'd like to have - It a series - * of 64 bits showing up in the LSB of the base register. - * - */ -static unsigned char *ds1216_read(void) -{ - static unsigned char rdbuf[8]; - unsigned char c; - int i, j; - - for (i = 0; i < 8; i++) { - c = 0x0; - for (j = 0; j < 8; j++) { - c |= (*ds1216_base & 0x1) << j; - } - rdbuf[i] = c; - } - - return rdbuf; -} - -static void ds1216_switch_ds_to_clock(void) -{ - unsigned char magic[] = { - 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c - }; - int i,j,c; - - /* Reset magic pointer */ - c = *ds1216_base; - - /* Write 64 bit magic to DS1216 */ - for (i = 0; i < 8; i++) { - c = magic[i]; - for (j = 0; j < 8; j++) { - *ds1216_base = c; - c = c >> 1; - } - } -} - -unsigned long ds1216_get_cmos_time(void) -{ - unsigned char *rdbuf; - unsigned int year, month, date, hour, min, sec; - - ds1216_switch_ds_to_clock(); - rdbuf = ds1216_read(); - - sec = BCD2BIN(DS1216_SEC(rdbuf)); - min = BCD2BIN(DS1216_MIN(rdbuf)); - hour = BCD2BIN(DS1216_HOUR(rdbuf)); - date = BCD2BIN(DS1216_DATE(rdbuf)); - month = BCD2BIN(DS1216_MONTH(rdbuf)); - year = BCD2BIN(DS1216_YEAR(rdbuf)); - - if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf)) - hour+=12; - - if (year < 70) - year += 2000; - else - year += 1900; - - return mktime(year, month, date, hour, min, sec); -} - -int ds1216_set_rtc_mmss(unsigned long nowtime) -{ - printk("ds1216_set_rtc_mmss called but not implemented\n"); - return -1; -} diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 97b234361b4d..44b1ae62aa4a 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -90,6 +89,26 @@ static struct platform_device pcimt_serial8250_device = { }, }; +static struct resource pcimt_cmos_rsrc[] = { + { + .start = 0x70, + .end = 0x71, + .flags = IORESOURCE_IO + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device pcimt_cmos_device = { + .name = "rtc_cmos", + .num_resources = ARRAY_SIZE(pcimt_cmos_rsrc), + .resource = pcimt_cmos_rsrc +}; + + static struct resource sni_io_resource = { .start = 0x00000000UL, .end = 0x03bfffffUL, @@ -290,12 +309,10 @@ void __init sni_pcimt_irq_init(void) change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); } -void sni_pcimt_init(void) +void __init sni_pcimt_init(void) { sni_pcimt_detect(); sni_pcimt_sc_init(); - rtc_mips_get_time = mc146818_get_cmos_time; - rtc_mips_set_time = mc146818_set_rtc_mmss; board_time_init = sni_cpu_time_init; ioport_resource.end = sni_io_resource.end; #ifdef CONFIG_PCI @@ -312,6 +329,7 @@ static int __init snirm_pcimt_setup_devinit(void) case SNI_BRD_PCI_DESKTOP: case SNI_BRD_PCI_MTOWER_CPLUS: platform_device_register(&pcimt_serial8250_device); + platform_device_register(&pcimt_cmos_device); break; } diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index 00d151f4d121..2480c478dcbd 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -58,6 +57,25 @@ static struct platform_device pcit_cplus_serial8250_device = { }, }; +static struct resource pcit_cmos_rsrc[] = { + { + .start = 0x70, + .end = 0x71, + .flags = IORESOURCE_IO + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device pcit_cmos_device = { + .name = "rtc_cmos", + .num_resources = ARRAY_SIZE(pcit_cmos_rsrc), + .resource = pcit_cmos_rsrc +}; + static struct resource sni_io_resource = { .start = 0x00000000UL, .end = 0x03bfffffUL, @@ -243,10 +261,8 @@ void __init sni_pcit_cplus_irq_init(void) setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq); } -void sni_pcit_init(void) +void __init sni_pcit_init(void) { - rtc_mips_get_time = mc146818_get_cmos_time; - rtc_mips_set_time = mc146818_set_rtc_mmss; board_time_init = sni_cpu_time_init; ioport_resource.end = sni_io_resource.end; #ifdef CONFIG_PCI @@ -261,10 +277,12 @@ static int __init snirm_pcit_setup_devinit(void) switch (sni_brd_type) { case SNI_BRD_PCI_TOWER: platform_device_register(&pcit_serial8250_device); + platform_device_register(&pcit_cmos_device); break; case SNI_BRD_PCI_TOWER_CPLUS: platform_device_register(&pcit_cplus_serial8250_device); + platform_device_register(&pcit_cmos_device); break; } return 0; diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index b82ff129f5ea..4bfda020fdc7 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -15,7 +15,6 @@ #include #include -#include #include #define PORT(_base,_irq) \ @@ -41,20 +40,34 @@ static struct platform_device rm200_serial8250_device = { }, }; +static struct resource rm200_ds1216_rsrc[] = { + { + .start = 0x1cd41ffc, + .end = 0x1cd41fff, + .flags = IORESOURCE_MEM + } +}; + +static struct platform_device rm200_ds1216_device = { + .name = "rtc-ds1216", + .num_resources = ARRAY_SIZE(rm200_ds1216_rsrc), + .resource = rm200_ds1216_rsrc +}; + static struct resource snirm_82596_rm200_rsrc[] = { { - .start = 0xb8000000, - .end = 0xb80fffff, + .start = 0x18000000, + .end = 0x180fffff, .flags = IORESOURCE_MEM }, { - .start = 0xbb000000, - .end = 0xbb000004, + .start = 0x1b000000, + .end = 0x1b000004, .flags = IORESOURCE_MEM }, { - .start = 0xbff00000, - .end = 0xbff00020, + .start = 0x1ff00000, + .end = 0x1ff00020, .flags = IORESOURCE_MEM }, { @@ -96,6 +109,7 @@ static int __init snirm_setup_devinit(void) { if (sni_brd_type == SNI_BRD_RM200) { platform_device_register(&rm200_serial8250_device); + platform_device_register(&rm200_ds1216_device); platform_device_register(&snirm_82596_rm200_pdev); platform_device_register(&snirm_53c710_rm200_pdev); } @@ -176,11 +190,9 @@ void __init sni_rm200_irq_init(void) setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq); } -void sni_rm200_init(void) +void __init sni_rm200_init(void) { set_io_port_base(SNI_PORT_BASE + 0x02000000); ioport_resource.end += 0x02000000; - ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE; - rtc_mips_get_time = ds1216_get_cmos_time; board_time_init = sni_cpu_time_init; } diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c index 643366eb854a..00a03a6e8f58 100644 --- a/arch/mips/sni/sniprom.c +++ b/arch/mips/sni/sniprom.c @@ -146,7 +146,10 @@ static void __init sni_console_setup(void) } if (baud) strcpy(options, baud); - add_preferred_console("ttyS", port, baud ? options : NULL); + if (strncmp (cdev, "tty552", 6) == 0) + add_preferred_console("ttyS", port, baud ? options : NULL); + else + add_preferred_console("ttySC", port, baud ? options : NULL); } } diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h index f257509b914f..ddaf36a1e389 100644 --- a/include/asm-mips/sni.h +++ b/include/asm-mips/sni.h @@ -146,9 +146,6 @@ extern unsigned int sni_brd_type; #define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE #define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5) -#define SNI_DS1216_A20R_BASE 0xbc081ffc -#define SNI_DS1216_RM200_BASE 0xbcd41ffc - #define SNI_PCIT_INT_REG 0xbfff000c #define SNI_PCIT_INT_START 24 From 3896b05418b9b8548a678231db754206b3ebe56e Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 22 Jun 2007 23:21:55 +0900 Subject: [PATCH 511/551] [MIPS] rbtx4938: Add generic GPIO support GPIO 0..15 are for TX4938 PIO pins, GPIO 16..18 are for FPGA-driven chipselect signals for SPI devices. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/configs/rbhma4500_defconfig | 1 + arch/mips/tx4938/toshiba_rbtx4938/setup.c | 104 ++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 24661d60bc8f..823a6285c55a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -660,6 +660,7 @@ config TOSHIBA_RBTX4938 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_KGDB select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_GPIO help This Toshiba board is based on the TX4938 processor. Say Y here to support this machine type diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index b0abd16fae29..6e10c15cecf7 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -80,6 +80,7 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y CONFIG_GENERIC_ISA_DMA=y CONFIG_I8259=y +CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index f5d1ce739fcc..12b9f4f9c3a2 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifdef CONFIG_SERIAL_TXX9 #include @@ -1057,3 +1058,106 @@ static int __init rbtx4938_ne_init(void) return IS_ERR(dev) ? PTR_ERR(dev) : 0; } device_initcall(rbtx4938_ne_init); + +/* GPIO support */ + +static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); + +static void rbtx4938_spi_gpio_set(unsigned gpio, int value) +{ + u8 val; + unsigned long flags; + gpio -= 16; + spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); + val = *rbtx4938_spics_ptr; + if (value) + val |= 1 << gpio; + else + val &= ~(1 << gpio); + *rbtx4938_spics_ptr = val; + mmiowb(); + spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); +} + +static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value) +{ + rbtx4938_spi_gpio_set(gpio, value); + return 0; +} + +static DEFINE_SPINLOCK(tx4938_gpio_lock); + +static int tx4938_gpio_get(unsigned gpio) +{ + return tx4938_pioptr->din & (1 << gpio); +} + +static void tx4938_gpio_set_raw(unsigned gpio, int value) +{ + u32 val; + val = tx4938_pioptr->dout; + if (value) + val |= 1 << gpio; + else + val &= ~(1 << gpio); + tx4938_pioptr->dout = val; +} + +static void tx4938_gpio_set(unsigned gpio, int value) +{ + unsigned long flags; + spin_lock_irqsave(&tx4938_gpio_lock, flags); + tx4938_gpio_set_raw(gpio, value); + mmiowb(); + spin_unlock_irqrestore(&tx4938_gpio_lock, flags); +} + +static int tx4938_gpio_dir_in(unsigned gpio) +{ + spin_lock_irq(&tx4938_gpio_lock); + tx4938_pioptr->dir &= ~(1 << gpio); + mmiowb(); + spin_unlock_irq(&tx4938_gpio_lock); + return 0; +} + +static int tx4938_gpio_dir_out(unsigned int gpio, int value) +{ + spin_lock_irq(&tx4938_gpio_lock); + tx4938_gpio_set_raw(gpio, value); + tx4938_pioptr->dir |= 1 << gpio; + mmiowb(); + spin_unlock_irq(&tx4938_gpio_lock); + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + if (gpio < 16) + return tx4938_gpio_dir_in(gpio); + return -EINVAL; +} + +int gpio_direction_output(unsigned gpio, int value) +{ + if (gpio < 16) + return tx4938_gpio_dir_out(gpio, value); + if (gpio < 16 + 3) + return rbtx4938_spi_gpio_dir_out(gpio, value); + return -EINVAL; +} + +int gpio_get_value(unsigned gpio) +{ + if (gpio < 16) + return tx4938_gpio_get(gpio); + return 0; +} + +void gpio_set_value(unsigned gpio, int value) +{ + if (gpio < 16) + tx4938_gpio_set(gpio, value); + else + rbtx4938_spi_gpio_set(gpio, value); +} From f74cf6ff99a49741b0f243996b621777b2d610d4 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 22 Jun 2007 23:22:06 +0900 Subject: [PATCH 512/551] [MIPS] rbtx4938: Convert SPI codes to use generic SPI drivers Use rtc-rs5c348 and at25 spi protocol driver and spi_txx9 spi controller driver instead of platform dependent codes. This patch also removes dependencies to old RTC interfaces such as rtc_mips_get_time, etc. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/configs/rbhma4500_defconfig | 54 +++- arch/mips/tx4938/common/Makefile | 2 +- arch/mips/tx4938/common/rtc_rx5c348.c | 192 ------------ arch/mips/tx4938/toshiba_rbtx4938/Makefile | 2 +- arch/mips/tx4938/toshiba_rbtx4938/irq.c | 6 - arch/mips/tx4938/toshiba_rbtx4938/setup.c | 171 ++++++----- .../mips/tx4938/toshiba_rbtx4938/spi_eeprom.c | 275 +++++------------- arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c | 164 ----------- include/asm-mips/tx4938/rbtx4938.h | 6 - include/asm-mips/tx4938/spi.h | 56 +--- 10 files changed, 226 insertions(+), 702 deletions(-) delete mode 100644 arch/mips/tx4938/common/rtc_rx5c348.c delete mode 100644 arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 6e10c15cecf7..6b9bebacb541 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -966,8 +966,20 @@ CONFIG_LEGACY_PTY_COUNT=256 # # SPI support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +CONFIG_SPI_TXX9=y + +# +# SPI Protocol Masters +# +CONFIG_SPI_AT25=y +# CONFIG_SPI_SPIDEV is not set # # Dallas's 1-wire bus @@ -1207,7 +1219,43 @@ CONFIG_USB_MON=y # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_RS5C348=y +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# # # DMA Engine support diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile index 2033ae77f632..83cda518f204 100644 --- a/arch/mips/tx4938/common/Makefile +++ b/arch/mips/tx4938/common/Makefile @@ -6,6 +6,6 @@ # unless it's something special (ie not a .c file). # -obj-y += prom.o setup.o irq.o rtc_rx5c348.o +obj-y += prom.o setup.o irq.o obj-$(CONFIG_KGDB) += dbgio.o diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c deleted file mode 100644 index 07f782fc0725..000000000000 --- a/arch/mips/tx4938/common/rtc_rx5c348.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * RTC routines for RICOH Rx5C348 SPI chip. - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define EPOCH 2000 - -/* registers */ -#define Rx5C348_REG_SECOND 0 -#define Rx5C348_REG_MINUTE 1 -#define Rx5C348_REG_HOUR 2 -#define Rx5C348_REG_WEEK 3 -#define Rx5C348_REG_DAY 4 -#define Rx5C348_REG_MONTH 5 -#define Rx5C348_REG_YEAR 6 -#define Rx5C348_REG_ADJUST 7 -#define Rx5C348_REG_ALARM_W_MIN 8 -#define Rx5C348_REG_ALARM_W_HOUR 9 -#define Rx5C348_REG_ALARM_W_WEEK 10 -#define Rx5C348_REG_ALARM_D_MIN 11 -#define Rx5C348_REG_ALARM_D_HOUR 12 -#define Rx5C348_REG_CTL1 14 -#define Rx5C348_REG_CTL2 15 - -/* register bits */ -#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */ -#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */ -#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */ -#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */ - -/* commands */ -#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */ -#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */ -#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */ -#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */ - -static struct spi_dev_desc srtc_dev_desc = { - .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */ - .tcss = 31, - .tcsh = 1, - .tcsr = 62, - /* 31us for Tcss (62us for Tcsr) is required for carry operation) */ - .byteorder = 1, /* MSB-First */ - .polarity = 0, /* High-Active */ - .phase = 1, /* Shift-Then-Sample */ - -}; -static int srtc_chipid; -static int srtc_24h; - -static inline int -spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count) -{ - unsigned char *inbufs[1], *outbufs[1]; - unsigned int incounts[2], outcounts[2]; - inbufs[0] = inbuf; - incounts[0] = count; - incounts[1] = 0; - outbufs[0] = outbuf; - outcounts[0] = count; - outcounts[1] = 0; - return txx9_spi_io(srtc_chipid, &srtc_dev_desc, - inbufs, incounts, outbufs, outcounts, 0); -} - -/* RTC-dependent code for time.c */ - -static int -rtc_rx5c348_set_time(unsigned long t) -{ - unsigned char inbuf[8]; - struct rtc_time tm; - u8 year, month, day, hour, minute, second, century; - - /* convert */ - to_tm(t, &tm); - - year = tm.tm_year % 100; - month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */ - day = tm.tm_mday; - hour = tm.tm_hour; - minute = tm.tm_min; - second = tm.tm_sec; - century = tm.tm_year / 100; - - inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND); - BIN_TO_BCD(second); - inbuf[1] = second; - BIN_TO_BCD(minute); - inbuf[2] = minute; - - if (srtc_24h) { - BIN_TO_BCD(hour); - inbuf[3] = hour; - } else { - /* hour 0 is AM12, noon is PM12 */ - inbuf[3] = 0; - if (hour >= 12) - inbuf[3] = Rx5C348_BIT_PM; - hour = (hour + 11) % 12 + 1; - BIN_TO_BCD(hour); - inbuf[3] |= hour; - } - inbuf[4] = 0; /* ignore week */ - BIN_TO_BCD(day); - inbuf[5] = day; - BIN_TO_BCD(month); - inbuf[6] = month; - if (century >= 20) - inbuf[6] |= Rx5C348_BIT_Y2K; - BIN_TO_BCD(year); - inbuf[7] = year; - /* write in one transfer to avoid data inconsistency */ - return spi_rtc_io(inbuf, NULL, 8); -} - -static unsigned long -rtc_rx5c348_get_time(void) -{ - unsigned char inbuf[8], outbuf[8]; - unsigned int year, month, day, hour, minute, second; - - inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND); - memset(inbuf + 1, 0, 7); - /* read in one transfer to avoid data inconsistency */ - if (spi_rtc_io(inbuf, outbuf, 8)) - return 0; - second = outbuf[1]; - BCD_TO_BIN(second); - minute = outbuf[2]; - BCD_TO_BIN(minute); - if (srtc_24h) { - hour = outbuf[3]; - BCD_TO_BIN(hour); - } else { - hour = outbuf[3] & ~Rx5C348_BIT_PM; - BCD_TO_BIN(hour); - hour %= 12; - if (outbuf[3] & Rx5C348_BIT_PM) - hour += 12; - } - day = outbuf[5]; - BCD_TO_BIN(day); - month = outbuf[6] & ~Rx5C348_BIT_Y2K; - BCD_TO_BIN(month); - year = outbuf[7]; - BCD_TO_BIN(year); - year += EPOCH; - - return mktime(year, month, day, hour, minute, second); -} - -void __init -rtc_rx5c348_init(int chipid) -{ - unsigned char inbuf[2], outbuf[2]; - srtc_chipid = chipid; - /* turn on RTC if it is not on */ - inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2); - inbuf[1] = 0; - spi_rtc_io(inbuf, outbuf, 2); - if (outbuf[1] & Rx5C348_BIT_XSTP) { - inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2); - inbuf[1] = 0; - spi_rtc_io(inbuf, NULL, 2); - } - - inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1); - inbuf[1] = 0; - spi_rtc_io(inbuf, outbuf, 2); - if (outbuf[1] & Rx5C348_BIT_24H) - srtc_24h = 1; - - /* set the function pointers */ - rtc_mips_get_time = rtc_rx5c348_get_time; - rtc_mips_set_time = rtc_rx5c348_set_time; -} diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile index 226941279d75..10c94e62bf5b 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile +++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile @@ -6,4 +6,4 @@ # unless it's something special (ie not a .c file). # -obj-y += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o +obj-y += prom.o setup.o irq.o spi_eeprom.o diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 2e96dbb248b1..91aea7aff515 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -165,8 +165,6 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); } -extern void __init txx9_spi_irqinit(int irc_irq); - void __init arch_init_irq(void) { extern void tx4938_irq_init(void); @@ -185,9 +183,5 @@ void __init arch_init_irq(void) /* Onboard 10M Ether: High Active */ TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040); - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) { - txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI); - } - wbflush(); } diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 12b9f4f9c3a2..361d89a81175 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -14,13 +14,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -29,13 +29,15 @@ #include #include #include -#include #include #ifdef CONFIG_SERIAL_TXX9 #include #include #include #endif +#include +#include +#include extern void rbtx4938_time_init(void) __init; extern char * __init prom_getcmdline(void); @@ -575,44 +577,33 @@ arch_initcall(tx4938_pcibios_init); #define SEEPROM3_CS 1 /* IOC */ #define SRTC_CS 2 /* IOC */ -static int rbtx4938_spi_cs_func(int chipid, int on) +#ifdef CONFIG_PCI +static unsigned char rbtx4938_ethaddr[17]; +static int __init rbtx4938_ethaddr_init(void) { - unsigned char bit; - switch (chipid) { - case RBTX4938_SEEPROM1_CHIPID: - if (on) - tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS); - else - tx4938_pioptr->dout |= (1 << SEEPROM1_CS); - return 0; - break; - case RBTX4938_SEEPROM2_CHIPID: - bit = (1 << SEEPROM2_CS); - break; - case RBTX4938_SEEPROM3_CHIPID: - bit = (1 << SEEPROM3_CS); - break; - case RBTX4938_SRTC_CHIPID: - bit = (1 << SRTC_CS); - break; - default: - return -ENODEV; + unsigned char sum; + int i; + + /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ + if (spi_eeprom_read(SEEPROM1_CS, 0, + rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr))) + printk(KERN_ERR "seeprom: read error.\n"); + else { + unsigned char *dat = rbtx4938_ethaddr; + if (strcmp(dat, "MAC") != 0) + printk(KERN_WARNING "seeprom: bad signature.\n"); + for (i = 0, sum = 0; i < sizeof(dat); i++) + sum += dat[i]; + if (sum) + printk(KERN_WARNING "seeprom: bad checksum.\n"); } - /* bit1,2,4 are low active, bit3 is high active */ - *rbtx4938_spics_ptr = - (*rbtx4938_spics_ptr & ~bit) | - ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit); return 0; } - -#ifdef CONFIG_PCI -extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); +device_initcall(rbtx4938_ethaddr_init); int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) { struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; - static unsigned char dat[17]; - static int read_dat = 0; int ch = 0; if (channel != &tx4938_pci_controller[1]) @@ -628,29 +619,11 @@ int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) default: return -ENODEV; } - if (!read_dat) { - unsigned char sum; - int i; - read_dat = 1; - /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ - if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID, - 0, dat, sizeof(dat))) { - printk(KERN_ERR "seeprom: read error.\n"); - } else { - if (strcmp(dat, "MAC") != 0) - printk(KERN_WARNING "seeprom: bad signature.\n"); - for (i = 0, sum = 0; i < sizeof(dat); i++) - sum += dat[i]; - if (sum) - printk(KERN_WARNING "seeprom: bad checksum.\n"); - } - } - memcpy(addr, &dat[4 + 6 * ch], 6); + memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6); return 0; } #endif /* CONFIG_PCI */ -extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)); static void __init rbtx4938_spi_setup(void) { /* set SPI_SEL */ @@ -658,7 +631,6 @@ static void __init rbtx4938_spi_setup(void) /* chip selects for SPI devices */ tx4938_pioptr->dout |= (1 << SEEPROM1_CS); tx4938_pioptr->dir |= (1 << SEEPROM1_CS); - txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func); } static struct resource rbtx4938_fpga_resource; @@ -897,10 +869,8 @@ void tx4938_report_pcic_status(void) /* We use onchip r4k counter or TMR timer as our system wide timer * interrupt running at 100HZ. */ -extern void __init rtc_rx5c348_init(int chipid); void __init rbtx4938_time_init(void) { - rtc_rx5c348_init(RBTX4938_SRTC_CHIPID); mips_hpt_frequency = txx9_cpu_clock / 2; } @@ -1017,29 +987,6 @@ void __init toshiba_rbtx4938_setup(void) *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); } -#ifdef CONFIG_PROC_FS -extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid); -static int __init tx4938_spi_proc_setup(void) -{ - struct proc_dir_entry *tx4938_spi_eeprom_dir; - - tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0); - - if (!tx4938_spi_eeprom_dir) - return -ENOMEM; - - /* don't allow user access to RBTX4938_SEEPROM1_CHIPID - * as it contains eth0 and eth1 MAC addresses - */ - spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID); - spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID); - - return 0; -} - -__initcall(tx4938_spi_proc_setup); -#endif - static int __init rbtx4938_ne_init(void) { struct resource res[] = { @@ -1161,3 +1108,73 @@ void gpio_set_value(unsigned gpio, int value) else rbtx4938_spi_gpio_set(gpio, value); } + +/* SPI support */ + +static void __init txx9_spi_init(unsigned long base, int irq) +{ + struct resource res[] = { + { + .start = base, + .end = base + 0x20 - 1, + .flags = IORESOURCE_MEM, + .parent = &tx4938_reg_resource, + }, { + .start = irq, + .flags = IORESOURCE_IRQ, + }, + }; + platform_device_register_simple("txx9spi", 0, + res, ARRAY_SIZE(res)); +} + +static int __init rbtx4938_spi_init(void) +{ + struct spi_board_info srtc_info = { + .modalias = "rs5c348", + .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ + .bus_num = 0, + .chip_select = 16 + SRTC_CS, + /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ + .mode = SPI_MODE_1 | SPI_CS_HIGH, + }; + spi_register_board_info(&srtc_info, 1); + spi_eeprom_register(SEEPROM1_CS); + spi_eeprom_register(16 + SEEPROM2_CS); + spi_eeprom_register(16 + SEEPROM3_CS); + txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); + return 0; +} +arch_initcall(rbtx4938_spi_init); + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "spi-baseclk")) + return (struct clk *)(txx9_gbus_clock / 2 / 4); + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c index 89596e62f909..4d6b4ade5e8c 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c @@ -10,209 +10,90 @@ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ #include -#include -#include -#include +#include +#include +#include #include -#include -/* ATMEL 250x0 instructions */ -#define ATMEL_WREN 0x06 -#define ATMEL_WRDI 0x04 -#define ATMEL_RDSR 0x05 -#define ATMEL_WRSR 0x01 -#define ATMEL_READ 0x03 -#define ATMEL_WRITE 0x02 +#define AT250X0_PAGE_SIZE 8 -#define ATMEL_SR_BSY 0x01 -#define ATMEL_SR_WEN 0x02 -#define ATMEL_SR_BP0 0x04 -#define ATMEL_SR_BP1 0x08 +/* register board information for at25 driver */ +int __init spi_eeprom_register(int chipid) +{ + static struct spi_eeprom eeprom = { + .name = "at250x0", + .byte_len = 128, + .page_size = AT250X0_PAGE_SIZE, + .flags = EE_ADDR1, + }; + struct spi_board_info info = { + .modalias = "at25", + .max_speed_hz = 1500000, /* 1.5Mbps */ + .bus_num = 0, + .chip_select = chipid, + .platform_data = &eeprom, + /* Mode 0: High-Active, Sample-Then-Shift */ + }; -DEFINE_SPINLOCK(spi_eeprom_lock); + return spi_register_board_info(&info, 1); +} -static struct spi_dev_desc seeprom_dev_desc = { - .baud = 1500000, /* 1.5Mbps */ - .tcss = 1, - .tcsh = 1, - .tcsr = 1, - .byteorder = 1, /* MSB-First */ - .polarity = 0, /* High-Active */ - .phase = 0, /* Sample-Then-Shift */ +/* simple temporary spi driver to provide early access to seeprom. */ +static struct read_param { + int chipid; + int address; + unsigned char *buf; + int len; +} *read_param; + +static int __init early_seeprom_probe(struct spi_device *spi) +{ + int stat = 0; + u8 cmd[2]; + int len = read_param->len; + char *buf = read_param->buf; + int address = read_param->address; + + dev_info(&spi->dev, "spiclk %u KHz.\n", + (spi->max_speed_hz + 500) / 1000); + if (read_param->chipid != spi->chip_select) + return -ENODEV; + while (len > 0) { + /* spi_write_then_read can only work with small chunk */ + int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; + cmd[0] = 0x03; /* AT25_READ */ + cmd[1] = address; + stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); + buf += c; + len -= c; + address += c; + } + return stat; +} + +static struct spi_driver early_seeprom_driver __initdata = { + .driver = { + .name = "at25", + .owner = THIS_MODULE, + }, + .probe = early_seeprom_probe, }; -static inline int -spi_eeprom_io(int chipid, - unsigned char **inbufs, unsigned int *incounts, - unsigned char **outbufs, unsigned int *outcounts) + +int __init spi_eeprom_read(int chipid, int address, + unsigned char *buf, int len) { - return txx9_spi_io(chipid, &seeprom_dev_desc, - inbufs, incounts, outbufs, outcounts, 0); + int ret; + struct read_param param = { + .chipid = chipid, + .address = address, + .buf = buf, + .len = len + }; + + read_param = ¶m; + ret = spi_register_driver(&early_seeprom_driver); + if (!ret) + spi_unregister_driver(&early_seeprom_driver); + return ret; } - -int spi_eeprom_write_enable(int chipid, int enable) -{ - unsigned char inbuf[1]; - unsigned char *inbufs[1]; - unsigned int incounts[2]; - unsigned long flags; - int stat; - inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI; - inbufs[0] = inbuf; - incounts[0] = sizeof(inbuf); - incounts[1] = 0; - spin_lock_irqsave(&spi_eeprom_lock, flags); - stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL); - spin_unlock_irqrestore(&spi_eeprom_lock, flags); - return stat; -} - -static int spi_eeprom_read_status_nolock(int chipid) -{ - unsigned char inbuf[2], outbuf[2]; - unsigned char *inbufs[1], *outbufs[1]; - unsigned int incounts[2], outcounts[2]; - int stat; - inbuf[0] = ATMEL_RDSR; - inbuf[1] = 0; - inbufs[0] = inbuf; - incounts[0] = sizeof(inbuf); - incounts[1] = 0; - outbufs[0] = outbuf; - outcounts[0] = sizeof(outbuf); - outcounts[1] = 0; - stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts); - if (stat < 0) - return stat; - return outbuf[1]; -} - -int spi_eeprom_read_status(int chipid) -{ - unsigned long flags; - int stat; - spin_lock_irqsave(&spi_eeprom_lock, flags); - stat = spi_eeprom_read_status_nolock(chipid); - spin_unlock_irqrestore(&spi_eeprom_lock, flags); - return stat; -} - -int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len) -{ - unsigned char inbuf[2]; - unsigned char *inbufs[2], *outbufs[2]; - unsigned int incounts[2], outcounts[3]; - unsigned long flags; - int stat; - inbuf[0] = ATMEL_READ; - inbuf[1] = address; - inbufs[0] = inbuf; - inbufs[1] = NULL; - incounts[0] = sizeof(inbuf); - incounts[1] = 0; - outbufs[0] = NULL; - outbufs[1] = buf; - outcounts[0] = 2; - outcounts[1] = len; - outcounts[2] = 0; - spin_lock_irqsave(&spi_eeprom_lock, flags); - stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts); - spin_unlock_irqrestore(&spi_eeprom_lock, flags); - return stat; -} - -int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len) -{ - unsigned char inbuf[2]; - unsigned char *inbufs[2]; - unsigned int incounts[3]; - unsigned long flags; - int i, stat; - - if (address / 8 != (address + len - 1) / 8) - return -EINVAL; - stat = spi_eeprom_write_enable(chipid, 1); - if (stat < 0) - return stat; - stat = spi_eeprom_read_status(chipid); - if (stat < 0) - return stat; - if (!(stat & ATMEL_SR_WEN)) - return -EPERM; - - inbuf[0] = ATMEL_WRITE; - inbuf[1] = address; - inbufs[0] = inbuf; - inbufs[1] = buf; - incounts[0] = sizeof(inbuf); - incounts[1] = len; - incounts[2] = 0; - spin_lock_irqsave(&spi_eeprom_lock, flags); - stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL); - if (stat < 0) - goto unlock_return; - - /* write start. max 10ms */ - for (i = 10; i > 0; i--) { - int stat = spi_eeprom_read_status_nolock(chipid); - if (stat < 0) - goto unlock_return; - if (!(stat & ATMEL_SR_BSY)) - break; - mdelay(1); - } - spin_unlock_irqrestore(&spi_eeprom_lock, flags); - if (i == 0) - return -EIO; - return len; - unlock_return: - spin_unlock_irqrestore(&spi_eeprom_lock, flags); - return stat; -} - -#ifdef CONFIG_PROC_FS -#define MAX_SIZE 0x80 /* for ATMEL 25010 */ -static int spi_eeprom_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - unsigned int size = MAX_SIZE; - if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0) - size = 0; - return size; -} - -static int spi_eeprom_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - unsigned int size = MAX_SIZE; - int i; - if (file->f_pos >= size) - return -EIO; - if (file->f_pos + count > size) - count = size - file->f_pos; - for (i = 0; i < count; i += 8) { - int len = count - i < 8 ? count - i : 8; - if (spi_eeprom_write((int)data, file->f_pos, - (unsigned char *)buffer, len) < 0) { - count = -EIO; - break; - } - buffer += len; - file->f_pos += len; - } - return count; -} - -__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) -{ - struct proc_dir_entry *entry; - char name[128]; - sprintf(name, "seeprom-%d", chipid); - entry = create_proc_entry(name, 0600, dir); - if (entry) { - entry->read_proc = spi_eeprom_read_proc; - entry->write_proc = spi_eeprom_write_proc; - entry->data = (void *)chipid; - } -} -#endif /* CONFIG_PROC_FS */ diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c deleted file mode 100644 index 08b20cdfd7b3..000000000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int (*txx9_spi_cs_func)(int chipid, int on); -static DEFINE_SPINLOCK(txx9_spi_lock); - -extern unsigned int txx9_gbus_clock; - -#define SPI_FIFO_SIZE 4 - -void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) -{ - txx9_spi_cs_func = cs_func; - /* enter config mode */ - tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR; -} - -static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait); - -static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id) -{ - /* disable rx intr */ - tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE; - wake_up(&txx9_spi_wait); - - return IRQ_HANDLED; -} - -static struct irqaction txx9_spi_action = { - .handler = txx9_spi_interrupt, - .name = "spi", -}; - -void __init txx9_spi_irqinit(int irc_irq) -{ - setup_irq(irc_irq, &txx9_spi_action); -} - -int txx9_spi_io(int chipid, struct spi_dev_desc *desc, - unsigned char **inbufs, unsigned int *incounts, - unsigned char **outbufs, unsigned int *outcounts, - int cansleep) -{ - unsigned int incount, outcount; - unsigned char *inp, *outp; - int ret; - unsigned long flags; - - spin_lock_irqsave(&txx9_spi_lock, flags); - if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) { - spin_unlock_irqrestore(&txx9_spi_lock, flags); - return -EBUSY; - } - /* enter config mode */ - tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR; - tx4938_spiptr->cr0 = - (desc->byteorder ? TXx9_SPCR0_SBOS : 0) | - (desc->polarity ? TXx9_SPCR0_SPOL : 0) | - (desc->phase ? TXx9_SPCR0_SPHA : 0) | - 0x08; - tx4938_spiptr->cr1 = - (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) | - 0x08 /* 8 bit only */; - /* enter active mode */ - tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE; - spin_unlock_irqrestore(&txx9_spi_lock, flags); - - /* CS ON */ - if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) { - spin_unlock_irqrestore(&txx9_spi_lock, flags); - return ret; - } - udelay(desc->tcss); - - /* do scatter IO */ - inp = inbufs ? *inbufs : NULL; - outp = outbufs ? *outbufs : NULL; - incount = 0; - outcount = 0; - while (1) { - unsigned char data; - unsigned int count; - int i; - if (!incount) { - incount = incounts ? *incounts++ : 0; - inp = (incount && inbufs) ? *inbufs++ : NULL; - } - if (!outcount) { - outcount = outcounts ? *outcounts++ : 0; - outp = (outcount && outbufs) ? *outbufs++ : NULL; - } - if (!inp && !outp) - break; - count = SPI_FIFO_SIZE; - if (incount) - count = min(count, incount); - if (outcount) - count = min(count, outcount); - - /* now tx must be idle... */ - while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE)) - ; - - tx4938_spiptr->cr0 = - (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) | - ((count - 1) << 12); - if (cansleep) { - /* enable rx intr */ - tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE; - } - /* send */ - for (i = 0; i < count; i++) - tx4938_spiptr->dr = inp ? *inp++ : 0; - /* wait all rx data */ - if (cansleep) { - wait_event(txx9_spi_wait, - tx4938_spiptr->sr & TXx9_SPSR_SRRDY); - } else { - while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI)) - ; - } - /* receive */ - for (i = 0; i < count; i++) { - data = tx4938_spiptr->dr; - if (outp) - *outp++ = data; - } - if (incount) - incount -= count; - if (outcount) - outcount -= count; - } - - /* CS OFF */ - udelay(desc->tcsh); - txx9_spi_cs_func(chipid, 0); - udelay(desc->tcsr); - - spin_lock_irqsave(&txx9_spi_lock, flags); - /* enter config mode */ - tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR; - spin_unlock_irqrestore(&txx9_spi_lock, flags); - - return 0; -} diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h index 0fbedafdcea8..74e7d8061e58 100644 --- a/include/asm-mips/tx4938/rbtx4938.h +++ b/include/asm-mips/tx4938/rbtx4938.h @@ -105,12 +105,6 @@ #define rbtx4938_pcireset_ptr \ ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR) -/* SPI */ -#define RBTX4938_SEEPROM1_CHIPID 0 -#define RBTX4938_SEEPROM2_CHIPID 1 -#define RBTX4938_SEEPROM3_CHIPID 2 -#define RBTX4938_SRTC_CHIPID 3 - /* * IRQ mappings */ diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h index 0dbbab820a5a..6a60c83e152b 100644 --- a/include/asm-mips/tx4938/spi.h +++ b/include/asm-mips/tx4938/spi.h @@ -14,61 +14,7 @@ #ifndef __ASM_TX_BOARDS_TX4938_SPI_H #define __ASM_TX_BOARDS_TX4938_SPI_H -/* SPI */ -struct spi_dev_desc { - unsigned int baud; - unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */ - unsigned int byteorder:1; /* 0:LSB-First, 1:MSB-First */ - unsigned int polarity:1; /* 0:High-Active */ - unsigned int phase:1; /* 0:Sample-Then-Shift */ -}; - -extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init; -extern void txx9_spi_irqinit(int irc_irq) __init; -extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc, - unsigned char **inbufs, unsigned int *incounts, - unsigned char **outbufs, unsigned int *outcounts, - int cansleep); -extern int spi_eeprom_write_enable(int chipid, int enable); -extern int spi_eeprom_read_status(int chipid); +extern int spi_eeprom_register(int chipid); extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); -extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len); -extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init; - -#define TXX9_IMCLK (txx9_gbus_clock / 2) - -/* -* SPI -*/ - -/* SPMCR : SPI Master Control */ -#define TXx9_SPMCR_OPMODE 0xc0 -#define TXx9_SPMCR_CONFIG 0x40 -#define TXx9_SPMCR_ACTIVE 0x80 -#define TXx9_SPMCR_SPSTP 0x02 -#define TXx9_SPMCR_BCLR 0x01 - -/* SPCR0 : SPI Status */ -#define TXx9_SPCR0_TXIFL_MASK 0xc000 -#define TXx9_SPCR0_RXIFL_MASK 0x3000 -#define TXx9_SPCR0_SIDIE 0x0800 -#define TXx9_SPCR0_SOEIE 0x0400 -#define TXx9_SPCR0_RBSIE 0x0200 -#define TXx9_SPCR0_TBSIE 0x0100 -#define TXx9_SPCR0_IFSPSE 0x0010 -#define TXx9_SPCR0_SBOS 0x0004 -#define TXx9_SPCR0_SPHA 0x0002 -#define TXx9_SPCR0_SPOL 0x0001 - -/* SPSR : SPI Status */ -#define TXx9_SPSR_TBSI 0x8000 -#define TXx9_SPSR_RBSI 0x4000 -#define TXx9_SPSR_TBS_MASK 0x3800 -#define TXx9_SPSR_RBS_MASK 0x0700 -#define TXx9_SPSR_SPOE 0x0080 -#define TXx9_SPSR_IFSD 0x0008 -#define TXx9_SPSR_SIDLE 0x0004 -#define TXx9_SPSR_STRDY 0x0002 -#define TXx9_SPSR_SRRDY 0x0001 #endif /* __ASM_TX_BOARDS_TX4938_SPI_H */ From bb33b19ff92aed11fb56435be4c5d5231598a948 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 22 Jun 2007 23:22:29 +0900 Subject: [PATCH 513/551] [MIPS] rbtx4938: Update and minimize defconfig Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/configs/rbhma4500_defconfig | 898 +++----------------------- 1 file changed, 103 insertions(+), 795 deletions(-) diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 6b9bebacb541..4aee174d4fbd 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:39 2007 +# Linux kernel version: 2.6.22-rc5 +# Fri Jun 22 21:39:45 2007 # CONFIG_MIPS=y @@ -9,19 +9,8 @@ CONFIG_MIPS=y # Machine selection # CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MACH_ALCHEMY is not set # CONFIG_BASLER_EXCITE is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set @@ -32,15 +21,13 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set # CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set # CONFIG_MARKEINS is not set @@ -80,6 +67,7 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y CONFIG_GENERIC_ISA_DMA=y CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set CONFIG_GENERIC_GPIO=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_LITTLE_ENDIAN=y @@ -92,6 +80,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y # # CPU selection # +# CONFIG_CPU_LOONGSON2 is not set # CONFIG_CPU_MIPS32_R1 is not set # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -148,12 +137,12 @@ CONFIG_ZONE_DMA_FLAG=1 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set +CONFIG_HZ_250=y # CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y +# CONFIG_HZ_1000 is not set # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 +CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -185,28 +174,35 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -243,17 +239,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +# CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -265,10 +256,7 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_PM is not set # # Networking @@ -278,14 +266,9 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -293,7 +276,7 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=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 @@ -304,130 +287,23 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -CONFIG_IPV6_MIP6=y +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_TUNNEL is not set -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK_ENABLED=m -CONFIG_NF_CONNTRACK_SUPPORT=y -# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_ACCT=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_NF_CONNTRACK_IPV6=m -# CONFIG_IP6_NF_QUEUE is not set -# CONFIG_IP6_NF_IPTABLES is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -445,7 +321,6 @@ CONFIG_NF_CONNTRACK_IPV6=m # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set -CONFIG_NET_CLS_ROUTE=y # # Network testing @@ -454,15 +329,16 @@ CONFIG_NET_CLS_ROUTE=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y -CONFIG_FIB_RULES=y +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -473,94 +349,13 @@ CONFIG_FIB_RULES=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # -CONFIG_CONNECTOR=m - -# -# 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 is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# 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 -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set # # Parallel port support @@ -582,93 +377,30 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -CONFIG_SGI_IOC4=m +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -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_IDECD=y -# 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_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -CONFIG_BLK_DEV_IT8213=m -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLK_DEV_TC86C001=m -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLINK is not set +# CONFIG_IDE is not set # # SCSI device support # -CONFIG_RAID_ATTRS=m +# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set # @@ -684,6 +416,7 @@ CONFIG_RAID_ATTRS=m # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -698,36 +431,15 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# ARCnet devices -# +# CONFIG_TUN is not set # CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set @@ -746,6 +458,7 @@ CONFIG_NET_PCI=y # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set +CONFIG_TC35815=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set @@ -760,91 +473,20 @@ CONFIG_NET_PCI=y # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_QLA3XXX=m -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_NET_WIRELESS_RTNETLINK is not set - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_IPW2100 is not set -CONFIG_IPW2200=m -# CONFIG_IPW2200_MONITOR is not set -# CONFIG_IPW2200_QOS is not set -# CONFIG_IPW2200_DEBUG is not set -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -# CONFIG_PRISM54 is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_HOSTAP is not set -# CONFIG_BCM43XX is not set -# CONFIG_ZD1211RW is not set -CONFIG_NET_WIRELESS=y - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m +# CONFIG_PPP is not set # CONFIG_SLIP is not set -CONFIG_SLHC=m # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -863,57 +505,18 @@ CONFIG_SLHC=m # # Input device support # -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set +# CONFIG_INPUT is not set # # Hardware I/O ports # -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set # # Character devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -925,11 +528,12 @@ CONFIG_VT_HW_CONSOLE_BINDING=y # Non-8250 serial port support # CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_TXX9=y CONFIG_HAS_TXX9_SERIAL=y CONFIG_SERIAL_TXX9_NR_UARTS=6 -# CONFIG_SERIAL_TXX9_CONSOLE is not set -# CONFIG_SERIAL_TXX9_STDSERIAL is not set +CONFIG_SERIAL_TXX9_CONSOLE=y +CONFIG_SERIAL_TXX9_STDSERIAL=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y @@ -939,15 +543,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set @@ -957,10 +556,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # TPM devices # # CONFIG_TCG_TPM is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -985,213 +581,53 @@ CONFIG_SPI_AT25=y # Dallas's 1-wire bus # # CONFIG_W1 is not set +# CONFIG_HWMON is not set # -# Hardware Monitoring support +# Multifunction device drivers # -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -CONFIG_FB_ATY=y -CONFIG_FB_ATY_CT=y -# CONFIG_FB_ATY_GENERIC_LCD is not set -# CONFIG_FB_ATY_GX is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_FB is not set + # # Sound # # CONFIG_SOUND is not set -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - # # USB support # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -CONFIG_USB_YEALINK=m -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -1270,39 +706,16 @@ CONFIG_RTC_DRV_RS5C348=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=m -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set +# CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set @@ -1312,26 +725,21 @@ CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +# CONFIG_ISO9660_FS is not set # CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -1345,7 +753,7 @@ CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1357,16 +765,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR 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=y +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -1381,19 +780,16 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set +# CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1409,54 +805,12 @@ 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 +# CONFIG_NLS is not set # # Distributed Lock Manager # -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set +# CONFIG_DLM is not set # # Profiling support @@ -1474,7 +828,6 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" CONFIG_SYS_SUPPORTS_KGDB=y @@ -1488,62 +841,17 @@ CONFIG_SYS_SUPPORTS_KGDB=y # # Cryptographic options # -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO is not set # # Library routines # CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -CONFIG_CRC16=m +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m +# CONFIG_LIBCRC32C is not set CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y From 5ddcb3c35be995517a32799796e2acda90a784e0 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 26 Jun 2007 01:14:01 +0900 Subject: [PATCH 514/551] [MIPS] Make ioremap() work on TX39/49 special unmapped segment TX39XX and TX49XX have "reserved" segment in CKSEG3 area. 0xff000000-0xff3fffff on TX49XX and 0xff000000-0xfffeffff on TX39XX are reserved (unmapped, uncached). Controllers on these SoCs are placed in this segment. This patch add plat_ioremap() and plat_iounmap() to override default behavior and implement these hooks for TX39/TX49. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 2 ++ include/asm-mips/io.h | 8 +++++ include/asm-mips/mach-au1x00/ioremap.h | 11 +++++++ include/asm-mips/mach-generic/ioremap.h | 11 +++++++ include/asm-mips/mach-jmr3927/ioremap.h | 38 ++++++++++++++++++++++ include/asm-mips/mach-tx49xx/ioremap.h | 42 +++++++++++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 include/asm-mips/mach-jmr3927/ioremap.h create mode 100644 include/asm-mips/mach-tx49xx/ioremap.h diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 2b9af2fd5507..96d4abbd7b30 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -580,6 +580,7 @@ load-$(CONFIG_TOSHIBA_JMR3927) += 0xffffffff80050000 # core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ +cflags-$(CONFIG_TOSHIBA_RBTX4927) += -Iinclude/asm-mips/mach-tx49xx load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 # @@ -587,6 +588,7 @@ load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 # core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/ core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/ +cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 cflags-y += -Iinclude/asm-mips/mach-generic diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 92ec2618560c..12bcc1f9fba9 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -178,6 +178,11 @@ extern void __iounmap(const volatile void __iomem *addr); static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, unsigned long flags) { + void __iomem *addr = plat_ioremap(offset, size, flags); + + if (addr) + return addr; + #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) if (cpu_has_64bit_addresses) { @@ -282,6 +287,9 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, static inline void iounmap(const volatile void __iomem *addr) { + if (plat_iounmap(addr)) + return; + #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) if (cpu_has_64bit_addresses || diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h index 098fca4289bb..364cea2dc71f 100644 --- a/include/asm-mips/mach-au1x00/ioremap.h +++ b/include/asm-mips/mach-au1x00/ioremap.h @@ -28,4 +28,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) return __fixup_bigphys_addr(phys_addr, size); } +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return 0; +} + #endif /* __ASM_MACH_AU1X00_IOREMAP_H */ diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h index 9b64ff6e485d..b379938d47f0 100644 --- a/include/asm-mips/mach-generic/ioremap.h +++ b/include/asm-mips/mach-generic/ioremap.h @@ -20,4 +20,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) return phys_addr; } +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return 0; +} + #endif /* __ASM_MACH_GENERIC_IOREMAP_H */ diff --git a/include/asm-mips/mach-jmr3927/ioremap.h b/include/asm-mips/mach-jmr3927/ioremap.h new file mode 100644 index 000000000000..aa131ad7f717 --- /dev/null +++ b/include/asm-mips/mach-jmr3927/ioremap.h @@ -0,0 +1,38 @@ +/* + * include/asm-mips/mach-jmr3927/ioremap.h + * + * 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. + */ +#ifndef __ASM_MACH_JMR3927_IOREMAP_H +#define __ASM_MACH_JMR3927_IOREMAP_H + +#include + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ +#define TXX9_DIRECTMAP_BASE 0xff000000ul + if (offset >= TXX9_DIRECTMAP_BASE && + offset < TXX9_DIRECTMAP_BASE + 0xf0000) + return (void __iomem *)offset; + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return (unsigned long)addr >= TXX9_DIRECTMAP_BASE; +} + +#endif /* __ASM_MACH_JMR3927_IOREMAP_H */ diff --git a/include/asm-mips/mach-tx49xx/ioremap.h b/include/asm-mips/mach-tx49xx/ioremap.h new file mode 100644 index 000000000000..88cf546719b8 --- /dev/null +++ b/include/asm-mips/mach-tx49xx/ioremap.h @@ -0,0 +1,42 @@ +/* + * include/asm-mips/mach-tx49xx/ioremap.h + * + * 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. + */ +#ifndef __ASM_MACH_TX49XX_IOREMAP_H +#define __ASM_MACH_TX49XX_IOREMAP_H + +#include + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ +#ifdef CONFIG_64BIT +#define TXX9_DIRECTMAP_BASE 0xfff000000ul +#else +#define TXX9_DIRECTMAP_BASE 0xff000000ul +#endif + if (offset >= TXX9_DIRECTMAP_BASE && + offset < TXX9_DIRECTMAP_BASE + 0x400000) + return (void __iomem *)(unsigned long)(int)offset; + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return (unsigned long)addr >= (unsigned long)(int)TXX9_DIRECTMAP_BASE; +} + +#endif /* __ASM_MACH_TX49XX_IOREMAP_H */ From 295cbf6d63165fe4253cf1d9ceadcda47a318b48 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 3 Jul 2007 14:37:43 +0100 Subject: [PATCH 515/551] [MIPS] Move FPU affinity code into separate file. Gets rid of some of the CONFIG_MIPS_MT_FPAFF #ifdefery. Signed-off-by: Ralf Baechle --- arch/mips/kernel/Makefile | 1 + arch/mips/kernel/mips-mt-fpaff.c | 176 +++++++++++++++++++++++++++++++ arch/mips/kernel/mips-mt.c | 169 ----------------------------- 3 files changed, 177 insertions(+), 169 deletions(-) create mode 100644 arch/mips/kernel/mips-mt-fpaff.c diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 73983eee1431..4b40015a66d2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_MIPS_MT) += mips-mt.o +obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c new file mode 100644 index 000000000000..ede5d73d652e --- /dev/null +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -0,0 +1,176 @@ +/* + * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels + * Copyright (C) 2005 Mips Technologies, Inc + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * CPU mask used to set process affinity for MT VPEs/TCs with FPUs + */ +cpumask_t mt_fpu_cpumask; + +static int fpaff_threshold = -1; +unsigned long mt_fpemul_threshold = 0; + +/* + * Replacement functions for the sys_sched_setaffinity() and + * sys_sched_getaffinity() system calls, so that we can integrate + * FPU affinity with the user's requested processor affinity. + * This code is 98% identical with the sys_sched_setaffinity() + * and sys_sched_getaffinity() system calls, and should be + * updated when kernel/sched.c changes. + */ + +/* + * find_process_by_pid - find a process with a matching PID value. + * used in sys_sched_set/getaffinity() in kernel/sched.c, so + * cloned here. + */ +static inline struct task_struct *find_process_by_pid(pid_t pid) +{ + return pid ? find_task_by_pid(pid) : current; +} + + +/* + * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process + */ +asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr) +{ + cpumask_t new_mask; + cpumask_t effective_mask; + int retval; + struct task_struct *p; + + if (len < sizeof(new_mask)) + return -EINVAL; + + if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) + return -EFAULT; + + lock_cpu_hotplug(); + read_lock(&tasklist_lock); + + p = find_process_by_pid(pid); + if (!p) { + read_unlock(&tasklist_lock); + unlock_cpu_hotplug(); + return -ESRCH; + } + + /* + * It is not safe to call set_cpus_allowed with the + * tasklist_lock held. We will bump the task_struct's + * usage count and drop tasklist_lock before invoking + * set_cpus_allowed. + */ + get_task_struct(p); + + retval = -EPERM; + if ((current->euid != p->euid) && (current->euid != p->uid) && + !capable(CAP_SYS_NICE)) { + read_unlock(&tasklist_lock); + goto out_unlock; + } + + retval = security_task_setscheduler(p, 0, NULL); + if (retval) + goto out_unlock; + + /* Record new user-specified CPU set for future reference */ + p->thread.user_cpus_allowed = new_mask; + + /* Unlock the task list */ + read_unlock(&tasklist_lock); + + /* Compute new global allowed CPU set if necessary */ + if ((p->thread.mflags & MF_FPUBOUND) + && cpus_intersects(new_mask, mt_fpu_cpumask)) { + cpus_and(effective_mask, new_mask, mt_fpu_cpumask); + retval = set_cpus_allowed(p, effective_mask); + } else { + p->thread.mflags &= ~MF_FPUBOUND; + retval = set_cpus_allowed(p, new_mask); + } + + +out_unlock: + put_task_struct(p); + unlock_cpu_hotplug(); + return retval; +} + +/* + * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process + */ +asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr) +{ + unsigned int real_len; + cpumask_t mask; + int retval; + struct task_struct *p; + + real_len = sizeof(mask); + if (len < real_len) + return -EINVAL; + + lock_cpu_hotplug(); + read_lock(&tasklist_lock); + + retval = -ESRCH; + p = find_process_by_pid(pid); + if (!p) + goto out_unlock; + retval = security_task_getscheduler(p); + if (retval) + goto out_unlock; + + cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); + +out_unlock: + read_unlock(&tasklist_lock); + unlock_cpu_hotplug(); + if (retval) + return retval; + if (copy_to_user(user_mask_ptr, &mask, real_len)) + return -EFAULT; + return real_len; +} + + +static int __init fpaff_thresh(char *str) +{ + get_option(&str, &fpaff_threshold); + return 1; +} +__setup("fpaff=", fpaff_thresh); + +/* + * FPU Use Factor empirically derived from experiments on 34K + */ +#define FPUSEFACTOR 333 + +static __init int mt_fp_affinity_init(void) +{ + if (fpaff_threshold >= 0) { + mt_fpemul_threshold = fpaff_threshold; + } else { + mt_fpemul_threshold = + (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; + } + printk(KERN_DEBUG "FPU Affinity set after %ld emulations\n", + mt_fpemul_threshold); + + return 0; +} +arch_initcall(mt_fp_affinity_init); diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index b1b994dd41db..1a7d89231299 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -22,149 +21,6 @@ #include #include -/* - * CPU mask used to set process affinity for MT VPEs/TCs with FPUs - */ - -cpumask_t mt_fpu_cpumask; - -#ifdef CONFIG_MIPS_MT_FPAFF - -#include -#include -#include - -unsigned long mt_fpemul_threshold = 0; - -/* - * Replacement functions for the sys_sched_setaffinity() and - * sys_sched_getaffinity() system calls, so that we can integrate - * FPU affinity with the user's requested processor affinity. - * This code is 98% identical with the sys_sched_setaffinity() - * and sys_sched_getaffinity() system calls, and should be - * updated when kernel/sched.c changes. - */ - -/* - * find_process_by_pid - find a process with a matching PID value. - * used in sys_sched_set/getaffinity() in kernel/sched.c, so - * cloned here. - */ -static inline struct task_struct *find_process_by_pid(pid_t pid) -{ - return pid ? find_task_by_pid(pid) : current; -} - - -/* - * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process - */ -asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) -{ - cpumask_t new_mask; - cpumask_t effective_mask; - int retval; - struct task_struct *p; - - if (len < sizeof(new_mask)) - return -EINVAL; - - if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) - return -EFAULT; - - lock_cpu_hotplug(); - read_lock(&tasklist_lock); - - p = find_process_by_pid(pid); - if (!p) { - read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); - return -ESRCH; - } - - /* - * It is not safe to call set_cpus_allowed with the - * tasklist_lock held. We will bump the task_struct's - * usage count and drop tasklist_lock before invoking - * set_cpus_allowed. - */ - get_task_struct(p); - - retval = -EPERM; - if ((current->euid != p->euid) && (current->euid != p->uid) && - !capable(CAP_SYS_NICE)) { - read_unlock(&tasklist_lock); - goto out_unlock; - } - - retval = security_task_setscheduler(p, 0, NULL); - if (retval) - goto out_unlock; - - /* Record new user-specified CPU set for future reference */ - p->thread.user_cpus_allowed = new_mask; - - /* Unlock the task list */ - read_unlock(&tasklist_lock); - - /* Compute new global allowed CPU set if necessary */ - if ((p->thread.mflags & MF_FPUBOUND) - && cpus_intersects(new_mask, mt_fpu_cpumask)) { - cpus_and(effective_mask, new_mask, mt_fpu_cpumask); - retval = set_cpus_allowed(p, effective_mask); - } else { - p->thread.mflags &= ~MF_FPUBOUND; - retval = set_cpus_allowed(p, new_mask); - } - - -out_unlock: - put_task_struct(p); - unlock_cpu_hotplug(); - return retval; -} - -/* - * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process - */ -asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) -{ - unsigned int real_len; - cpumask_t mask; - int retval; - struct task_struct *p; - - real_len = sizeof(mask); - if (len < real_len) - return -EINVAL; - - lock_cpu_hotplug(); - read_lock(&tasklist_lock); - - retval = -ESRCH; - p = find_process_by_pid(pid); - if (!p) - goto out_unlock; - retval = security_task_getscheduler(p); - if (retval) - goto out_unlock; - - cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); - -out_unlock: - read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); - if (retval) - return retval; - if (copy_to_user(user_mask_ptr, &mask, real_len)) - return -EFAULT; - return real_len; -} - -#endif /* CONFIG_MIPS_MT_FPAFF */ - /* * Dump new MIPS MT state for the core. Does not leave TCs halted. * Takes an argument which taken to be a pre-call MVPControl value. @@ -314,17 +170,6 @@ static int __init ndflush(char *s) return 1; } __setup("ndflush=", ndflush); -#ifdef CONFIG_MIPS_MT_FPAFF -static int fpaff_threshold = -1; - -static int __init fpaff_thresh(char *str) -{ - get_option(&str, &fpaff_threshold); - return 1; -} - -__setup("fpaff=", fpaff_thresh); -#endif /* CONFIG_MIPS_MT_FPAFF */ static unsigned int itc_base = 0; @@ -380,20 +225,6 @@ void mips_mt_set_cpuoptions(void) if (mt_n_dflushes != 1) printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); -#ifdef CONFIG_MIPS_MT_FPAFF - /* FPU Use Factor empirically derived from experiments on 34K */ -#define FPUSEFACTOR 333 - - if (fpaff_threshold >= 0) { - mt_fpemul_threshold = fpaff_threshold; - } else { - mt_fpemul_threshold = - (FPUSEFACTOR * (loops_per_jiffy / (500000 / HZ))) / HZ; - } - printk("FPU Affinity set after %ld emulations\n", - mt_fpemul_threshold); -#endif /* CONFIG_MIPS_MT_FPAFF */ - if (itc_base != 0) { /* * Configure ITC mapping. This code is very From bd43da8ff130caf31fff0482a75660507a26b641 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 29 Jun 2007 22:34:53 +0900 Subject: [PATCH 516/551] [MIPS] tc35815: Load MAC address via platform_device TX49XX SoCs include PCI NIC (TC35815 compatible) connected via its internal PCI bus, but the NIC's PROM interface is not connected to SEEPROM. So we must provide its ethernet address by another way. Signed-off-by: Atsushi Nemoto Acked-by: Jeff Garzik Signed-off-by: Ralf Baechle --- drivers/net/tc35815.c | 50 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 463d600ed83d..75655add3f34 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -23,9 +23,9 @@ */ #ifdef TC35815_NAPI -#define DRV_VERSION "1.35-NAPI" +#define DRV_VERSION "1.36-NAPI" #else -#define DRV_VERSION "1.35" +#define DRV_VERSION "1.36" #endif static const char *version = "tc35815.c:v" DRV_VERSION "\n"; #define MODNAME "tc35815" @@ -49,6 +49,7 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n"; #include #include #include +#include #include #include @@ -597,13 +598,46 @@ static int tc_mdio_read(struct net_device *dev, int phy_id, int location); static void tc_mdio_write(struct net_device *dev, int phy_id, int location, int val); -static void __devinit tc35815_init_dev_addr (struct net_device *dev) +#ifdef CONFIG_CPU_TX49XX +/* + * Find a platform_device providing a MAC address. The platform code + * should provide a "tc35815-mac" device with a MAC address in its + * platform_data. + */ +static int __devinit tc35815_mac_match(struct device *dev, void *data) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct pci_dev *pci_dev = data; + unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn; + return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id; +} + +static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev) +{ + struct tc35815_local *lp = dev->priv; + struct device *pd = bus_find_device(&platform_bus_type, NULL, + lp->pci_dev, tc35815_mac_match); + if (pd) { + if (pd->platform_data) + memcpy(dev->dev_addr, pd->platform_data, ETH_ALEN); + put_device(pd); + return is_valid_ether_addr(dev->dev_addr) ? 0 : -ENODEV; + } + return -ENODEV; +} +#else +static int __devinit tc35815_read_plat_dev_addr(struct device *dev) +{ + return -ENODEV; +} +#endif + +static int __devinit tc35815_init_dev_addr (struct net_device *dev) { struct tc35815_regs __iomem *tr = (struct tc35815_regs __iomem *)dev->base_addr; int i; - /* dev_addr will be overwritten on NETDEV_REGISTER event */ while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) ; for (i = 0; i < 6; i += 2) { @@ -615,6 +649,9 @@ static void __devinit tc35815_init_dev_addr (struct net_device *dev) dev->dev_addr[i] = data & 0xff; dev->dev_addr[i+1] = data >> 8; } + if (!is_valid_ether_addr(dev->dev_addr)) + return tc35815_read_plat_dev_addr(dev); + return 0; } static int __devinit tc35815_init_one (struct pci_dev *pdev, @@ -724,7 +761,10 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, tc35815_chip_reset(dev); /* Retrieve the ethernet address. */ - tc35815_init_dev_addr(dev); + if (tc35815_init_dev_addr(dev)) { + dev_warn(&pdev->dev, "not valid ether addr\n"); + random_ether_addr(dev->dev_addr); + } rc = register_netdev (dev); if (rc) From 2db30150fe4fe309c57087c661209c9ea0b5c21b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 2 Jul 2007 22:43:06 +0900 Subject: [PATCH 517/551] [MIPS] rbtx4938: Fix secondary PCIC and glue internal NICs * Fix pci ops for secondary PCIC * Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero) * Use platform_device to provide ethernet addresses for internal NICs. (background: TX49XX SoCs include PCI NIC (TC35815 compatible) connected via its internal PCI bus, but the NIC's PROM interface is not connected to SEEPROM. So we must provide its ethernet address by another way.) * Check return value of early_read_config_word() Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/pci/ops-tx4938.c | 80 ++++++++++++++--------- arch/mips/tx4938/toshiba_rbtx4938/setup.c | 53 +++++++-------- 2 files changed, 70 insertions(+), 63 deletions(-) diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c index 445007084515..a450c4062031 100644 --- a/arch/mips/pci/ops-tx4938.c +++ b/arch/mips/pci/ops-tx4938.c @@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = { .flags = IORESOURCE_MEM }; -static int mkaddr(int bus, int dev_fn, int where, int *flagsp) +static int mkaddr(int bus, int dev_fn, int where, + struct tx4938_pcic_reg *pcicptr) { if (bus > 0) { /* Type 1 configuration */ - tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; } else { if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) return -1; /* Type 0 configuration */ - tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | ((dev_fn & 0xff) << 0x08) | (where & 0xfc); } /* clear M_ABORT and Disable M_ABORT Int. */ - tx4938_pcicptr->pcistatus = - (tx4938_pcicptr->pcistatus & 0x0000ffff) | + pcicptr->pcistatus = + (pcicptr->pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT << 16); - tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; return 0; } -static int check_abort(int flags) +static int check_abort(struct tx4938_pcic_reg *pcicptr) { int code = PCIBIOS_SUCCESSFUL; /* wait write cycle completion before checking error status */ - while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) + while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) ; - if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - tx4938_pcicptr->pcistatus = - (tx4938_pcicptr-> + if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + pcicptr->pcistatus = + (pcicptr-> pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT << 16); - tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; code = PCIBIOS_DEVICE_NOT_FOUND; } return code; } +extern struct pci_controller tx4938_pci_controller[]; +extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch); + +static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus) +{ + struct pci_controller *channel = bus->sysdata; + return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]); +} + static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { - int flags, retval, dev, busno, func; + int retval, dev, busno, func; + struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); + void __iomem *cfgdata = + (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); @@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, busno = 0; } - if (mkaddr(busno, devfn, where, &flags)) + if (mkaddr(busno, devfn, where, pcicptr)) return -1; switch (size) { case 1: - *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | #ifdef __BIG_ENDIAN - ((where & 3) ^ 3)); + cfgdata += (where & 3) ^ 3; #else - (where & 3)); + cfgdata += where & 3; #endif + *val = __raw_readb(cfgdata); break; case 2: - *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | #ifdef __BIG_ENDIAN - ((where & 3) ^ 2)); + cfgdata += (where & 2) ^ 2; #else - (where & 3)); + cfgdata += where & 2; #endif + *val = __raw_readw(cfgdata); break; case 4: - *val = tx4938_pcicptr->g2pcfgdata; + *val = __raw_readl(cfgdata); break; } - retval = check_abort(flags); + retval = check_abort(pcicptr); if (retval == PCIBIOS_DEVICE_NOT_FOUND) *val = 0xffffffff; @@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - int flags, dev, busno, func; + int dev, busno, func; + struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); + void __iomem *cfgdata = + (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; busno = bus->number; dev = PCI_SLOT(devfn); @@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, busno = 0; } - if (mkaddr(busno, devfn, where, &flags)) + if (mkaddr(busno, devfn, where, pcicptr)) return -1; switch (size) { case 1: - *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | #ifdef __BIG_ENDIAN - ((where & 3) ^ 3)) = val; + cfgdata += (where & 3) ^ 3; #else - (where & 3)) = val; + cfgdata += where & 3; #endif + __raw_writeb(val, cfgdata); break; case 2: - *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | #ifdef __BIG_ENDIAN - ((where & 0x3) ^ 0x2)) = val; + cfgdata += (where & 2) ^ 2; #else - (where & 3)) = val; + cfgdata += where & 2; #endif + __raw_writew(val, cfgdata); break; case 4: - tx4938_pcicptr->g2pcfgdata = val; + __raw_writel(val, cfgdata); break; } - return check_abort(flags); + return check_abort(pcicptr); } struct pci_ops tx4938_pci_ops = { diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 361d89a81175..6ed39a5aea72 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -352,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose, static struct pci_dev dev; static struct pci_bus bus; - dev.sysdata = (void *)hose; + dev.sysdata = bus.sysdata = hose; dev.devfn = devfn; bus.number = busnr; bus.ops = hose->pci_ops; @@ -385,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu printk("PCI: Checking 66MHz capabilities...\n"); for (pci_devfn=devfn_start; pci_devfnccfg & TX4938_CCFG_PCIXARB); PCIBIOS_MIN_IO = 0x00001000UL; - PCIBIOS_MIN_MEM = 0x01000000UL; mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); @@ -578,18 +579,17 @@ arch_initcall(tx4938_pcibios_init); #define SRTC_CS 2 /* IOC */ #ifdef CONFIG_PCI -static unsigned char rbtx4938_ethaddr[17]; static int __init rbtx4938_ethaddr_init(void) { + unsigned char dat[17]; unsigned char sum; int i; /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ - if (spi_eeprom_read(SEEPROM1_CS, 0, - rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr))) + if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { printk(KERN_ERR "seeprom: read error.\n"); - else { - unsigned char *dat = rbtx4938_ethaddr; + return -ENODEV; + } else { if (strcmp(dat, "MAC") != 0) printk(KERN_WARNING "seeprom: bad signature.\n"); for (i = 0, sum = 0; i < sizeof(dat); i++) @@ -597,31 +597,22 @@ static int __init rbtx4938_ethaddr_init(void) if (sum) printk(KERN_WARNING "seeprom: bad checksum.\n"); } + for (i = 0; i < 2; i++) { + unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i); + unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */ + struct platform_device *pdev; + if (!(tx4938_ccfgptr->pcfg & + (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) + continue; + pdev = platform_device_alloc("tc35815-mac", id); + if (!pdev || + platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || + platform_device_add(pdev)) + platform_device_put(pdev); + } return 0; } device_initcall(rbtx4938_ethaddr_init); - -int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) -{ - struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; - int ch = 0; - - if (channel != &tx4938_pci_controller[1]) - return -ENODEV; - /* TX4938 PCIC1 */ - switch (PCI_SLOT(dev->devfn)) { - case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): - ch = 0; - break; - case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): - ch = 1; - break; - default: - return -ENODEV; - } - memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6); - return 0; -} #endif /* CONFIG_PCI */ static void __init rbtx4938_spi_setup(void) From 6312e0ee45236b6882cd26b2ccc167b1b91646fc Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 30 Jun 2007 00:55:48 +0900 Subject: [PATCH 518/551] [MIPS] Add some debugfs files to debug unaligned accesses Currently a number of unaligned instructions is counted but not used. Add /debug/mips/unaligned_instructions file to show the value. And add /debug/mips/unaligned_action to control behavior upon an unaligned access. Possible actions are: 0: silently fixup the unaligned access. 1: send SIGBUS. 2: dump registers, process name, etc. and fixup. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 16 ++++++++++++++ arch/mips/kernel/unaligned.c | 41 +++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 4975da0bfb63..316685fca059 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -574,3 +575,18 @@ __setup("nodsp", dsp_disable); unsigned long kernelsp[NR_CPUS]; unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; + +#ifdef CONFIG_DEBUG_FS +struct dentry *mips_debugfs_dir; +static int __init debugfs_mips(void) +{ + struct dentry *d; + + d = debugfs_create_dir("mips", NULL); + if (IS_ERR(d)) + return PTR_ERR(d); + mips_debugfs_dir = d; + return 0; +} +arch_initcall(debugfs_mips); +#endif diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 18c4a3c45a31..8b9c34ffae18 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -87,9 +88,18 @@ #define STR(x) __STR(x) #define __STR(x) #x -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; +enum { + UNALIGNED_ACTION_QUIET, + UNALIGNED_ACTION_SIGNAL, + UNALIGNED_ACTION_SHOW, +}; +#ifdef CONFIG_DEBUG_FS +static u32 unaligned_instructions; +static u32 unaligned_action; +#else +#define unaligned_action UNALIGNED_ACTION_QUIET #endif +extern void show_registers(struct pt_regs *regs); static inline int emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned int __user *pc, @@ -459,7 +469,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs, goto sigill; } -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_DEBUG_FS unaligned_instructions++; #endif @@ -516,6 +526,10 @@ asmlinkage void do_ade(struct pt_regs *regs) pc = (unsigned int __user *) exception_epc(regs); if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0) goto sigbus; + if (unaligned_action == UNALIGNED_ACTION_SIGNAL) + goto sigbus; + else if (unaligned_action == UNALIGNED_ACTION_SHOW) + show_registers(regs); /* * Do branch emulation only if we didn't forward the exception. @@ -546,3 +560,24 @@ sigbus: * XXX On return from the signal handler we should advance the epc */ } + +#ifdef CONFIG_DEBUG_FS +extern struct dentry *mips_debugfs_dir; +static int __init debugfs_unaligned(void) +{ + struct dentry *d; + + if (!mips_debugfs_dir) + return -ENODEV; + d = debugfs_create_u32("unaligned_instructions", S_IRUGO, + mips_debugfs_dir, &unaligned_instructions); + if (IS_ERR(d)) + return PTR_ERR(d); + d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR, + mips_debugfs_dir, &unaligned_action); + if (IS_ERR(d)) + return PTR_ERR(d); + return 0; +} +__initcall(debugfs_unaligned); +#endif From 83fd38cabc982db041d3586a15734713f45caa31 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 7 Jul 2007 23:21:49 +0900 Subject: [PATCH 519/551] [MIPS] Add debugfs files to show fpuemu statistics Export contents of struct mips_fpu_emulator_stats via debugfs. There is no way to read these statistics for now but they (at least the "emulated" count) might be sometimes useful for performance tuning on FPU-less CPUs. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/math-emu/cp1emu.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 80531b35cd61..d7f05b0abe17 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -35,6 +35,7 @@ * better performance by compiling with -msoft-float! */ #include +#include #include #include @@ -1277,3 +1278,36 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, return sig; } + +#ifdef CONFIG_DEBUG_FS +extern struct dentry *mips_debugfs_dir; +static int __init debugfs_fpuemu(void) +{ + struct dentry *d, *dir; + int i; + static struct { + const char *name; + unsigned int *v; + } vars[] __initdata = { + { "emulated", &fpuemustats.emulated }, + { "loads", &fpuemustats.loads }, + { "stores", &fpuemustats.stores }, + { "cp1ops", &fpuemustats.cp1ops }, + { "cp1xops", &fpuemustats.cp1xops }, + { "errors", &fpuemustats.errors }, + }; + + if (!mips_debugfs_dir) + return -ENODEV; + dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); + if (IS_ERR(dir)) + return PTR_ERR(dir); + for (i = 0; i < ARRAY_SIZE(vars); i++) { + d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v); + if (IS_ERR(d)) + return PTR_ERR(d); + } + return 0; +} +__initcall(debugfs_fpuemu); +#endif From ecd27b92fbb41f779d857632a69bd45dbaf0f915 Mon Sep 17 00:00:00 2001 From: Chris Dearman Date: Fri, 6 Jul 2007 17:11:20 +0100 Subject: [PATCH 520/551] [MIPS] Early check for SMTC kernel on non-MT processor Signed-off-by: Chris Dearman Signed-off-by: Ralf Baechle --- .../asm-mips/mach-mips/kernel-entry-init.h | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 include/asm-mips/mach-mips/kernel-entry-init.h diff --git a/include/asm-mips/mach-mips/kernel-entry-init.h b/include/asm-mips/mach-mips/kernel-entry-init.h new file mode 100644 index 000000000000..0b793e7bf67e --- /dev/null +++ b/include/asm-mips/mach-mips/kernel-entry-init.h @@ -0,0 +1,52 @@ +/* + * 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. + * + * Chris Dearman (chris@mips.com) + * Copyright (C) 2007 Mips Technologies, Inc. + */ +#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H +#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H + + .macro kernel_entry_setup +#ifdef CONFIG_MIPS_MT_SMTC + mfc0 t0, CP0_CONFIG + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 1 + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 2 + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 3 + and t0, 1<<2 + bnez t0, 0f +9: + /* Assume we came from YAMON... */ + PTR_LA v0, 0x9fc00534 /* YAMON print */ + lw v0, (v0) + move a0, zero + PTR_LA a1, nonmt_processor + jal v0 + + PTR_LA v0, 0x9fc00520 /* YAMON exit */ + lw v0, (v0) + li a0, 1 + jal v0 + +1: b 1b + + __INITDATA +nonmt_processor: + .asciz "SMTC kernel requires the MT ASE to run\n" + __FINIT +0: +#endif + .endm + +/* + * Do SMP slave processor setup necessary before we can safely execute C code. + */ + .macro smp_slave_setup + .endm + +#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */ From c99cabf034d42c9e4a9c1ed9dfd26411b2fb9b57 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 9 Jul 2007 13:10:55 +0900 Subject: [PATCH 521/551] [MIPS] remove LASAT Networks platforms support Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 18 - arch/mips/Makefile | 10 - arch/mips/configs/atlas_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/ddb5477_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/fulong_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/lasat200_defconfig | 1116 -------------------- arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/msp71xx_defconfig | 1 - arch/mips/configs/ocelot_3_defconfig | 1 - arch/mips/configs/ocelot_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/qemu_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 1 - arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/defconfig | 1 - arch/mips/lasat/Kconfig | 15 - arch/mips/lasat/Makefile | 14 - arch/mips/lasat/at93c.c | 148 --- arch/mips/lasat/at93c.h | 18 - arch/mips/lasat/ds1603.c | 183 ---- arch/mips/lasat/ds1603.h | 33 - arch/mips/lasat/image/Makefile | 53 - arch/mips/lasat/image/head.S | 31 - arch/mips/lasat/image/romscript.normal | 23 - arch/mips/lasat/interrupt.c | 130 --- arch/mips/lasat/lasat_board.c | 279 ----- arch/mips/lasat/lasat_models.h | 63 -- arch/mips/lasat/picvue.c | 240 ----- arch/mips/lasat/picvue.h | 48 - arch/mips/lasat/picvue_proc.c | 186 ---- arch/mips/lasat/prom.c | 117 -- arch/mips/lasat/prom.h | 5 - arch/mips/lasat/reset.c | 69 -- arch/mips/lasat/setup.c | 182 ---- arch/mips/lasat/sysctl.c | 441 -------- arch/mips/lasat/sysctl.h | 24 - arch/mips/pci/Makefile | 2 - arch/mips/pci/ops-nile4.c | 147 --- arch/mips/pci/pci-lasat.c | 91 -- drivers/mtd/maps/Kconfig | 6 - drivers/mtd/maps/Makefile | 1 - drivers/mtd/maps/lasat.c | 103 -- include/asm-mips/bootinfo.h | 7 - include/asm-mips/lasat/ds1603.h | 18 - include/asm-mips/lasat/eeprom.h | 17 - include/asm-mips/lasat/head.h | 22 - include/asm-mips/lasat/lasat.h | 253 ----- include/asm-mips/lasat/lasatint.h | 12 - include/asm-mips/lasat/picvue.h | 15 - include/asm-mips/lasat/serial.h | 13 - include/asm-mips/mach-lasat/mach-gt64120.h | 27 - include/asm-mips/nile4.h | 310 ------ 84 files changed, 4534 deletions(-) delete mode 100644 arch/mips/configs/lasat200_defconfig delete mode 100644 arch/mips/lasat/Kconfig delete mode 100644 arch/mips/lasat/Makefile delete mode 100644 arch/mips/lasat/at93c.c delete mode 100644 arch/mips/lasat/at93c.h delete mode 100644 arch/mips/lasat/ds1603.c delete mode 100644 arch/mips/lasat/ds1603.h delete mode 100644 arch/mips/lasat/image/Makefile delete mode 100644 arch/mips/lasat/image/head.S delete mode 100644 arch/mips/lasat/image/romscript.normal delete mode 100644 arch/mips/lasat/interrupt.c delete mode 100644 arch/mips/lasat/lasat_board.c delete mode 100644 arch/mips/lasat/lasat_models.h delete mode 100644 arch/mips/lasat/picvue.c delete mode 100644 arch/mips/lasat/picvue.h delete mode 100644 arch/mips/lasat/picvue_proc.c delete mode 100644 arch/mips/lasat/prom.c delete mode 100644 arch/mips/lasat/prom.h delete mode 100644 arch/mips/lasat/reset.c delete mode 100644 arch/mips/lasat/setup.c delete mode 100644 arch/mips/lasat/sysctl.c delete mode 100644 arch/mips/lasat/sysctl.h delete mode 100644 arch/mips/pci/ops-nile4.c delete mode 100644 arch/mips/pci/pci-lasat.c delete mode 100644 drivers/mtd/maps/lasat.c delete mode 100644 include/asm-mips/lasat/ds1603.h delete mode 100644 include/asm-mips/lasat/eeprom.h delete mode 100644 include/asm-mips/lasat/head.h delete mode 100644 include/asm-mips/lasat/lasat.h delete mode 100644 include/asm-mips/lasat/lasatint.h delete mode 100644 include/asm-mips/lasat/picvue.h delete mode 100644 include/asm-mips/lasat/serial.h delete mode 100644 include/asm-mips/mach-lasat/mach-gt64120.h delete mode 100644 include/asm-mips/nile4.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 823a6285c55a..1619cf2c9ff0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -131,20 +131,6 @@ config MACH_JAZZ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and Olivetti M700-10 workstations. -config LASAT - bool "LASAT Networks platforms" - select DMA_NONCOHERENT - select SYS_HAS_EARLY_PRINTK - select HW_HAS_PCI - select PCI_GT64XXX_PCI0 - select MIPS_NILE4 - select R5000_CPU_SCACHE - select SYS_HAS_CPU_R5000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if BROKEN - select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ - config MIPS_ATLAS bool "MIPS Atlas board" select BOOT_ELF32 @@ -670,7 +656,6 @@ endchoice source "arch/mips/au1000/Kconfig" source "arch/mips/ddb5xxx/Kconfig" source "arch/mips/jazz/Kconfig" -source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" @@ -779,9 +764,6 @@ config MIPS_BONITO64 config MIPS_MSC bool -config MIPS_NILE4 - bool - config MIPS_DISABLE_OBSOLETE_IDE bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 96d4abbd7b30..0c270b6ee24c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -389,10 +389,6 @@ core-$(CONFIG_DDB5XXX_COMMON) += arch/mips/ddb5xxx/common/ core-$(CONFIG_DDB5477) += arch/mips/ddb5xxx/ddb5477/ load-$(CONFIG_DDB5477) += 0xffffffff80100000 -core-$(CONFIG_LASAT) += arch/mips/lasat/ -cflags-$(CONFIG_LASAT) += -Iinclude/asm-mips/mach-lasat -load-$(CONFIG_LASAT) += 0xffffffff80000000 - # # Common VR41xx # @@ -641,11 +637,6 @@ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ -ifdef CONFIG_LASAT -rom.bin rom.sw: vmlinux - $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ -endif - # # Some machines like the Indy need 32-bit ELF binaries for booting purposes. # Other need ECOFF, so we build a 32-bit ELF binary for them which we then @@ -715,7 +706,6 @@ endif archclean: @$(MAKE) $(clean)=arch/mips/boot - @$(MAKE) $(clean)=arch/mips/lasat CLEAN_FILES += vmlinux.32 \ vmlinux.64 \ diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index de855d1fc01f..6480571de944 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index bf88a6ce8042..9c75795cba08 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 7582709874c3..0152730fb4d1 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 9c5750c91810..521311ad9528 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -13,7 +13,6 @@ CONFIG_MIPS=y CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index bbf007a69105..f3b0bc7abb56 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 384e41afb544..b9ebb301a523 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 76c3c46851a7..cfebcca2f938 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 89c458086e6e..213ef385ff09 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index c83ba3cc1f05..aa40611fb00b 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 7ec230ed225a..1f4acce27659 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 2a4948a2d7d3..a08b99a0379d 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index d853278fce65..938da2d7b19d 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index 31f03f8113ee..dab9aba49487 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index b1a9e0b3067e..a828c04d1afe 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -27,7 +27,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig index 549f61b5896a..f15559fa578d 100644 --- a/arch/mips/configs/fulong_defconfig +++ b/arch/mips/configs/fulong_defconfig @@ -14,7 +14,6 @@ CONFIG_LEMOTE_FULONG=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 2f2243658aad..cc0530ef33f2 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 267af44f97ab..482f2fa120df 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 00ec6ed5e550..f9f58d0906ba 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 12c02656013e..bc4e30fe4e22 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set CONFIG_MACH_JAZZ=y -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 61235a552df2..baa1736c21cd 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig deleted file mode 100644 index c427c08efb6c..000000000000 --- a/arch/mips/configs/lasat200_defconfig +++ /dev/null @@ -1,1116 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:34 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -CONFIG_LASAT=y -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_PICVUE=y -CONFIG_PICVUE_PROC=y -CONFIG_DS1603=y -CONFIG_LASAT_SYSCTL=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_MIPS_NILE4=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_MIPS_GT64120=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -CONFIG_CPU_R5000=y -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R5000=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_R5000_CPU_SCACHE=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -# CONFIG_PACKET is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# 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 is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# 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 -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_LASAT=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -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=y -# CONFIG_BLK_DEV_IDECD is not set -# 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_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -CONFIG_BLK_DEV_IT8213=m -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLK_DEV_TC86C001=m -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_QLA3XXX=m -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_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=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=m -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM 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_HW_RANDOM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -# CONFIG_HID is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS 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 -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m -CONFIG_GENERIC_ACL=y - -# -# 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_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS 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_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1f5cf9200846..d8ee7c28c83b 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set CONFIG_MIPS_MALTA=y # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index ef5cae94c076..fc8a42477840 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 73a5314603e3..2da27ece70c7 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index 0d8a692d8826..cb2aeb20721e 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index cc99c83a81d2..20946b8141a3 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 5f3b47fa3f19..492c9abfd943 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index b57662a2a3e3..22fb01bc6a7a 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 350f9bdbb5e2..b0abaef4ce56 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 8ea039ab0895..ddb173ae50ea 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 9c8c54ee5e9d..2c2a8c8dca69 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index 2f60c5a4286b..b435d63deab9 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index d7ace0857383..cfe1f5a0a20f 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index b020e9270147..76b939fad78e 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -25,7 +25,6 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 4aee174d4fbd..2c9e7e493a1b 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -15,7 +15,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 120dcff4942e..9d731409c730 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 534de60fd03c..55fa6731c111 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index e0185ebdfa8f..f80c61a54653 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set CONFIG_MIPS_SEAD=y diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index 11f4c66ea456..d5e4e3e3769b 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index 1c54d1bbba7d..8743f6dfd7ed 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 7f2ece3d857c..eab47f2ac829 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index ef663304c93d..d32e4cd55ee4 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index d57d6cca646c..95986e37382c 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 38349216668f..c1e5a128cfa6 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 9515ed6128ca..bf18baf2fbc2 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig deleted file mode 100644 index 1d2ee8a9be13..000000000000 --- a/arch/mips/lasat/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config PICVUE - tristate "PICVUE LCD display driver" - depends on LASAT - -config PICVUE_PROC - tristate "PICVUE LCD display driver /proc interface" - depends on PICVUE - -config DS1603 - bool "DS1603 RTC driver" - depends on LASAT - -config LASAT_SYSCTL - bool "LASAT sysctl interface" - depends on LASAT diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile deleted file mode 100644 index 99f5046fdf49..000000000000 --- a/arch/mips/lasat/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for the LASAT specific kernel interface routines under Linux. -# - -obj-y += reset.o setup.o prom.o lasat_board.o \ - at93c.o interrupt.o - -obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o -obj-$(CONFIG_DS1603) += ds1603.o -obj-$(CONFIG_PICVUE) += picvue.o -obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o - -clean: - make -C image clean diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c deleted file mode 100644 index ca26e554615e..000000000000 --- a/arch/mips/lasat/at93c.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Atmel AT93C46 serial eeprom driver - * - * Brian Murphy - * - */ -#include -#include -#include -#include -#include - -#include "at93c.h" - -#define AT93C_ADDR_SHIFT 7 -#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) -#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) -#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) -#define AT93C_WENCMD 0x260 -#define AT93C_WDSCMD 0x200 - -struct at93c_defs *at93c; - -static void at93c_reg_write(u32 val) -{ - *at93c->reg = val; -} - -static u32 at93c_reg_read(void) -{ - u32 tmp = *at93c->reg; - return tmp; -} - -static u32 at93c_datareg_read(void) -{ - u32 tmp = *at93c->rdata_reg; - return tmp; -} - -static void at93c_cycle_clk(u32 data) -{ - at93c_reg_write(data | at93c->clk); - lasat_ndelay(250); - at93c_reg_write(data & ~at93c->clk); - lasat_ndelay(250); -} - -static void at93c_write_databit(u8 bit) -{ - u32 data = at93c_reg_read(); - if (bit) - data |= 1 << at93c->wdata_shift; - else - data &= ~(1 << at93c->wdata_shift); - - at93c_reg_write(data); - lasat_ndelay(100); - at93c_cycle_clk(data); -} - -static unsigned int at93c_read_databit(void) -{ - u32 data; - - at93c_cycle_clk(at93c_reg_read()); - data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; - return data; -} - -static u8 at93c_read_byte(void) -{ - int i; - u8 data = 0; - - for (i = 0; i<=7; i++) { - data <<= 1; - data |= at93c_read_databit(); - } - return data; -} - -static void at93c_write_bits(u32 data, int size) -{ - int i; - int shift = size - 1; - u32 mask = (1 << shift); - - for (i = 0; i < size; i++) { - at93c_write_databit((data & mask) >> shift); - data <<= 1; - } -} - -static void at93c_init_op(void) -{ - at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift)); - lasat_ndelay(50); -} - -static void at93c_end_op(void) -{ - at93c_reg_write(at93c_reg_read() & ~at93c->cs); - lasat_ndelay(250); -} - -static void at93c_wait(void) -{ - at93c_init_op(); - while (!at93c_read_databit()) - ; - at93c_end_op(); -}; - -static void at93c_disable_wp(void) -{ - at93c_init_op(); - at93c_write_bits(AT93C_WENCMD, 10); - at93c_end_op(); -} - -static void at93c_enable_wp(void) -{ - at93c_init_op(); - at93c_write_bits(AT93C_WDSCMD, 10); - at93c_end_op(); -} - -u8 at93c_read(u8 addr) -{ - u8 byte; - at93c_init_op(); - at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); - byte = at93c_read_byte(); - at93c_end_op(); - return byte; -} - -void at93c_write(u8 addr, u8 data) -{ - at93c_disable_wp(); - at93c_init_op(); - at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); - at93c_write_bits(data, 8); - at93c_end_op(); - at93c_wait(); - at93c_enable_wp(); -} diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h deleted file mode 100644 index cfe2f99b1d44..000000000000 --- a/arch/mips/lasat/at93c.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Atmel AT93C46 serial eeprom driver - * - * Brian Murphy - * - */ - -extern struct at93c_defs { - volatile u32 *reg; - volatile u32 *rdata_reg; - int rdata_shift; - int wdata_shift; - u32 cs; - u32 clk; -} *at93c; - -u8 at93c_read(u8 addr); -void at93c_write(u8 addr, u8 data); diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c deleted file mode 100644 index 7dced67c55eb..000000000000 --- a/arch/mips/lasat/ds1603.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Dallas Semiconductors 1603 RTC driver - * - * Brian Murphy - * - */ -#include -#include -#include -#include -#include - -#include "ds1603.h" - -#define READ_TIME_CMD 0x81 -#define SET_TIME_CMD 0x80 -#define TRIMMER_SET_CMD 0xC0 -#define TRIMMER_VALUE_MASK 0x38 -#define TRIMMER_SHIFT 3 - -struct ds_defs *ds1603 = NULL; - -/* HW specific register functions */ -static void rtc_reg_write(unsigned long val) -{ - *ds1603->reg = val; -} - -static unsigned long rtc_reg_read(void) -{ - unsigned long tmp = *ds1603->reg; - return tmp; -} - -static unsigned long rtc_datareg_read(void) -{ - unsigned long tmp = *ds1603->data_reg; - return tmp; -} - -static void rtc_nrst_high(void) -{ - rtc_reg_write(rtc_reg_read() | ds1603->rst); -} - -static void rtc_nrst_low(void) -{ - rtc_reg_write(rtc_reg_read() & ~ds1603->rst); -} - -static void rtc_cycle_clock(unsigned long data) -{ - data |= ds1603->clk; - rtc_reg_write(data); - lasat_ndelay(250); - if (ds1603->data_reversed) - data &= ~ds1603->data; - else - data |= ds1603->data; - data &= ~ds1603->clk; - rtc_reg_write(data); - lasat_ndelay(250 + ds1603->huge_delay); -} - -static void rtc_write_databit(unsigned int bit) -{ - unsigned long data = rtc_reg_read(); - if (ds1603->data_reversed) - bit = !bit; - if (bit) - data |= ds1603->data; - else - data &= ~ds1603->data; - - rtc_reg_write(data); - lasat_ndelay(50 + ds1603->huge_delay); - rtc_cycle_clock(data); -} - -static unsigned int rtc_read_databit(void) -{ - unsigned int data; - - data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) - >> ds1603->data_read_shift; - rtc_cycle_clock(rtc_reg_read()); - return data; -} - -static void rtc_write_byte(unsigned int byte) -{ - int i; - - for (i = 0; i<=7; i++) { - rtc_write_databit(byte & 1L); - byte >>= 1; - } -} - -static void rtc_write_word(unsigned long word) -{ - int i; - - for (i = 0; i<=31; i++) { - rtc_write_databit(word & 1L); - word >>= 1; - } -} - -static unsigned long rtc_read_word(void) -{ - int i; - unsigned long word = 0; - unsigned long shift = 0; - - for (i = 0; i<=31; i++) { - word |= rtc_read_databit() << shift; - shift++; - } - return word; -} - -static void rtc_init_op(void) -{ - rtc_nrst_high(); - - rtc_reg_write(rtc_reg_read() & ~ds1603->clk); - - lasat_ndelay(50); -} - -static void rtc_end_op(void) -{ - rtc_nrst_low(); - lasat_ndelay(1000); -} - -/* interface */ -unsigned long ds1603_read(void) -{ - unsigned long word; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - rtc_init_op(); - rtc_write_byte(READ_TIME_CMD); - word = rtc_read_word(); - rtc_end_op(); - spin_unlock_irqrestore(&rtc_lock, flags); - return word; -} - -int ds1603_set(unsigned long time) -{ - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - rtc_init_op(); - rtc_write_byte(SET_TIME_CMD); - rtc_write_word(time); - rtc_end_op(); - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - -void ds1603_set_trimmer(unsigned int trimval) -{ - rtc_init_op(); - rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) - | (TRIMMER_SET_CMD)); - rtc_end_op(); -} - -void ds1603_disable(void) -{ - ds1603_set_trimmer(TRIMMER_DISABLE_RTC); -} - -void ds1603_enable(void) -{ - ds1603_set_trimmer(TRIMMER_DEFAULT); -} diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h deleted file mode 100644 index c2e5c76a379d..000000000000 --- a/arch/mips/lasat/ds1603.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Dallas Semiconductors 1603 RTC driver - * - * Brian Murphy - * - */ -#ifndef __DS1603_H -#define __DS1603_H - -struct ds_defs { - volatile u32 *reg; - volatile u32 *data_reg; - u32 rst; - u32 clk; - u32 data; - u32 data_read_shift; - char data_reversed; - u32 huge_delay; -}; - -extern struct ds_defs *ds1603; - -unsigned long ds1603_read(void); -int ds1603_set(unsigned long); -void ds1603_set_trimmer(unsigned int); -void ds1603_enable(void); -void ds1603_disable(void); -void ds1603_init(struct ds_defs *); - -#define TRIMMER_DEFAULT 3 -#define TRIMMER_DISABLE_RTC 0 - -#endif diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile deleted file mode 100644 index 35ecd6483ef6..000000000000 --- a/arch/mips/lasat/image/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER -# -# i-data Networks -# -# Author: Thomas Horsten -# - -ifndef Version - Version = "$(USER)-test" -endif - -MKLASATIMG = mklasatimg -MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 -KERNEL_IMAGE = $(TOPDIR)/vmlinux -KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ ) -KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) - -LDSCRIPT= -L$(obj) -Tromscript.normal - -HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \ - -D_kernel_entry=0x$(KERNEL_ENTRY) \ - -D VERSION="\"$(Version)\"" \ - -D TIMESTAMP=$(shell date +%s) - -$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE) - $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $< - -OBJECTS = head.o kImage.o - -rom.sw: $(obj)/rom.sw - -$(obj)/rom.sw: $(obj)/rom.bin - $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH) - -$(obj)/rom.bin: $(obj)/rom - $(OBJCOPY) -O binary -S $^ $@ - -# Rule to make the bootloader -$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS)) - $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^ - -$(obj)/%.o: $(obj)/%.gz - $(LD) -r -o $@ -b binary $< - -$(obj)/%.gz: $(obj)/%.bin - gzip -cf -9 $< > $@ - -$(obj)/kImage.bin: $(KERNEL_IMAGE) - $(OBJCOPY) -O binary -S $^ $@ - -clean: - rm -f rom rom.bin rom.sw kImage.bin kImage.o diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S deleted file mode 100644 index efb95f2609c2..000000000000 --- a/arch/mips/lasat/image/head.S +++ /dev/null @@ -1,31 +0,0 @@ -#include - - .text - .section .text.start, "ax" - .set noreorder - .set mips3 - - /* Magic words identifying a software image */ - .word LASAT_K_MAGIC0_VAL - .word LASAT_K_MAGIC1_VAL - - /* Image header version */ - .word 0x00000002 - - /* image start and size */ - .word _image_start - .word _image_size - - /* start of kernel and entrypoint in uncompressed image */ - .word _kernel_start - .word _kernel_entry - - /* Here we have room for future flags */ - - .org 0x40 -reldate: - .word TIMESTAMP - - .org 0x50 -release: - .string VERSION diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal deleted file mode 100644 index 988f8ad189cb..000000000000 --- a/arch/mips/lasat/image/romscript.normal +++ /dev/null @@ -1,23 +0,0 @@ -OUTPUT_ARCH(mips) - -SECTIONS -{ - .text : - { - *(.text.start) - } - - /* Data in ROM */ - - .data ALIGN(0x10) : - { - *(.data) - } - _image_start = ADDR(.data); - _image_size = SIZEOF(.data); - - .other : - { - *(.*) - } -} diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c deleted file mode 100644 index 9a622b9a1051..000000000000 --- a/arch/mips/lasat/interrupt.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Routines for generic manipulation of the interrupts found on the - * Lasat boards. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static volatile int *lasat_int_status = NULL; -static volatile int *lasat_int_mask = NULL; -static volatile int lasat_int_mask_shift; - -void disable_lasat_irq(unsigned int irq_nr) -{ - *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; -} - -void enable_lasat_irq(unsigned int irq_nr) -{ - *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; -} - -static struct irq_chip lasat_irq_type = { - .name = "Lasat", - .ack = disable_lasat_irq, - .mask = disable_lasat_irq, - .mask_ack = disable_lasat_irq, - .unmask = enable_lasat_irq, -}; - -static inline int ls1bit32(unsigned int x) -{ - int b = 31, s; - - s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; - s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; - s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; - s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; - s = 1; if (x << 1 == 0) s = 0; b -= s; - - return b; -} - -static unsigned long (* get_int_status)(void); - -static unsigned long get_int_status_100(void) -{ - return *lasat_int_status & *lasat_int_mask; -} - -static unsigned long get_int_status_200(void) -{ - unsigned long int_status; - - int_status = *lasat_int_status; - int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; - return int_status; -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long int_status; - unsigned int cause = read_c0_cause(); - int irq; - - if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ - ll_timer_interrupt(7); - return; - } - - int_status = get_int_status(); - - /* if int_status == 0, then the interrupt has already been cleared */ - if (int_status) { - irq = ls1bit32(int_status); - - do_IRQ(irq); - } -} - -void __init arch_init_irq(void) -{ - int i; - - switch (mips_machtype) { - case MACH_LASAT_100: - lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; - lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; - lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; - get_int_status = get_int_status_100; - *lasat_int_mask = 0; - break; - case MACH_LASAT_200: - lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; - lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; - lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; - get_int_status = get_int_status_200; - *lasat_int_mask &= 0xffff; - break; - default: - panic("arch_init_irq: mips_machtype incorrect"); - } - - for (i = 0; i <= LASATINT_END; i++) - set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); -} diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c deleted file mode 100644 index fbe9a87bd0ad..000000000000 --- a/arch/mips/lasat/lasat_board.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Thomas Horsten - * Copyright (C) 2000 LASAT Networks A/S. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Routines specific to the LASAT boards - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "at93c.h" -/* New model description table */ -#include "lasat_models.h" - -#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len)) - -struct lasat_info lasat_board_info; - -void update_bcastaddr(void); - -int EEPROMRead(unsigned int pos, unsigned char *data, int len) -{ - int i; - - for (i=0; i 0x200000) { - ls[LASAT_MTD_CONFIG] = 0x100000; - ls[LASAT_MTD_FS] = 0x500000; - } - } else { - lasat_board_info.li_flash_base = 0x10000000; - - if (lasat_board_info.li_flash_size < 0x1000000) { - lb[LASAT_MTD_BOOTLOADER] = 0x10000000; - ls[LASAT_MTD_CONFIG] = 0x100000; - if (lasat_board_info.li_flash_size >= 0x400000) { - ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; - } - } - } - - for (i = 1; i < LASAT_MTD_LAST; i++) - lb[i] = lb[i-1] + ls[i-1]; -} - -int lasat_init_board_info(void) -{ - int c; - unsigned long crc; - unsigned long cfg0, cfg1; - const product_info_t *ppi; - int i_n_base_models = N_BASE_MODELS; - const char * const * i_txt_base_models = txt_base_models; - int i_n_prids = N_PRIDS; - - memset(&lasat_board_info, 0, sizeof(lasat_board_info)); - - /* First read the EEPROM info */ - EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, - sizeof(struct lasat_eeprom_struct)); - - /* Check the CRC */ - crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), - sizeof(struct lasat_eeprom_struct) - 4); - - if (crc != lasat_board_info.li_eeprom_info.crc32) { - printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does " - "not match calculated, attempting to soldier on...\n"); - } - - if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) { - printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version " - "%d, wanted version %d, attempting to soldier on...\n", - (unsigned int)lasat_board_info.li_eeprom_info.version, - LASAT_EEPROM_VERSION); - } - - cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; - cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; - - if ( LASAT_W0_DSCTYPE(cfg0) != 1) { - printk(KERN_WARNING "WARNING...\nWARNING...\n" - "Invalid configuration read from EEPROM, attempting to " - "soldier on..."); - } - /* We have a valid configuration */ - - switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { - case 0: - lasat_board_info.li_memsize = 0x0800000; - break; - case 1: - lasat_board_info.li_memsize = 0x1000000; - break; - case 2: - lasat_board_info.li_memsize = 0x2000000; - break; - case 3: - lasat_board_info.li_memsize = 0x4000000; - break; - case 4: - lasat_board_info.li_memsize = 0x8000000; - break; - default: - lasat_board_info.li_memsize = 0; - } - - switch (LASAT_W0_SDRAMBANKS(cfg0)) { - case 0: - break; - case 1: - lasat_board_info.li_memsize *= 2; - break; - default: - break; - } - - switch (LASAT_W0_BUSSPEED(cfg0)) { - case 0x0: - lasat_board_info.li_bus_hz = 60000000; - break; - case 0x1: - lasat_board_info.li_bus_hz = 66000000; - break; - case 0x2: - lasat_board_info.li_bus_hz = 66666667; - break; - case 0x3: - lasat_board_info.li_bus_hz = 80000000; - break; - case 0x4: - lasat_board_info.li_bus_hz = 83333333; - break; - case 0x5: - lasat_board_info.li_bus_hz = 100000000; - break; - } - - switch (LASAT_W0_CPUCLK(cfg0)) { - case 0x0: - lasat_board_info.li_cpu_hz = - lasat_board_info.li_bus_hz; - break; - case 0x1: - lasat_board_info.li_cpu_hz = - lasat_board_info.li_bus_hz + - (lasat_board_info.li_bus_hz >> 1); - break; - case 0x2: - lasat_board_info.li_cpu_hz = - lasat_board_info.li_bus_hz + - lasat_board_info.li_bus_hz; - break; - case 0x3: - lasat_board_info.li_cpu_hz = - lasat_board_info.li_bus_hz + - lasat_board_info.li_bus_hz + - (lasat_board_info.li_bus_hz >> 1); - break; - case 0x4: - lasat_board_info.li_cpu_hz = - lasat_board_info.li_bus_hz + - lasat_board_info.li_bus_hz + - lasat_board_info.li_bus_hz; - break; - } - - /* Flash size */ - switch (LASAT_W1_FLASHSIZE(cfg1)) { - case 0: - lasat_board_info.li_flash_size = 0x200000; - break; - case 1: - lasat_board_info.li_flash_size = 0x400000; - break; - case 2: - lasat_board_info.li_flash_size = 0x800000; - break; - case 3: - lasat_board_info.li_flash_size = 0x1000000; - break; - case 4: - lasat_board_info.li_flash_size = 0x2000000; - break; - } - - init_flash_sizes(); - - lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); - lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; - if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) - lasat_board_info.li_prid = lasat_board_info.li_bmid; - - /* Base model stuff */ - if (lasat_board_info.li_bmid > i_n_base_models) - lasat_board_info.li_bmid = i_n_base_models; - strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]); - - /* Product ID dependent values */ - c = lasat_board_info.li_prid; - if (c >= i_n_prids) { - strcpy(lasat_board_info.li_namestr, "Unknown Model"); - strcpy(lasat_board_info.li_typestr, "Unknown Type"); - } else { - ppi = &vendor_info_table[0].vi_product_info[c]; - strcpy(lasat_board_info.li_namestr, ppi->pi_name); - if (ppi->pi_type) - strcpy(lasat_board_info.li_typestr, ppi->pi_type); - else - sprintf(lasat_board_info.li_typestr, "%d",10*c); - } - -#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) - update_bcastaddr(); -#endif - - return 0; -} - -void lasat_write_eeprom_info(void) -{ - unsigned long crc; - - /* Generate the CRC */ - crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), - sizeof(struct lasat_eeprom_struct) - 4); - lasat_board_info.li_eeprom_info.crc32 = crc; - - /* Write the EEPROM info */ - EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, - sizeof(struct lasat_eeprom_struct)); -} - diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h deleted file mode 100644 index ae0c5d0bd403..000000000000 --- a/arch/mips/lasat/lasat_models.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Model description tables - */ - -typedef struct product_info_t { - const char *pi_name; - const char *pi_type; -} product_info_t; - -typedef struct vendor_info_t { - const char *vi_name; - const product_info_t *vi_product_info; -} vendor_info_t; - -/* - * Base models - */ -static const char * const txt_base_models[] = { - "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown" -}; -#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1) - -/* - * Eicon Networks - */ -static const char txt_en_mq[] = "Masquerade"; -static const char txt_en_sp[] = "Safepipe"; - -static const product_info_t product_info_eicon[] = { - { txt_en_mq, "II" }, /* 0 */ - { txt_en_mq, "Pro" }, /* 1 */ - { txt_en_sp, "25" }, /* 2 */ - { txt_en_sp, "50" }, /* 3 */ - { txt_en_sp, "100" }, /* 4 */ - { txt_en_sp, "5000" }, /* 5 */ - { txt_en_sp, "7000" }, /* 6 */ - { txt_en_sp, "30" }, /* 7 */ - { txt_en_sp, "5100" }, /* 8 */ - { txt_en_sp, "7100" }, /* 9 */ - { txt_en_sp, "1110" }, /* 10 */ - { txt_en_sp, "3020" }, /* 11 */ - { txt_en_sp, "3030" }, /* 12 */ - { txt_en_sp, "5020" }, /* 13 */ - { txt_en_sp, "5030" }, /* 14 */ - { txt_en_sp, "1120" }, /* 15 */ - { txt_en_sp, "1130" }, /* 16 */ - { txt_en_sp, "6010" }, /* 17 */ - { txt_en_sp, "6110" }, /* 18 */ - { txt_en_sp, "6210" }, /* 19 */ - { txt_en_sp, "1020" }, /* 20 */ - { txt_en_sp, "1040" }, /* 21 */ - { txt_en_sp, "1050" }, /* 22 */ - { txt_en_sp, "1060" }, /* 23 */ -}; -#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t)) - -/* - * The vendor table - */ -static vendor_info_t const vendor_info_table[] = { - { "Eicon Networks", product_info_eicon }, -}; -#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t)) diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c deleted file mode 100644 index 9ae82c3ffb07..000000000000 --- a/arch/mips/lasat/picvue.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Picvue PVC160206 display driver - * - * Brian Murphy - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "picvue.h" - -#define PVC_BUSY 0x80 -#define PVC_NLINES 2 -#define PVC_DISPMEM 80 -#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES - -struct pvc_defs *picvue = NULL; - -DECLARE_MUTEX(pvc_sem); - -static void pvc_reg_write(u32 val) -{ - *picvue->reg = val; -} - -static u32 pvc_reg_read(void) -{ - u32 tmp = *picvue->reg; - return tmp; -} - -static void pvc_write_byte(u32 data, u8 byte) -{ - data |= picvue->e; - pvc_reg_write(data); - data &= ~picvue->data_mask; - data |= byte << picvue->data_shift; - pvc_reg_write(data); - ndelay(220); - pvc_reg_write(data & ~picvue->e); - ndelay(220); -} - -static u8 pvc_read_byte(u32 data) -{ - u8 byte; - - data |= picvue->e; - pvc_reg_write(data); - ndelay(220); - byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; - data &= ~picvue->e; - pvc_reg_write(data); - ndelay(220); - return byte; -} - -static u8 pvc_read_data(void) -{ - u32 data = pvc_reg_read(); - u8 byte; - data |= picvue->rw; - data &= ~picvue->rs; - pvc_reg_write(data); - ndelay(40); - byte = pvc_read_byte(data); - data |= picvue->rs; - pvc_reg_write(data); - return byte; -} - -#define TIMEOUT 1000 -static int pvc_wait(void) -{ - int i = TIMEOUT; - int err = 0; - - while ((pvc_read_data() & PVC_BUSY) && i) - i--; - if (i == 0) - err = -ETIME; - - return err; -} - -#define MODE_INST 0 -#define MODE_DATA 1 -static void pvc_write(u8 byte, int mode) -{ - u32 data = pvc_reg_read(); - data &= ~picvue->rw; - if (mode == MODE_DATA) - data |= picvue->rs; - else - data &= ~picvue->rs; - pvc_reg_write(data); - ndelay(40); - pvc_write_byte(data, byte); - if (mode == MODE_DATA) - data &= ~picvue->rs; - else - data |= picvue->rs; - pvc_reg_write(data); - pvc_wait(); -} - -void pvc_write_string(const unsigned char *str, u8 addr, int line) -{ - int i = 0; - - if (line > 0 && (PVC_NLINES > 1)) - addr += 0x40 * line; - pvc_write(0x80 | addr, MODE_INST); - - while (*str != 0 && i < PVC_LINELEN) { - pvc_write(*str++, MODE_DATA); - i++; - } -} - -void pvc_write_string_centered(const unsigned char *str, int line) -{ - int len = strlen(str); - u8 addr; - - if (len > PVC_VISIBLE_CHARS) - addr = 0; - else - addr = (PVC_VISIBLE_CHARS - strlen(str))/2; - - pvc_write_string(str, addr, line); -} - -void pvc_dump_string(const unsigned char *str) -{ - int len = strlen(str); - - pvc_write_string(str, 0, 0); - if (len > PVC_VISIBLE_CHARS) - pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); -} - -#define BM_SIZE 8 -#define MAX_PROGRAMMABLE_CHARS 8 -int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) -{ - int i; - int addr; - - if (charnum > MAX_PROGRAMMABLE_CHARS) - return -ENOENT; - - addr = charnum * 8; - pvc_write(0x40 | addr, MODE_INST); - - for (i=0; i - * - */ -#include - -struct pvc_defs { - volatile u32 *reg; - u32 data_shift; - u32 data_mask; - u32 e; - u32 rw; - u32 rs; -}; - -extern struct pvc_defs *picvue; - -#define PVC_NLINES 2 -#define PVC_DISPMEM 80 -#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES -#define PVC_VISIBLE_CHARS 16 - -void pvc_write_string(const unsigned char *str, u8 addr, int line); -void pvc_write_string_centered(const unsigned char *str, int line); -void pvc_dump_string(const unsigned char *str); - -#define BM_SIZE 8 -#define MAX_PROGRAMMABLE_CHARS 8 -int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); - -void pvc_dispcnt(u8 cmd); -#define DISP_OFF 0 -#define DISP_ON (1 << 2) -#define CUR_ON (1 << 1) -#define CUR_BLINK (1 << 0) - -void pvc_move(u8 cmd); -#define DISPLAY (1 << 3) -#define CURSOR 0 -#define RIGHT (1 << 2) -#define LEFT 0 - -void pvc_clear(void); -void pvc_home(void); - -extern struct semaphore pvc_sem; diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c deleted file mode 100644 index cce7cddcdb08..000000000000 --- a/arch/mips/lasat/picvue_proc.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Picvue PVC160206 display driver - * - * Brian Murphy - * - */ -#include -#include -#include -#include - -#include -#include - -#include - -#include "picvue.h" - -static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; -static int pvc_linedata[PVC_NLINES]; -static struct proc_dir_entry *pvc_display_dir; -static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; -#define DISPLAY_DIR_NAME "display" -static int scroll_dir = 0, scroll_interval = 0; - -static struct timer_list timer; - -static void pvc_display(unsigned long data) { - int i; - - pvc_clear(); - for (i=0; i PVC_NLINES) { - printk("proc_read_line: invalid lineno %d\n", lineno); - return 0; - } - - down(&pvc_sem); - page += sprintf(page, "%s\n", pvc_lines[lineno]); - up(&pvc_sem); - - return page - origpage; -} - -static int pvc_proc_write_line(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int origcount = count; - int lineno = *(int *)data; - - if (lineno < 0 || lineno > PVC_NLINES) { - printk("proc_write_line: invalid lineno %d\n", lineno); - return origcount; - } - - if (count > PVC_LINELEN) - count = PVC_LINELEN; - - if (buffer[count-1] == '\n') - count--; - - down(&pvc_sem); - strncpy(pvc_lines[lineno], buffer, count); - pvc_lines[lineno][count] = '\0'; - up(&pvc_sem); - - tasklet_schedule(&pvc_display_tasklet); - - return origcount; -} - -static int pvc_proc_write_scroll(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - int origcount = count; - int cmd = simple_strtol(buffer, NULL, 10); - - down(&pvc_sem); - if (scroll_interval != 0) - del_timer(&timer); - - if (cmd == 0) { - scroll_dir = 0; - scroll_interval = 0; - } else { - if (cmd < 0) { - scroll_dir = -1; - scroll_interval = -cmd; - } else { - scroll_dir = 1; - scroll_interval = cmd; - } - add_timer(&timer); - } - up(&pvc_sem); - - return origcount; -} - -static int pvc_proc_read_scroll(char *page, char **start, - off_t off, int count, - int *eof, void *data) -{ - char *origpage = page; - - down(&pvc_sem); - page += sprintf(page, "%d\n", scroll_dir * scroll_interval); - up(&pvc_sem); - - return page - origpage; -} - - -void pvc_proc_timerfunc(unsigned long data) -{ - if (scroll_dir < 0) - pvc_move(DISPLAY|RIGHT); - else if (scroll_dir > 0) - pvc_move(DISPLAY|LEFT); - - timer.expires = jiffies + scroll_interval; - add_timer(&timer); -} - -static void pvc_proc_cleanup(void) -{ - int i; - for (i=0; iread_proc = pvc_proc_read_line; - proc_entry->write_proc = pvc_proc_write_line; - proc_entry->data = &pvc_linedata[i]; - } - proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); - if (proc_entry == NULL) - goto error; - proc_entry->write_proc = pvc_proc_write_scroll; - proc_entry->read_proc = pvc_proc_read_scroll; - - init_timer(&timer); - timer.function = pvc_proc_timerfunc; - - return 0; -error: - pvc_proc_cleanup(); - return -ENOMEM; -} - -module_init(pvc_proc_init); -module_exit(pvc_proc_cleanup); -MODULE_LICENSE("GPL"); diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c deleted file mode 100644 index 812c6ac366be..000000000000 --- a/arch/mips/lasat/prom.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * PROM interface routines. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "at93c.h" -#include -#include "prom.h" - -#define RESET_VECTOR 0xbfc00000 -#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) -#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) -#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) -#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) - -static void null_prom_display(const char *string, int pos, int clear) -{ -} - -static void null_prom_monitor(void) -{ -} - -static void null_prom_putc(char c) -{ -} - -/* these are functions provided by the bootloader */ -static void (* __prom_putc)(char c) = null_prom_putc; - -void prom_putchar(char c) -{ - __prom_putc(c); -} - -void (* prom_display)(const char *string, int pos, int clear) = - null_prom_display; -void (* prom_monitor)(void) = null_prom_monitor; - -unsigned int lasat_ndelay_divider; - -static void setup_prom_vectors(void) -{ - u32 version = *(u32 *)(RESET_VECTOR + 0x90); - - if (version >= 307) { - prom_display = (void *)PROM_DISPLAY_ADDR; - __prom_putc = (void *)PROM_PUTC_ADDR; - prom_monitor = (void *)PROM_MONITOR_ADDR; - } - printk("prom vectors set up\n"); -} - -static struct at93c_defs at93c_defs[N_MACHTYPES] = { - {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100, - AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100}, - {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200, - AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200}, -}; - -void __init prom_init(void) -{ - int argc = fw_arg0; - char **argv = (char **) fw_arg1; - - setup_prom_vectors(); - - if (current_cpu_data.cputype == CPU_R5000) { - printk("LASAT 200 board\n"); - mips_machtype = MACH_LASAT_200; - lasat_ndelay_divider = LASAT_200_DIVIDER; - } else { - printk("LASAT 100 board\n"); - mips_machtype = MACH_LASAT_100; - lasat_ndelay_divider = LASAT_100_DIVIDER; - } - - at93c = &at93c_defs[mips_machtype]; - - lasat_init_board_info(); /* Read info from EEPROM */ - - mips_machgroup = MACH_GROUP_LASAT; - - /* Get the command line */ - if (argc > 0) { - strncpy(arcs_cmdline, argv[0], CL_SIZE-1); - arcs_cmdline[CL_SIZE-1] = '\0'; - } - - /* Set the I/O base address */ - set_io_port_base(KSEG1); - - /* Set memory regions */ - ioport_resource.start = 0; - ioport_resource.end = 0xffffffff; /* Wrong, fixme. */ - - add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} - -const char *get_system_type(void) -{ - return lasat_board_info.li_bmstr; -} diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h deleted file mode 100644 index 019d45fbd268..000000000000 --- a/arch/mips/lasat/prom.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef PROM_H -#define PROM_H -extern void (* prom_display)(const char *string, int pos, int clear); -extern void (* prom_monitor)(void); -#endif diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c deleted file mode 100644 index 9e22acf03083..000000000000 --- a/arch/mips/lasat/reset.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Thomas Horsten - * Copyright (C) 2000 LASAT Networks A/S. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Reset the LASAT board. - */ -#include -#include - -#include -#include -#include - -#include "picvue.h" -#include "prom.h" - -static void lasat_machine_restart(char *command); -static void lasat_machine_halt(void); - -/* Used to set machine to boot in service mode via /proc interface */ -int lasat_boot_to_service = 0; - -static void lasat_machine_restart(char *command) -{ - local_irq_disable(); - - if (lasat_boot_to_service) { - printk("machine_restart: Rebooting to service mode\n"); - *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; - *(volatile unsigned int *)0xa00000fc = 0xfedeabba; - } - *lasat_misc->reset_reg = 0xbedead; - for (;;) ; -} - -#define MESSAGE "System halted" -static void lasat_machine_halt(void) -{ - local_irq_disable(); - - /* Disable interrupts and loop forever */ - printk(KERN_NOTICE MESSAGE "\n"); -#ifdef CONFIG_PICVUE - pvc_clear(); - pvc_write_string(MESSAGE, 0, 0); -#endif - prom_monitor(); - for (;;) ; -} - -void lasat_reboot_setup(void) -{ - _machine_restart = lasat_machine_restart; - _machine_halt = lasat_machine_halt; - pm_power_off = lasat_machine_halt; -} diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c deleted file mode 100644 index 488007f13988..000000000000 --- a/arch/mips/lasat/setup.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. - * - * Thomas Horsten - * Copyright (C) 2000 LASAT Networks A/S. - * - * Brian Murphy - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Lasat specific setup. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PICVUE -#include -#endif - -#include "ds1603.h" -#include -#include -#include - -#include "prom.h" - -int lasat_command_line = 0; -void lasatint_init(void); - -extern void lasat_reboot_setup(void); -extern void pcisetup(void); -extern void edhac_init(void *, void *, void *); -extern void addrflt_init(void); - -struct lasat_misc lasat_misc_info[N_MACHTYPES] = { - {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2}, - {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6} -}; - -struct lasat_misc *lasat_misc = NULL; - -#ifdef CONFIG_DS1603 -static struct ds_defs ds_defs[N_MACHTYPES] = { - { (void *)DS1603_REG_100, (void *)DS1603_REG_100, - DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, - DS1603_DATA_SHIFT_100, 0, 0 }, - { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, - DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, - DS1603_DATA_READ_SHIFT_200, 1, 2000 } -}; -#endif - -#ifdef CONFIG_PICVUE -#include "picvue.h" -static struct pvc_defs pvc_defs[N_MACHTYPES] = { - { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, - PVC_E_100, PVC_RW_100, PVC_RS_100 }, - { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, - PVC_E_200, PVC_RW_200, PVC_RS_200 } -}; -#endif - -static int lasat_panic_display(struct notifier_block *this, - unsigned long event, void *ptr) -{ -#ifdef CONFIG_PICVUE - unsigned char *string = ptr; - if (string == NULL) - string = "Kernel Panic"; - pvc_dump_string(string); -#endif - return NOTIFY_DONE; -} - -static int lasat_panic_prom_monitor(struct notifier_block *this, - unsigned long event, void *ptr) -{ - prom_monitor(); - return NOTIFY_DONE; -} - -static struct notifier_block lasat_panic_block[] = -{ - { lasat_panic_display, NULL, INT_MAX }, - { lasat_panic_prom_monitor, NULL, INT_MIN } -}; - -static void lasat_time_init(void) -{ - mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; -} - -void __init plat_timer_setup(struct irqaction *irq) -{ - change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); -} - -#define DYNAMIC_SERIAL_INIT -#ifdef DYNAMIC_SERIAL_INIT -void __init serial_init(void) -{ -#ifdef CONFIG_SERIAL_8250 - struct uart_port s; - - memset(&s, 0, sizeof(s)); - - s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; - s.iotype = UPIO_MEM; - - if (mips_machtype == MACH_LASAT_100) { - s.uartclk = LASAT_BASE_BAUD_100 * 16; - s.irq = LASATINT_UART_100; - s.regshift = LASAT_UART_REGS_SHIFT_100; - s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_100); - } else { - s.uartclk = LASAT_BASE_BAUD_200 * 16; - s.irq = LASATINT_UART_200; - s.regshift = LASAT_UART_REGS_SHIFT_200; - s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_200); - } - - if (early_serial_setup(&s) != 0) - printk(KERN_ERR "Serial setup failed!\n"); -#endif -} -#endif - -void __init plat_mem_setup(void) -{ - int i; - lasat_misc = &lasat_misc_info[mips_machtype]; -#ifdef CONFIG_PICVUE - picvue = &pvc_defs[mips_machtype]; -#endif - - /* Set up panic notifier */ - for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) - atomic_notifier_chain_register(&panic_notifier_list, - &lasat_panic_block[i]); - - lasat_reboot_setup(); - - board_time_init = lasat_time_init; - -#ifdef CONFIG_DS1603 - ds1603 = &ds_defs[mips_machtype]; - rtc_mips_get_time = ds1603_read; - rtc_mips_set_time = ds1603_set; -#endif - -#ifdef DYNAMIC_SERIAL_INIT - serial_init(); -#endif - /* Switch from prom exception handler to normal mode */ - change_c0_status(ST0_BEV,0); - - pr_info("Lasat specific initialization complete\n"); -} diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c deleted file mode 100644 index 699ab1886ceb..000000000000 --- a/arch/mips/lasat/sysctl.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Thomas Horsten - * Copyright (C) 2000 LASAT Networks A/S. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Routines specific to the LASAT boards - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysctl.h" -#include "ds1603.h" - -static DEFINE_MUTEX(lasat_info_mutex); - -/* Strategy function to write EEPROM after changing string entry */ -int sysctl_lasatstring(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen) -{ - int r; - mutex_lock(&lasat_info_mutex); - r = sysctl_string(table, name, - nlen, oldval, oldlenp, newval, newlen); - if (r < 0) { - mutex_unlock(&lasat_info_mutex); - return r; - } - if (newval && newlen) { - lasat_write_eeprom_info(); - } - mutex_unlock(&lasat_info_mutex); - return 1; -} - - -/* And the same for proc */ -int proc_dolasatstring(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) -{ - int r; - mutex_lock(&lasat_info_mutex); - r = proc_dostring(table, write, filp, buffer, lenp, ppos); - if ( (!write) || r) { - mutex_unlock(&lasat_info_mutex); - return r; - } - lasat_write_eeprom_info(); - mutex_unlock(&lasat_info_mutex); - return 0; -} - -/* proc function to write EEPROM after changing int entry */ -int proc_dolasatint(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) -{ - int r; - mutex_lock(&lasat_info_mutex); - r = proc_dointvec(table, write, filp, buffer, lenp, ppos); - if ( (!write) || r) { - mutex_unlock(&lasat_info_mutex); - return r; - } - lasat_write_eeprom_info(); - mutex_unlock(&lasat_info_mutex); - return 0; -} - -static int rtctmp; - -#ifdef CONFIG_DS1603 -/* proc function to read/write RealTime Clock */ -int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) -{ - int r; - mutex_lock(&lasat_info_mutex); - if (!write) { - rtctmp = ds1603_read(); - /* check for time < 0 and set to 0 */ - if (rtctmp < 0) - rtctmp = 0; - } - r = proc_dointvec(table, write, filp, buffer, lenp, ppos); - if ( (!write) || r) { - mutex_unlock(&lasat_info_mutex); - return r; - } - ds1603_set(rtctmp); - mutex_unlock(&lasat_info_mutex); - return 0; -} -#endif - -/* Sysctl for setting the IP addresses */ -int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen) -{ - int r; - mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); - if (r < 0) { - mutex_unlock(&lasat_info_mutex); - return r; - } - if (newval && newlen) { - lasat_write_eeprom_info(); - } - mutex_unlock(&lasat_info_mutex); - return 1; -} - -#ifdef CONFIG_DS1603 -/* Same for RTC */ -int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen) -{ - int r; - mutex_lock(&lasat_info_mutex); - rtctmp = ds1603_read(); - if (rtctmp < 0) - rtctmp = 0; - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); - if (r < 0) { - mutex_unlock(&lasat_info_mutex); - return r; - } - if (newval && newlen) { - ds1603_set(rtctmp); - } - mutex_unlock(&lasat_info_mutex); - return 1; -} -#endif - -#ifdef CONFIG_INET -static char lasat_bcastaddr[16]; - -void update_bcastaddr(void) -{ - unsigned int ip; - - ip = (lasat_board_info.li_eeprom_info.ipaddr & - lasat_board_info.li_eeprom_info.netmask) | - ~lasat_board_info.li_eeprom_info.netmask; - - sprintf(lasat_bcastaddr, "%d.%d.%d.%d", - (ip ) & 0xff, - (ip >> 8) & 0xff, - (ip >> 16) & 0xff, - (ip >> 24) & 0xff); -} - -static char proc_lasat_ipbuf[32]; -/* Parsing of IP address */ -int proc_lasat_ip(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) -{ - int len; - unsigned int ip; - char *p, c; - - if (!table->data || !table->maxlen || !*lenp || - (*ppos && !write)) { - *lenp = 0; - return 0; - } - - mutex_lock(&lasat_info_mutex); - if (write) { - len = 0; - p = buffer; - while (len < *lenp) { - if(get_user(c, p++)) { - mutex_unlock(&lasat_info_mutex); - return -EFAULT; - } - if (c == 0 || c == '\n') - break; - len++; - } - if (len >= sizeof(proc_lasat_ipbuf)-1) - len = sizeof(proc_lasat_ipbuf) - 1; - if (copy_from_user(proc_lasat_ipbuf, buffer, len)) - { - mutex_unlock(&lasat_info_mutex); - return -EFAULT; - } - proc_lasat_ipbuf[len] = 0; - *ppos += *lenp; - /* Now see if we can convert it to a valid IP */ - ip = in_aton(proc_lasat_ipbuf); - *(unsigned int *)(table->data) = ip; - lasat_write_eeprom_info(); - } else { - ip = *(unsigned int *)(table->data); - sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", - (ip ) & 0xff, - (ip >> 8) & 0xff, - (ip >> 16) & 0xff, - (ip >> 24) & 0xff); - len = strlen(proc_lasat_ipbuf); - if (len > *lenp) - len = *lenp; - if (len) - if(copy_to_user(buffer, proc_lasat_ipbuf, len)) { - mutex_unlock(&lasat_info_mutex); - return -EFAULT; - } - if (len < *lenp) { - if(put_user('\n', ((char *) buffer) + len)) { - mutex_unlock(&lasat_info_mutex); - return -EFAULT; - } - len++; - } - *lenp = len; - *ppos += len; - } - update_bcastaddr(); - mutex_unlock(&lasat_info_mutex); - return 0; -} -#endif /* defined(CONFIG_INET) */ - -static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen) -{ - int r; - - mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); - if (r < 0) { - mutex_unlock(&lasat_info_mutex); - return r; - } - - if (newval && newlen) - { - if (name && *name == LASAT_PRID) - lasat_board_info.li_eeprom_info.prid = *(int*)newval; - - lasat_write_eeprom_info(); - lasat_init_board_info(); - } - mutex_unlock(&lasat_info_mutex); - - return 0; -} - -int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp, loff_t *ppos) -{ - int r; - mutex_lock(&lasat_info_mutex); - r = proc_dointvec(table, write, filp, buffer, lenp, ppos); - if ( (!write) || r) { - mutex_unlock(&lasat_info_mutex); - return r; - } - if (filp && filp->f_path.dentry) - { - if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) - lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; - if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) - lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; - } - lasat_write_eeprom_info(); - mutex_unlock(&lasat_info_mutex); - return 0; -} - -extern int lasat_boot_to_service; - -#ifdef CONFIG_SYSCTL - -static ctl_table lasat_table[] = { - { - .ctl_name = CTL_UNNUMBERED, - .procname = "cpu-hz", - .data = &lasat_board_info.li_cpu_hz, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "bus-hz", - .data = &lasat_board_info.li_bus_hz, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "bmid", - .data = &lasat_board_info.li_bmid, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "prid", - .data = &lasat_board_info.li_prid, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_lasat_eeprom_value, - .strategy = &sysctl_lasat_eeprom_value - }, -#ifdef CONFIG_INET - { - .ctl_name = CTL_UNNUMBERED, - .procname = "ipaddr", - .data = &lasat_board_info.li_eeprom_info.ipaddr, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_lasat_ip, - .strategy = &sysctl_lasat_intvec - }, - { - .ctl_name = LASAT_NETMASK, - .procname = "netmask", - .data = &lasat_board_info.li_eeprom_info.netmask, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_lasat_ip, - .strategy = &sysctl_lasat_intvec - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "bcastaddr", - .data = &lasat_bcastaddr, - .maxlen = sizeof(lasat_bcastaddr), - .mode = 0600, - .proc_handler = &proc_dostring, - .strategy = &sysctl_string - }, -#endif - { - .ctl_name = CTL_UNNUMBERED, - .procname = "passwd_hash", - .data = &lasat_board_info.li_eeprom_info.passwd_hash, - .maxlen = sizeof(lasat_board_info.li_eeprom_info.passwd_hash), - .mode = 0600, - .proc_handler = &proc_dolasatstring, - .strategy = &sysctl_lasatstring - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "boot-service", - .data = &lasat_boot_to_service, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec - }, -#ifdef CONFIG_DS1603 - { - .ctl_name = CTL_UNNUMBERED, - .procname = "rtc", - .data = &rtctmp, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dolasatrtc, - .strategy = &sysctl_lasat_rtc - }, -#endif - { - .ctl_name = CTL_UNNUMBERED, - .procname = "namestr", - .data = &lasat_board_info.li_namestr, - .maxlen = sizeof(lasat_board_info.li_namestr), - .mode = 0444, - .proc_handler = &proc_dostring, - .strategy = &sysctl_string - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "typestr", - .data = &lasat_board_info.li_typestr, - .maxlen = sizeof(lasat_board_info.li_typestr), - .mode = 0444, - .proc_handler = &proc_dostring, - .strategy = &sysctl_string - }, - {} -}; - -static ctl_table lasat_root_table[] = { - { - .ctl_name = CTL_UNNUMBERED, - .procname = "lasat", - .mode = 0555, - .child = lasat_table - }, - {} -}; - -static int __init lasat_register_sysctl(void) -{ - struct ctl_table_header *lasat_table_header; - - lasat_table_header = - register_sysctl_table(lasat_root_table); - - return 0; -} - -__initcall(lasat_register_sysctl); -#endif /* CONFIG_SYSCTL */ diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h deleted file mode 100644 index 4d139d2adbdf..000000000000 --- a/arch/mips/lasat/sysctl.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * LASAT sysctl values - */ - -#ifndef _LASAT_SYSCTL_H -#define _LASAT_SYSCTL_H - -/* /proc/sys/lasat */ -enum { - LASAT_CPU_HZ=1, - LASAT_BUS_HZ, - LASAT_MODEL, - LASAT_PRID, - LASAT_IPADDR, - LASAT_NETMASK, - LASAT_BCAST, - LASAT_PASSWORD, - LASAT_SBOOT, - LASAT_RTC, - LASAT_NAMESTR, - LASAT_TYPESTR, -}; - -#endif /* _LASAT_SYSCTL_H */ diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c5845db55984..cfebf58c8dc6 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o -obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o @@ -22,7 +21,6 @@ obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o # obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o -obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c deleted file mode 100644 index a8d38dc8c504..000000000000 --- a/arch/mips/pci/ops-nile4.c +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#define LO(reg) (reg / 4) -#define HI(reg) (reg / 4 + 1) - -volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; - -static DEFINE_SPINLOCK(nile4_pci_lock); - -static int nile4_pcibios_config_access(unsigned char access_type, - struct pci_bus *bus, unsigned int devfn, int where, u32 * val) -{ - unsigned char busnum = bus->number; - u32 adr, mask, err; - - if ((busnum == 0) && (PCI_SLOT(devfn) > 8)) - /* The addressing scheme chosen leaves room for just - * 8 devices on the first busnum (besides the PCI - * controller itself) */ - return PCIBIOS_DEVICE_NOT_FOUND; - - if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) { - /* Access controller registers directly */ - if (access_type == PCI_ACCESS_WRITE) { - vrc_pciregs[(0x200 + where) >> 2] = *val; - } else { - *val = vrc_pciregs[(0x200 + where) >> 2]; - } - return PCIBIOS_SUCCESSFUL; - } - - /* Temporarily map PCI Window 1 to config space */ - mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; - vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0); - - /* Clear PCI Error register. This also clears the Error Type - * bits in the Control register */ - vrc_pciregs[LO(NILE4_PCIERR)] = 0; - vrc_pciregs[HI(NILE4_PCIERR)] = 0; - - /* Setup address */ - if (busnum == 0) - adr = - KSEG1ADDR(PCI_WINDOW1) + - ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8) - | (where & ~3)); - else - adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) | - (where & ~3); - - if (access_type == PCI_ACCESS_WRITE) - *(u32 *) adr = *val; - else - *val = *(u32 *) adr; - - /* Check for master or target abort */ - err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; - - /* Restore PCI Window 1 */ - vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; - - if (err) - return PCIBIOS_DEVICE_NOT_FOUND; - - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - unsigned long flags; - u32 data = 0; - int err; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - spin_lock_irqsave(&nile4_pci_lock, flags); - err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data); - spin_unlock_irqrestore(&nile4_pci_lock, flags); - - if (err) - return err; - - if (size == 1) - *val = (data >> ((where & 3) << 3)) & 0xff; - else if (size == 2) - *val = (data >> ((where & 3) << 3)) & 0xffff; - else - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - unsigned long flags; - u32 data = 0; - int err; - - if ((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - spin_lock_irqsave(&nile4_pci_lock, flags); - err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data); - spin_unlock_irqrestore(&nile4_pci_lock, flags); - - if (err) - return err; - - if (size == 1) - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - else if (size == 2) - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - else - data = val; - - if (nile4_pcibios_config_access - (PCI_ACCESS_WRITE, bus, devfn, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops nile4_pci_ops = { - .read = nile4_pcibios_read, - .write = nile4_pcibios_write, -}; diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c deleted file mode 100644 index c5045ff3ad8c..000000000000 --- a/arch/mips/pci/pci-lasat.c +++ /dev/null @@ -1,91 +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) 2000, 2001, 04 Keith M Wesolowski - */ -#include -#include -#include -#include -#include - -extern struct pci_ops nile4_pci_ops; -extern struct pci_ops gt64xxx_pci0_ops; -static struct resource lasat_pci_mem_resource = { - .name = "LASAT PCI MEM", - .start = 0x18000000, - .end = 0x19ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct resource lasat_pci_io_resource = { - .name = "LASAT PCI IO", - .start = 0x1a000000, - .end = 0x1bffffff, - .flags = IORESOURCE_IO, -}; - -static struct pci_controller lasat_pci_controller = { - .mem_resource = &lasat_pci_mem_resource, - .io_resource = &lasat_pci_io_resource, -}; - -static int __init lasat_pci_setup(void) -{ - printk("PCI: starting\n"); - - switch (mips_machtype) { - case MACH_LASAT_100: - lasat_pci_controller.pci_ops = >64xxx_pci0_ops; - break; - case MACH_LASAT_200: - lasat_pci_controller.pci_ops = &nile4_pci_ops; - break; - default: - panic("pcibios_init: mips_machtype incorrect"); - } - - register_pci_controller(&lasat_pci_controller); - - return 0; -} - -arch_initcall(lasat_pci_setup); - -#define LASATINT_ETH1 0 -#define LASATINT_ETH0 1 -#define LASATINT_HDC 2 -#define LASATINT_COMP 3 -#define LASATINT_HDLC 4 -#define LASATINT_PCIA 5 -#define LASATINT_PCIB 6 -#define LASATINT_PCIC 7 -#define LASATINT_PCID 8 - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - switch (slot) { - case 1: - case 2: - case 3: - return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4); - case 4: - return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */ - case 5: - return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */ - case 6: - return LASATINT_HDC; /* IDE controller */ - default: - return 0xff; /* Illegal */ - } - - return -1; -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index b665e4ac2208..f88ebc5b685e 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -258,12 +258,6 @@ config MTD_TSUNAMI help Support for the flash chip on Tsunami TIG bus. -config MTD_LASAT - tristate "LASAT flash device" - depends on LASAT && MTD_CFI - help - Support for the flash chips on the Lasat 100 and 200 boards. - config MTD_NETtel tristate "CFI flash device on SnapGear/SecureEdge" depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 3acbb5d01ca4..970b189271a2 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o obj-$(CONFIG_MTD_PCI) += pci.o obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o -obj-$(CONFIG_MTD_LASAT) += lasat.o obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o obj-$(CONFIG_MTD_EDB7312) += edb7312.o obj-$(CONFIG_MTD_IMPA7) += impa7.o diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c deleted file mode 100644 index e34376321050..000000000000 --- a/drivers/mtd/maps/lasat.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Flash device on Lasat 100 and 200 boards - * - * (C) 2002 Brian Murphy - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct mtd_info *lasat_mtd; - -static struct mtd_partition partition_info[LASAT_MTD_LAST]; -static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; - -static void lasat_set_vpp(struct map_info *map, int vpp) -{ - if (vpp) - *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; - else - *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit); -} - -static struct map_info lasat_map = { - .name = "LASAT flash", - .bankwidth = 4, - .set_vpp = lasat_set_vpp -}; - -static int __init init_lasat(void) -{ - int i; - /* since we use AMD chips and set_vpp is not implimented - * for these (yet) we still have to permanently enable flash write */ - printk(KERN_NOTICE "Unprotecting flash\n"); - ENABLE_VPP((&lasat_map)); - - lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); - lasat_map.virt = ioremap_nocache( - lasat_map.phys, lasat_board_info.li_flash_size); - lasat_map.size = lasat_board_info.li_flash_size; - - simple_map_init(&lasat_map); - - for (i=0; i < LASAT_MTD_LAST; i++) - partition_info[i].name = lasat_mtd_partnames[i]; - - lasat_mtd = do_map_probe("cfi_probe", &lasat_map); - - if (!lasat_mtd) - lasat_mtd = do_map_probe("jedec_probe", &lasat_map); - - if (lasat_mtd) { - u32 size, offset = 0; - - lasat_mtd->owner = THIS_MODULE; - - for (i=0; i < LASAT_MTD_LAST; i++) { - size = lasat_flash_partition_size(i); - partition_info[i].size = size; - partition_info[i].offset = offset; - offset += size; - } - - add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST ); - return 0; - } - - iounmap(lasat_map.virt); - return -ENXIO; -} - -static void __exit cleanup_lasat(void) -{ - if (lasat_mtd) { - del_mtd_partitions(lasat_mtd); - map_destroy(lasat_mtd); - } - if (lasat_map.virt) { - iounmap(lasat_map.virt); - lasat_map.virt = 0; - } -} - -module_init(init_lasat); -module_exit(cleanup_lasat); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Brian Murphy "); -MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver"); diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 94fc9be1aab6..075a4d3de326 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -187,13 +187,6 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_HP_LASERJET 1 -/* - * Valid machtype for group LASAT - */ -#define MACH_GROUP_LASAT 21 -#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ -#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ - /* * Valid machtype for group TITAN */ diff --git a/include/asm-mips/lasat/ds1603.h b/include/asm-mips/lasat/ds1603.h deleted file mode 100644 index edcd7544b358..000000000000 --- a/include/asm-mips/lasat/ds1603.h +++ /dev/null @@ -1,18 +0,0 @@ -#include - -/* Lasat 100 */ -#define DS1603_REG_100 (KSEG1ADDR(0x1c810000)) -#define DS1603_RST_100 (1 << 2) -#define DS1603_CLK_100 (1 << 0) -#define DS1603_DATA_SHIFT_100 1 -#define DS1603_DATA_100 (1 << DS1603_DATA_SHIFT_100) - -/* Lasat 200 */ -#define DS1603_REG_200 (KSEG1ADDR(0x11000000)) -#define DS1603_RST_200 (1 << 3) -#define DS1603_CLK_200 (1 << 4) -#define DS1603_DATA_200 (1 << 5) - -#define DS1603_DATA_REG_200 (DS1603_REG_200 + 0x10000) -#define DS1603_DATA_READ_SHIFT_200 9 -#define DS1603_DATA_READ_200 (1 << DS1603_DATA_READ_SHIFT_200) diff --git a/include/asm-mips/lasat/eeprom.h b/include/asm-mips/lasat/eeprom.h deleted file mode 100644 index 7b53edd5cd5f..000000000000 --- a/include/asm-mips/lasat/eeprom.h +++ /dev/null @@ -1,17 +0,0 @@ -#include - -/* lasat 100 */ -#define AT93C_REG_100 KSEG1ADDR(0x1c810000) -#define AT93C_RDATA_REG_100 AT93C_REG_100 -#define AT93C_RDATA_SHIFT_100 4 -#define AT93C_WDATA_SHIFT_100 4 -#define AT93C_CS_M_100 ( 1 << 5 ) -#define AT93C_CLK_M_100 ( 1 << 3 ) - -/* lasat 200 */ -#define AT93C_REG_200 KSEG1ADDR(0x11000000) -#define AT93C_RDATA_REG_200 (AT93C_REG_200+0x10000) -#define AT93C_RDATA_SHIFT_200 8 -#define AT93C_WDATA_SHIFT_200 2 -#define AT93C_CS_M_200 ( 1 << 0 ) -#define AT93C_CLK_M_200 ( 1 << 1 ) diff --git a/include/asm-mips/lasat/head.h b/include/asm-mips/lasat/head.h deleted file mode 100644 index f5589f31a197..000000000000 --- a/include/asm-mips/lasat/head.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Image header stuff - */ -#ifndef _HEAD_H -#define _HEAD_H - -#define LASAT_K_MAGIC0_VAL 0xfedeabba -#define LASAT_K_MAGIC1_VAL 0x00bedead - -#ifndef _LANGUAGE_ASSEMBLY -#include -struct bootloader_header { - u32 magic[2]; - u32 version; - u32 image_start; - u32 image_size; - u32 kernel_start; - u32 kernel_entry; -}; -#endif - -#endif /* _HEAD_H */ diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h deleted file mode 100644 index 42077e367a5b..000000000000 --- a/include/asm-mips/lasat/lasat.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * lasat.h - * - * Thomas Horsten - * Copyright (C) 2000 LASAT Networks A/S. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Configuration for LASAT boards, loads the appropriate include files. - */ -#ifndef _LASAT_H -#define _LASAT_H - -#ifndef _LANGUAGE_ASSEMBLY - -extern struct lasat_misc { - volatile u32 *reset_reg; - volatile u32 *flash_wp_reg; - u32 flash_wp_bit; -} *lasat_misc; - -enum lasat_mtdparts { - LASAT_MTD_BOOTLOADER, - LASAT_MTD_SERVICE, - LASAT_MTD_NORMAL, - LASAT_MTD_CONFIG, - LASAT_MTD_FS, - LASAT_MTD_LAST -}; - -/* - * The format of the data record in the EEPROM. - * See Documentation/LASAT/eeprom.txt for a detailed description - * of the fields in this struct, and the LASAT Hardware Configuration - * field specification for a detailed description of the config - * field. - */ -#include - -#define LASAT_EEPROM_VERSION 7 -struct lasat_eeprom_struct { - unsigned int version; - unsigned int cfg[3]; - unsigned char hwaddr[6]; - unsigned char print_partno[12]; - unsigned char term0; - unsigned char print_serial[14]; - unsigned char term1; - unsigned char prod_partno[12]; - unsigned char term2; - unsigned char prod_serial[14]; - unsigned char term3; - unsigned char passwd_hash[16]; - unsigned char pwdnull; - unsigned char vendid; - unsigned char ts_ref; - unsigned char ts_signoff; - unsigned char reserved[11]; - unsigned char debugaccess; - unsigned short prid; - unsigned int serviceflag; - unsigned int ipaddr; - unsigned int netmask; - unsigned int crc32; -}; - -struct lasat_eeprom_struct_pre7 { - unsigned int version; - unsigned int flags[3]; - unsigned char hwaddr0[6]; - unsigned char hwaddr1[6]; - unsigned char print_partno[9]; - unsigned char term0; - unsigned char print_serial[14]; - unsigned char term1; - unsigned char prod_partno[9]; - unsigned char term2; - unsigned char prod_serial[14]; - unsigned char term3; - unsigned char passwd_hash[24]; - unsigned char pwdnull; - unsigned char vendor; - unsigned char ts_ref; - unsigned char ts_signoff; - unsigned char reserved[6]; - unsigned int writecount; - unsigned int ipaddr; - unsigned int netmask; - unsigned int crc32; -}; - -/* Configuration descriptor encoding - see the doc for details */ - -#define LASAT_W0_DSCTYPE(v) ( ( (v) ) & 0xf ) -#define LASAT_W0_BMID(v) ( ( (v) >> 0x04 ) & 0xf ) -#define LASAT_W0_CPUTYPE(v) ( ( (v) >> 0x08 ) & 0xf ) -#define LASAT_W0_BUSSPEED(v) ( ( (v) >> 0x0c ) & 0xf ) -#define LASAT_W0_CPUCLK(v) ( ( (v) >> 0x10 ) & 0xf ) -#define LASAT_W0_SDRAMBANKSZ(v) ( ( (v) >> 0x14 ) & 0xf ) -#define LASAT_W0_SDRAMBANKS(v) ( ( (v) >> 0x18 ) & 0xf ) -#define LASAT_W0_L2CACHE(v) ( ( (v) >> 0x1c ) & 0xf ) - -#define LASAT_W1_EDHAC(v) ( ( (v) ) & 0xf ) -#define LASAT_W1_HIFN(v) ( ( (v) >> 0x04 ) & 0x1 ) -#define LASAT_W1_ISDN(v) ( ( (v) >> 0x05 ) & 0x1 ) -#define LASAT_W1_IDE(v) ( ( (v) >> 0x06 ) & 0x1 ) -#define LASAT_W1_HDLC(v) ( ( (v) >> 0x07 ) & 0x1 ) -#define LASAT_W1_USVERSION(v) ( ( (v) >> 0x08 ) & 0x1 ) -#define LASAT_W1_4MACS(v) ( ( (v) >> 0x09 ) & 0x1 ) -#define LASAT_W1_EXTSERIAL(v) ( ( (v) >> 0x0a ) & 0x1 ) -#define LASAT_W1_FLASHSIZE(v) ( ( (v) >> 0x0c ) & 0xf ) -#define LASAT_W1_PCISLOTS(v) ( ( (v) >> 0x10 ) & 0xf ) -#define LASAT_W1_PCI1OPT(v) ( ( (v) >> 0x14 ) & 0xf ) -#define LASAT_W1_PCI2OPT(v) ( ( (v) >> 0x18 ) & 0xf ) -#define LASAT_W1_PCI3OPT(v) ( ( (v) >> 0x1c ) & 0xf ) - -/* Routines specific to LASAT boards */ - -#define LASAT_BMID_MASQUERADE2 0 -#define LASAT_BMID_MASQUERADEPRO 1 -#define LASAT_BMID_SAFEPIPE25 2 -#define LASAT_BMID_SAFEPIPE50 3 -#define LASAT_BMID_SAFEPIPE100 4 -#define LASAT_BMID_SAFEPIPE5000 5 -#define LASAT_BMID_SAFEPIPE7000 6 -#define LASAT_BMID_SAFEPIPE1000 7 -//#define LASAT_BMID_SAFEPIPE30 7 -//#define LASAT_BMID_SAFEPIPE5100 8 -//#define LASAT_BMID_SAFEPIPE7100 9 -#define LASAT_BMID_UNKNOWN 0xf -#define LASAT_MAX_BMID_NAMES 9 // no larger than 15! - -#define LASAT_HAS_EDHAC ( 1 << 0 ) -#define LASAT_EDHAC_FAST ( 1 << 1 ) -#define LASAT_HAS_EADI ( 1 << 2 ) -#define LASAT_HAS_HIFN ( 1 << 3 ) -#define LASAT_HAS_ISDN ( 1 << 4 ) -#define LASAT_HAS_LEASEDLINE_IF ( 1 << 5 ) -#define LASAT_HAS_HDC ( 1 << 6 ) - -#define LASAT_PRID_MASQUERADE2 0 -#define LASAT_PRID_MASQUERADEPRO 1 -#define LASAT_PRID_SAFEPIPE25 2 -#define LASAT_PRID_SAFEPIPE50 3 -#define LASAT_PRID_SAFEPIPE100 4 -#define LASAT_PRID_SAFEPIPE5000 5 -#define LASAT_PRID_SAFEPIPE7000 6 -#define LASAT_PRID_SAFEPIPE30 7 -#define LASAT_PRID_SAFEPIPE5100 8 -#define LASAT_PRID_SAFEPIPE7100 9 - -#define LASAT_PRID_SAFEPIPE1110 10 -#define LASAT_PRID_SAFEPIPE3020 11 -#define LASAT_PRID_SAFEPIPE3030 12 -#define LASAT_PRID_SAFEPIPE5020 13 -#define LASAT_PRID_SAFEPIPE5030 14 -#define LASAT_PRID_SAFEPIPE1120 15 -#define LASAT_PRID_SAFEPIPE1130 16 -#define LASAT_PRID_SAFEPIPE6010 17 -#define LASAT_PRID_SAFEPIPE6110 18 -#define LASAT_PRID_SAFEPIPE6210 19 -#define LASAT_PRID_SAFEPIPE1020 20 -#define LASAT_PRID_SAFEPIPE1040 21 -#define LASAT_PRID_SAFEPIPE1060 22 - -struct lasat_info { - unsigned int li_cpu_hz; - unsigned int li_bus_hz; - unsigned int li_bmid; - unsigned int li_memsize; - unsigned int li_flash_size; - unsigned int li_prid; - unsigned char li_bmstr[16]; - unsigned char li_namestr[32]; - unsigned char li_typestr[16]; - /* Info on the Flash layout */ - unsigned int li_flash_base; - unsigned long li_flashpart_base[LASAT_MTD_LAST]; - unsigned long li_flashpart_size[LASAT_MTD_LAST]; - struct lasat_eeprom_struct li_eeprom_info; - unsigned int li_eeprom_upgrade_version; - unsigned int li_debugaccess; -}; - -extern struct lasat_info lasat_board_info; - -static inline unsigned long lasat_flash_partition_start(int partno) -{ - if (partno < 0 || partno >= LASAT_MTD_LAST) - return 0; - - return lasat_board_info.li_flashpart_base[partno]; -} - -static inline unsigned long lasat_flash_partition_size(int partno) -{ - if (partno < 0 || partno >= LASAT_MTD_LAST) - return 0; - - return lasat_board_info.li_flashpart_size[partno]; -} - -/* Called from setup() to initialize the global board_info struct */ -extern int lasat_init_board_info(void); - -/* Write the modified EEPROM info struct */ -extern void lasat_write_eeprom_info(void); - -#define N_MACHTYPES 2 -/* for calibration of delays */ - -/* the lasat_ndelay function is necessary because it is used at an - * early stage of the boot process where ndelay is not calibrated. - * It is used for the bit-banging rtc and eeprom drivers */ - -#include -/* calculating with the slowest board with 100 MHz clock */ -#define LASAT_100_DIVIDER 20 -/* All 200's run at 250 MHz clock */ -#define LASAT_200_DIVIDER 8 - -extern unsigned int lasat_ndelay_divider; - -static inline void lasat_ndelay(unsigned int ns) -{ - __delay(ns / lasat_ndelay_divider); -} - -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - -#define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef -#define LASAT_SERVICEMODE_MAGIC_2 0xfedeabba - -/* Lasat 100 boards */ -#define LASAT_GT_BASE (KSEG1ADDR(0x14000000)) - -/* Lasat 200 boards */ -#define Vrc5074_PHYS_BASE 0x1fa00000 -#define Vrc5074_BASE (KSEG1ADDR(Vrc5074_PHYS_BASE)) -#define PCI_WINDOW1 0x1a000000 - -#endif /* _LASAT_H */ diff --git a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h deleted file mode 100644 index 065474feeccc..000000000000 --- a/include/asm-mips/lasat/lasatint.h +++ /dev/null @@ -1,12 +0,0 @@ -#define LASATINT_END 16 - -/* lasat 100 */ -#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000)) -#define LASAT_INT_MASK_REG_100 (KSEG1ADDR(0x1c890000)) -#define LASATINT_MASK_SHIFT_100 0 - -/* lasat 200 */ -#define LASAT_INT_STATUS_REG_200 (KSEG1ADDR(0x1104003c)) -#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c)) -#define LASATINT_MASK_SHIFT_200 16 - diff --git a/include/asm-mips/lasat/picvue.h b/include/asm-mips/lasat/picvue.h deleted file mode 100644 index 42a492edc40e..000000000000 --- a/include/asm-mips/lasat/picvue.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Lasat 100 */ -#define PVC_REG_100 KSEG1ADDR(0x1c820000) -#define PVC_DATA_SHIFT_100 0 -#define PVC_DATA_M_100 0xFF -#define PVC_E_100 (1 << 8) -#define PVC_RW_100 (1 << 9) -#define PVC_RS_100 (1 << 10) - -/* Lasat 200 */ -#define PVC_REG_200 KSEG1ADDR(0x11000000) -#define PVC_DATA_SHIFT_200 24 -#define PVC_DATA_M_200 (0xFF << PVC_DATA_SHIFT_200) -#define PVC_E_200 (1 << 16) -#define PVC_RW_200 (1 << 17) -#define PVC_RS_200 (1 << 18) diff --git a/include/asm-mips/lasat/serial.h b/include/asm-mips/lasat/serial.h deleted file mode 100644 index 9e88c7669c7a..000000000000 --- a/include/asm-mips/lasat/serial.h +++ /dev/null @@ -1,13 +0,0 @@ -#include - -/* Lasat 100 boards serial configuration */ -#define LASAT_BASE_BAUD_100 ( 7372800 / 16 ) -#define LASAT_UART_REGS_BASE_100 0x1c8b0000 -#define LASAT_UART_REGS_SHIFT_100 2 -#define LASATINT_UART_100 8 - -/* * LASAT 200 boards serial configuration */ -#define LASAT_BASE_BAUD_200 (100000000 / 16 / 12) -#define LASAT_UART_REGS_BASE_200 (Vrc5074_PHYS_BASE + 0x0300) -#define LASAT_UART_REGS_SHIFT_200 3 -#define LASATINT_UART_200 13 diff --git a/include/asm-mips/mach-lasat/mach-gt64120.h b/include/asm-mips/mach-lasat/mach-gt64120.h deleted file mode 100644 index 1a9ad45cc135..000000000000 --- a/include/asm-mips/mach-lasat/mach-gt64120.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global - * search and replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef _ASM_GT64120_LASAT_GT64120_DEP_H -#define _ASM_GT64120_LASAT_GT64120_DEP_H - -/* - * GT64120 config space base address on Lasat 100 - */ -#define GT64120_BASE (KSEG1ADDR(0x14000000)) - -/* - * PCI Bus allocation - * - * (Guessing ...) - */ -#define GT_PCI_MEM_BASE 0x12000000UL -#define GT_PCI_MEM_SIZE 0x02000000UL -#define GT_PCI_IO_BASE 0x10000000UL -#define GT_PCI_IO_SIZE 0x02000000UL -#define GT_ISA_IO_BASE PCI_IO_BASE - -#endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */ diff --git a/include/asm-mips/nile4.h b/include/asm-mips/nile4.h deleted file mode 100644 index c3ca959aa4d9..000000000000 --- a/include/asm-mips/nile4.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - * - * This file is based on the following documentation: - * - * NEC Vrc 5074 System Controller Data Sheet, June 1998 - */ - -#ifndef _ASM_NILE4_H -#define _ASM_NILE4_H - -#define NILE4_BASE 0xbfa00000 -#define NILE4_SIZE 0x00200000 /* 2 MB */ - - - /* - * Physical Device Address Registers (PDARs) - */ - -#define NILE4_SDRAM0 0x0000 /* SDRAM Bank 0 [R/W] */ -#define NILE4_SDRAM1 0x0008 /* SDRAM Bank 1 [R/W] */ -#define NILE4_DCS2 0x0010 /* Device Chip-Select 2 [R/W] */ -#define NILE4_DCS3 0x0018 /* Device Chip-Select 3 [R/W] */ -#define NILE4_DCS4 0x0020 /* Device Chip-Select 4 [R/W] */ -#define NILE4_DCS5 0x0028 /* Device Chip-Select 5 [R/W] */ -#define NILE4_DCS6 0x0030 /* Device Chip-Select 6 [R/W] */ -#define NILE4_DCS7 0x0038 /* Device Chip-Select 7 [R/W] */ -#define NILE4_DCS8 0x0040 /* Device Chip-Select 8 [R/W] */ -#define NILE4_PCIW0 0x0060 /* PCI Address Window 0 [R/W] */ -#define NILE4_PCIW1 0x0068 /* PCI Address Window 1 [R/W] */ -#define NILE4_INTCS 0x0070 /* Controller Internal Registers and Devices */ - /* [R/W] */ -#define NILE4_BOOTCS 0x0078 /* Boot ROM Chip-Select [R/W] */ - - - /* - * CPU Interface Registers - */ - -#define NILE4_CPUSTAT 0x0080 /* CPU Status [R/W] */ -#define NILE4_INTCTRL 0x0088 /* Interrupt Control [R/W] */ -#define NILE4_INTSTAT0 0x0090 /* Interrupt Status 0 [R] */ -#define NILE4_INTSTAT1 0x0098 /* Interrupt Status 1 and CPU Interrupt */ - /* Enable [R/W] */ -#define NILE4_INTCLR 0x00A0 /* Interrupt Clear [R/W] */ -#define NILE4_INTPPES 0x00A8 /* PCI Interrupt Control [R/W] */ - - - /* - * Memory-Interface Registers - */ - -#define NILE4_MEMCTRL 0x00C0 /* Memory Control */ -#define NILE4_ACSTIME 0x00C8 /* Memory Access Timing [R/W] */ -#define NILE4_CHKERR 0x00D0 /* Memory Check Error Status [R] */ - - - /* - * PCI-Bus Registers - */ - -#define NILE4_PCICTRL 0x00E0 /* PCI Control [R/W] */ -#define NILE4_PCIARB 0x00E8 /* PCI Arbiter [R/W] */ -#define NILE4_PCIINIT0 0x00F0 /* PCI Master (Initiator) 0 [R/W] */ -#define NILE4_PCIINIT1 0x00F8 /* PCI Master (Initiator) 1 [R/W] */ -#define NILE4_PCIERR 0x00B8 /* PCI Error [R/W] */ - - - /* - * Local-Bus Registers - */ - -#define NILE4_LCNFG 0x0100 /* Local Bus Configuration [R/W] */ -#define NILE4_LCST2 0x0110 /* Local Bus Chip-Select Timing 2 [R/W] */ -#define NILE4_LCST3 0x0118 /* Local Bus Chip-Select Timing 3 [R/W] */ -#define NILE4_LCST4 0x0120 /* Local Bus Chip-Select Timing 4 [R/W] */ -#define NILE4_LCST5 0x0128 /* Local Bus Chip-Select Timing 5 [R/W] */ -#define NILE4_LCST6 0x0130 /* Local Bus Chip-Select Timing 6 [R/W] */ -#define NILE4_LCST7 0x0138 /* Local Bus Chip-Select Timing 7 [R/W] */ -#define NILE4_LCST8 0x0140 /* Local Bus Chip-Select Timing 8 [R/W] */ -#define NILE4_DCSFN 0x0150 /* Device Chip-Select Muxing and Output */ - /* Enables [R/W] */ -#define NILE4_DCSIO 0x0158 /* Device Chip-Selects As I/O Bits [R/W] */ -#define NILE4_BCST 0x0178 /* Local Boot Chip-Select Timing [R/W] */ - - - /* - * DMA Registers - */ - -#define NILE4_DMACTRL0 0x0180 /* DMA Control 0 [R/W] */ -#define NILE4_DMASRCA0 0x0188 /* DMA Source Address 0 [R/W] */ -#define NILE4_DMADESA0 0x0190 /* DMA Destination Address 0 [R/W] */ -#define NILE4_DMACTRL1 0x0198 /* DMA Control 1 [R/W] */ -#define NILE4_DMASRCA1 0x01A0 /* DMA Source Address 1 [R/W] */ -#define NILE4_DMADESA1 0x01A8 /* DMA Destination Address 1 [R/W] */ - - - /* - * Timer Registers - */ - -#define NILE4_T0CTRL 0x01C0 /* SDRAM Refresh Control [R/W] */ -#define NILE4_T0CNTR 0x01C8 /* SDRAM Refresh Counter [R/W] */ -#define NILE4_T1CTRL 0x01D0 /* CPU-Bus Read Time-Out Control [R/W] */ -#define NILE4_T1CNTR 0x01D8 /* CPU-Bus Read Time-Out Counter [R/W] */ -#define NILE4_T2CTRL 0x01E0 /* General-Purpose Timer Control [R/W] */ -#define NILE4_T2CNTR 0x01E8 /* General-Purpose Timer Counter [R/W] */ -#define NILE4_T3CTRL 0x01F0 /* Watchdog Timer Control [R/W] */ -#define NILE4_T3CNTR 0x01F8 /* Watchdog Timer Counter [R/W] */ - - - /* - * PCI Configuration Space Registers - */ - -#define NILE4_PCI_BASE 0x0200 - -#define NILE4_VID 0x0200 /* PCI Vendor ID [R] */ -#define NILE4_DID 0x0202 /* PCI Device ID [R] */ -#define NILE4_PCICMD 0x0204 /* PCI Command [R/W] */ -#define NILE4_PCISTS 0x0206 /* PCI Status [R/W] */ -#define NILE4_REVID 0x0208 /* PCI Revision ID [R] */ -#define NILE4_CLASS 0x0209 /* PCI Class Code [R] */ -#define NILE4_CLSIZ 0x020C /* PCI Cache Line Size [R/W] */ -#define NILE4_MLTIM 0x020D /* PCI Latency Timer [R/W] */ -#define NILE4_HTYPE 0x020E /* PCI Header Type [R] */ -#define NILE4_BIST 0x020F /* BIST [R] (unimplemented) */ -#define NILE4_BARC 0x0210 /* PCI Base Address Register Control [R/W] */ -#define NILE4_BAR0 0x0218 /* PCI Base Address Register 0 [R/W] */ -#define NILE4_BAR1 0x0220 /* PCI Base Address Register 1 [R/W] */ -#define NILE4_CIS 0x0228 /* PCI Cardbus CIS Pointer [R] */ - /* (unimplemented) */ -#define NILE4_SSVID 0x022C /* PCI Sub-System Vendor ID [R/W] */ -#define NILE4_SSID 0x022E /* PCI Sub-System ID [R/W] */ -#define NILE4_ROM 0x0230 /* Expansion ROM Base Address [R] */ - /* (unimplemented) */ -#define NILE4_INTLIN 0x023C /* PCI Interrupt Line [R/W] */ -#define NILE4_INTPIN 0x023D /* PCI Interrupt Pin [R] */ -#define NILE4_MINGNT 0x023E /* PCI Min_Gnt [R] (unimplemented) */ -#define NILE4_MAXLAT 0x023F /* PCI Max_Lat [R] (unimplemented) */ -#define NILE4_BAR2 0x0240 /* PCI Base Address Register 2 [R/W] */ -#define NILE4_BAR3 0x0248 /* PCI Base Address Register 3 [R/W] */ -#define NILE4_BAR4 0x0250 /* PCI Base Address Register 4 [R/W] */ -#define NILE4_BAR5 0x0258 /* PCI Base Address Register 5 [R/W] */ -#define NILE4_BAR6 0x0260 /* PCI Base Address Register 6 [R/W] */ -#define NILE4_BAR7 0x0268 /* PCI Base Address Register 7 [R/W] */ -#define NILE4_BAR8 0x0270 /* PCI Base Address Register 8 [R/W] */ -#define NILE4_BARB 0x0278 /* PCI Base Address Register BOOT [R/W] */ - - - /* - * Serial-Port Registers - */ - -#define NILE4_UART_BASE 0x0300 - -#define NILE4_UARTRBR 0x0300 /* UART Receiver Data Buffer [R] */ -#define NILE4_UARTTHR 0x0300 /* UART Transmitter Data Holding [W] */ -#define NILE4_UARTIER 0x0308 /* UART Interrupt Enable [R/W] */ -#define NILE4_UARTDLL 0x0300 /* UART Divisor Latch LSB [R/W] */ -#define NILE4_UARTDLM 0x0308 /* UART Divisor Latch MSB [R/W] */ -#define NILE4_UARTIIR 0x0310 /* UART Interrupt ID [R] */ -#define NILE4_UARTFCR 0x0310 /* UART FIFO Control [W] */ -#define NILE4_UARTLCR 0x0318 /* UART Line Control [R/W] */ -#define NILE4_UARTMCR 0x0320 /* UART Modem Control [R/W] */ -#define NILE4_UARTLSR 0x0328 /* UART Line Status [R/W] */ -#define NILE4_UARTMSR 0x0330 /* UART Modem Status [R/W] */ -#define NILE4_UARTSCR 0x0338 /* UART Scratch [R/W] */ - -#define NILE4_UART_BASE_BAUD 520833 /* 100 MHz / 12 / 16 */ - - - /* - * Interrupt Lines - */ - -#define NILE4_INT_CPCE 0 /* CPU-Interface Parity-Error Interrupt */ -#define NILE4_INT_CNTD 1 /* CPU No-Target Decode Interrupt */ -#define NILE4_INT_MCE 2 /* Memory-Check Error Interrupt */ -#define NILE4_INT_DMA 3 /* DMA Controller Interrupt */ -#define NILE4_INT_UART 4 /* UART Interrupt */ -#define NILE4_INT_WDOG 5 /* Watchdog Timer Interrupt */ -#define NILE4_INT_GPT 6 /* General-Purpose Timer Interrupt */ -#define NILE4_INT_LBRTD 7 /* Local-Bus Ready Timer Interrupt */ -#define NILE4_INT_INTA 8 /* PCI Interrupt Signal INTA# */ -#define NILE4_INT_INTB 9 /* PCI Interrupt Signal INTB# */ -#define NILE4_INT_INTC 10 /* PCI Interrupt Signal INTC# */ -#define NILE4_INT_INTD 11 /* PCI Interrupt Signal INTD# */ -#define NILE4_INT_INTE 12 /* PCI Interrupt Signal INTE# (ISA cascade) */ -#define NILE4_INT_RESV 13 /* Reserved */ -#define NILE4_INT_PCIS 14 /* PCI SERR# Interrupt */ -#define NILE4_INT_PCIE 15 /* PCI Internal Error Interrupt */ - - - /* - * Nile 4 Register Access - */ - -static inline void nile4_sync(void) -{ - volatile u32 *p = (volatile u32 *)0xbfc00000; - (void)(*p); -} - -static inline void nile4_out32(u32 offset, u32 val) -{ - *(volatile u32 *)(NILE4_BASE+offset) = val; - nile4_sync(); -} - -static inline u32 nile4_in32(u32 offset) -{ - u32 val = *(volatile u32 *)(NILE4_BASE+offset); - nile4_sync(); - return val; -} - -static inline void nile4_out16(u32 offset, u16 val) -{ - *(volatile u16 *)(NILE4_BASE+offset) = val; - nile4_sync(); -} - -static inline u16 nile4_in16(u32 offset) -{ - u16 val = *(volatile u16 *)(NILE4_BASE+offset); - nile4_sync(); - return val; -} - -static inline void nile4_out8(u32 offset, u8 val) -{ - *(volatile u8 *)(NILE4_BASE+offset) = val; - nile4_sync(); -} - -static inline u8 nile4_in8(u32 offset) -{ - u8 val = *(volatile u8 *)(NILE4_BASE+offset); - nile4_sync(); - return val; -} - - - /* - * Physical Device Address Registers - */ - -extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, - int on_memory_bus, int visible); - - - /* - * PCI Master Registers - */ - -#define NILE4_PCICMD_IACK 0 /* PCI Interrupt Acknowledge */ -#define NILE4_PCICMD_IO 1 /* PCI I/O Space */ -#define NILE4_PCICMD_MEM 3 /* PCI Memory Space */ -#define NILE4_PCICMD_CFG 5 /* PCI Configuration Space */ - - - /* - * PCI Address Spaces - * - * Note that these are multiplexed using PCIINIT[01]! - */ - -#define NILE4_PCI_IO_BASE 0xa6000000 -#define NILE4_PCI_MEM_BASE 0xa8000000 -#define NILE4_PCI_CFG_BASE NILE4_PCI_MEM_BASE -#define NILE4_PCI_IACK_BASE NILE4_PCI_IO_BASE - - -extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr); - - - /* - * Interrupt Programming - */ - -#define NUM_I8259_INTERRUPTS 16 -#define NUM_NILE4_INTERRUPTS 16 - -#define IRQ_I8259_CASCADE NILE4_INT_INTE -#define is_i8259_irq(irq) ((irq) < NUM_I8259_INTERRUPTS) -#define nile4_to_irq(n) ((n)+NUM_I8259_INTERRUPTS) -#define irq_to_nile4(n) ((n)-NUM_I8259_INTERRUPTS) - -extern void nile4_map_irq(int nile4_irq, int cpu_irq); -extern void nile4_map_irq_all(int cpu_irq); -extern void nile4_enable_irq(unsigned int nile4_irq); -extern void nile4_disable_irq(unsigned int nile4_irq); -extern void nile4_disable_irq_all(void); -extern u16 nile4_get_irq_stat(int cpu_irq); -extern void nile4_enable_irq_output(int cpu_irq); -extern void nile4_disable_irq_output(int cpu_irq); -extern void nile4_set_pci_irq_polarity(int pci_irq, int high); -extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level); -extern void nile4_clear_irq(int nile4_irq); -extern void nile4_clear_irq_mask(u32 mask); -extern u8 nile4_i8259_iack(void); -extern void nile4_dump_irq_status(void); /* Debug */ - -#endif - From 688b3d720820a9e3e2e9d5882be64a28f649e206 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 9 Jul 2007 16:29:16 +0100 Subject: [PATCH 522/551] [MIPS] Delete Ocelot 3 support. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 25 - arch/mips/Makefile | 7 - arch/mips/configs/atlas_defconfig | 1 - arch/mips/configs/bigsur_defconfig | 1 - arch/mips/configs/capcella_defconfig | 1 - arch/mips/configs/cobalt_defconfig | 1 - arch/mips/configs/db1000_defconfig | 1 - arch/mips/configs/db1100_defconfig | 1 - arch/mips/configs/db1200_defconfig | 1 - arch/mips/configs/db1500_defconfig | 1 - arch/mips/configs/db1550_defconfig | 1 - arch/mips/configs/ddb5477_defconfig | 1 - arch/mips/configs/decstation_defconfig | 1 - arch/mips/configs/e55_defconfig | 1 - arch/mips/configs/emma2rh_defconfig | 1 - arch/mips/configs/excite_defconfig | 1 - arch/mips/configs/fulong_defconfig | 1 - arch/mips/configs/ip22_defconfig | 1 - arch/mips/configs/ip27_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/jazz_defconfig | 1 - arch/mips/configs/jmr3927_defconfig | 1 - arch/mips/configs/malta_defconfig | 1 - arch/mips/configs/mipssim_defconfig | 1 - arch/mips/configs/mpc30x_defconfig | 1 - arch/mips/configs/msp71xx_defconfig | 1 - arch/mips/configs/ocelot_3_defconfig | 1280 ----------------- arch/mips/configs/ocelot_defconfig | 1 - arch/mips/configs/pb1100_defconfig | 1 - arch/mips/configs/pb1500_defconfig | 1 - arch/mips/configs/pb1550_defconfig | 1 - arch/mips/configs/pnx8550-jbs_defconfig | 1 - arch/mips/configs/pnx8550-stb810_defconfig | 1 - arch/mips/configs/qemu_defconfig | 1 - arch/mips/configs/rbhma4200_defconfig | 1 - arch/mips/configs/rbhma4500_defconfig | 1 - arch/mips/configs/rm200_defconfig | 1 - arch/mips/configs/sb1250-swarm_defconfig | 1 - arch/mips/configs/sead_defconfig | 1 - arch/mips/configs/tb0219_defconfig | 1 - arch/mips/configs/tb0226_defconfig | 1 - arch/mips/configs/tb0287_defconfig | 1 - arch/mips/configs/workpad_defconfig | 1 - arch/mips/configs/wrppmc_defconfig | 1 - arch/mips/configs/yosemite_defconfig | 1 - arch/mips/defconfig | 1 - arch/mips/kernel/Makefile | 1 - arch/mips/kernel/irq-mv6434x.c | 111 -- arch/mips/momentum/ocelot_3/Makefile | 8 - arch/mips/momentum/ocelot_3/irq.c | 109 -- arch/mips/momentum/ocelot_3/ocelot_3_fpga.h | 59 - arch/mips/momentum/ocelot_3/platform.c | 252 ---- arch/mips/momentum/ocelot_3/prom.c | 189 --- arch/mips/momentum/ocelot_3/reset.c | 59 - arch/mips/momentum/ocelot_3/setup.c | 398 ----- arch/mips/pci/Makefile | 2 - arch/mips/pci/fixup-ocelot3.c | 41 - arch/mips/pci/ops-marvell.c | 93 -- drivers/net/Kconfig | 2 +- .../mach-ocelot3/cpu-feature-overrides.h | 48 - include/asm-mips/war.h | 4 +- include/linux/mv643xx.h | 4 - 62 files changed, 3 insertions(+), 2732 deletions(-) delete mode 100644 arch/mips/configs/ocelot_3_defconfig delete mode 100644 arch/mips/kernel/irq-mv6434x.c delete mode 100644 arch/mips/momentum/ocelot_3/Makefile delete mode 100644 arch/mips/momentum/ocelot_3/irq.c delete mode 100644 arch/mips/momentum/ocelot_3/ocelot_3_fpga.h delete mode 100644 arch/mips/momentum/ocelot_3/platform.c delete mode 100644 arch/mips/momentum/ocelot_3/prom.c delete mode 100644 arch/mips/momentum/ocelot_3/reset.c delete mode 100644 arch/mips/momentum/ocelot_3/setup.c delete mode 100644 arch/mips/pci/fixup-ocelot3.c delete mode 100644 arch/mips/pci/ops-marvell.c delete mode 100644 include/asm-mips/mach-ocelot3/cpu-feature-overrides.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1619cf2c9ff0..a00fabe2e4e0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -266,25 +266,6 @@ config MOMENCO_OCELOT The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . -config MOMENCO_OCELOT_3 - bool "Momentum Ocelot-3 board" - select BOOT_ELF32 - select DMA_NONCOHERENT - select HW_HAS_PCI - select IRQ_CPU - select IRQ_CPU_RM7K - select IRQ_MV64340 - select PCI_MARVELL - select RM7000_CPU_SCACHE - select SWAP_IO_SPACE - select SYS_HAS_CPU_RM9000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - help - The Ocelot-3 is based off Discovery III System Controller and - PMC-Sierra Rm79000 core. - config PNX8550_JBS bool "Philips PNX8550 based JBS board" select PNX8550 @@ -826,9 +807,6 @@ config IRQ_MSP_SLP config IRQ_MSP_CIC bool -config IRQ_MV64340 - bool - config DDB5XXX_COMMON bool select SYS_SUPPORTS_KGDB @@ -850,9 +828,6 @@ config MIPS_RM9122 bool select SERIAL_RM9000 -config PCI_MARVELL - bool - config PNX8550 bool select SOC_PNX8550 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0c270b6ee24c..20d19c9b7761 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -364,13 +364,6 @@ core-$(CONFIG_QEMU) += arch/mips/qemu/ cflags-$(CONFIG_QEMU) += -Iinclude/asm-mips/mach-qemu load-$(CONFIG_QEMU) += 0xffffffff80010000 -# -# Momentum Ocelot-3 -# -core-$(CONFIG_MOMENCO_OCELOT_3) += arch/mips/momentum/ocelot_3/ -cflags-$(CONFIG_MOMENCO_OCELOT_3) += -Iinclude/asm-mips/mach-ocelot3 -load-$(CONFIG_MOMENCO_OCELOT_3) += 0xffffffff80100000 - # # Basler eXcite # diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 6480571de944..129e2c961fec 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -33,7 +33,6 @@ CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 9c75795cba08..dc3e1bf4e42e 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index 0152730fb4d1..4c7031222e64 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 521311ad9528..c8c05785a86d 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -19,7 +19,6 @@ CONFIG_MIPS_COBALT=y # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index f3b0bc7abb56..ec60beb888b2 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index b9ebb301a523..f3c25f08bfad 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index cfebcca2f938..6d400befbacc 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 213ef385ff09..82aea6e08823 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index aa40611fb00b..82697714a9e3 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 1f4acce27659..a42ab9ae7d4b 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index a08b99a0379d..d6e3fffbc80d 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -33,7 +33,6 @@ CONFIG_MACH_DECSTATION=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 938da2d7b19d..78f5004fb721 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index dab9aba49487..b29bff0f56c3 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index a828c04d1afe..69810592aa6b 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -34,7 +34,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig index f15559fa578d..6ab94d8cf08b 100644 --- a/arch/mips/configs/fulong_defconfig +++ b/arch/mips/configs/fulong_defconfig @@ -20,7 +20,6 @@ CONFIG_LEMOTE_FULONG=y # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index cc0530ef33f2..405c9f505a77 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 482f2fa120df..a9dcbcf563cb 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index f9f58d0906ba..a040459bec11 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index bc4e30fe4e22..dd04eece9fd3 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -33,7 +33,6 @@ CONFIG_MACH_JAZZ=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index baa1736c21cd..9a25e770abd8 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index d8ee7c28c83b..546cb243fd09 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -33,7 +33,6 @@ CONFIG_MIPS_MALTA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index fc8a42477840..bc3246b2c808 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y CONFIG_MIPS_SIM=y # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 2da27ece70c7..4981ce425d82 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index cb2aeb20721e..adca5f7ba533 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig deleted file mode 100644 index 20946b8141a3..000000000000 --- a/arch/mips/configs/ocelot_3_defconfig +++ /dev/null @@ -1,1280 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:35 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -CONFIG_MOMENCO_OCELOT_3=y -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_IRQ_CPU_RM7K=y -CONFIG_IRQ_MV64340=y -CONFIG_PCI_MARVELL=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_BOOT_ELF32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -CONFIG_CPU_RM9000=y -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_RM9000=y -CONFIG_WEAK_ORDERING=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_RM7000_CPU_SCACHE=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -CONFIG_IPV6_MIP6=y -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_TUNNEL is not set -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK_ENABLED=m -CONFIG_NF_CONNTRACK_SUPPORT=y -# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_ACCT=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_NF_CONNTRACK_IPV6=m -# CONFIG_IP6_NF_QUEUE is not set -# CONFIG_IP6_NF_IPTABLES is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -CONFIG_NET_CLS_ROUTE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y -CONFIG_FIB_RULES=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -CONFIG_ATA_OVER_ETH=m - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=m -CONFIG_SCSI_TGT=m -CONFIG_SCSI_NETLINK=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -# CONFIG_BLK_DEV_SD is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_SCAN_ASYNC=y - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -CONFIG_SCSI_FC_ATTRS=m -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set - -# -# SCSI low-level drivers -# -CONFIG_ISCSI_TCP=m -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -CONFIG_SCSI_AIC94XX=m -# CONFIG_AIC94XX_DEBUG is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_MV643XX_ETH=y -CONFIG_QLA3XXX=m -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3=m -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -CONFIG_NETXEN_NIC=m - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -# CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# 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=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM 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_HW_RANDOM is not set -CONFIG_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -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_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=m -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m -CONFIG_GENERIC_ACL=y - -# -# 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_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# 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=y -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=m -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 - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -CONFIG_DLM_TCP=y -# CONFIG_DLM_SCTP is not set -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="ip=any root=nfs" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 492c9abfd943..e1db1fb80cd0 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set CONFIG_MOMENCO_OCELOT=y -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 22fb01bc6a7a..0028aef0af9d 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index b0abaef4ce56..8a1d5888739c 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index ddb173ae50ea..5581ad2ca411 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -34,7 +34,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 2c2a8c8dca69..821c1cee5639 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set CONFIG_PNX8550_JBS=y diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index b435d63deab9..0e8bd92b38cf 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index cfe1f5a0a20f..6cca105832ca 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index 76b939fad78e..20a38526d483 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -31,7 +31,6 @@ CONFIG_MIPS=y # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 2c9e7e493a1b..5dbb250f71c7 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -21,7 +21,6 @@ CONFIG_ZONE_DMA=y # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 9d731409c730..1a67a85aabbb 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 55fa6731c111..98a914092258 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index f80c61a54653..69c08b24c82a 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -33,7 +33,6 @@ CONFIG_MIPS_SEAD=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index d5e4e3e3769b..5d4fc0e4f729 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index 8743f6dfd7ed..1b92b48de051 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index eab47f2ac829..5b77c7a5d83a 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index d32e4cd55ee4..94a4f94a8b24 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 95986e37382c..e38bd9b0eadc 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -33,7 +33,6 @@ CONFIG_WR_PPMC=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index c1e5a128cfa6..f1cdb12f7925 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index bf18baf2fbc2..b3b6e58058f6 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -33,7 +33,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set # CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 4b40015a66d2..961594cb5214 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -49,7 +49,6 @@ obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o -obj-$(CONFIG_IRQ_MV64340) += irq-mv6434x.o obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o obj-$(CONFIG_32BIT) += scall32-o32.o diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c deleted file mode 100644 index 3dd561832e4c..000000000000 --- a/arch/mips/kernel/irq-mv6434x.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2002 Momentum Computer - * Author: mdharm@momenco.com - * Copyright (C) 2004, 06 Ralf Baechle - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static unsigned int irq_base; - -static inline int ls1bit32(unsigned int x) -{ - int b = 31, s; - - s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; - s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; - s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; - s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; - s = 1; if (x << 1 == 0) s = 0; b -= s; - - return b; -} - -/* mask off an interrupt -- 1 is enable, 0 is disable */ -static inline void mask_mv64340_irq(unsigned int irq) -{ - uint32_t value; - - if (irq < (irq_base + 32)) { - value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW); - value &= ~(1 << (irq - irq_base)); - MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); - } else { - value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH); - value &= ~(1 << (irq - irq_base - 32)); - MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); - } -} - -/* unmask an interrupt -- 1 is enable, 0 is disable */ -static inline void unmask_mv64340_irq(unsigned int irq) -{ - uint32_t value; - - if (irq < (irq_base + 32)) { - value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW); - value |= 1 << (irq - irq_base); - MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); - } else { - value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH); - value |= 1 << (irq - irq_base - 32); - MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); - } -} - -/* - * Interrupt handler for interrupts coming from the Marvell chip. - * It could be built in ethernet ports etc... - */ -void ll_mv64340_irq(void) -{ - unsigned int irq_src_low, irq_src_high; - unsigned int irq_mask_low, irq_mask_high; - - /* read the interrupt status registers */ - irq_mask_low = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW); - irq_mask_high = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH); - irq_src_low = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW); - irq_src_high = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH); - - /* mask for just the interrupts we want */ - irq_src_low &= irq_mask_low; - irq_src_high &= irq_mask_high; - - if (irq_src_low) - do_IRQ(ls1bit32(irq_src_low) + irq_base); - else - do_IRQ(ls1bit32(irq_src_high) + irq_base + 32); -} - -struct irq_chip mv64340_irq_type = { - .name = "MV-64340", - .ack = mask_mv64340_irq, - .mask = mask_mv64340_irq, - .mask_ack = mask_mv64340_irq, - .unmask = unmask_mv64340_irq, -}; - -void __init mv64340_irq_init(unsigned int base) -{ - int i; - - for (i = base; i < base + 64; i++) - set_irq_chip_and_handler(i, &mv64340_irq_type, - handle_level_irq); - - irq_base = base; -} diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile deleted file mode 100644 index d5a090a85a15..000000000000 --- a/arch/mips/momentum/ocelot_3/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for Momentum Computer's Ocelot-3 board. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -obj-y += irq.o platform.o prom.o reset.o setup.o diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c deleted file mode 100644 index 3862d1d1add4..000000000000 --- a/arch/mips/momentum/ocelot_3/irq.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - * - * Copyright 2004 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct irqaction cascade_mv64340 = { - no_action, IRQF_DISABLED, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL -}; - -void __init arch_init_irq(void) -{ - /* - * Clear all of the interrupts while we change the able around a bit. - * int-handler is not on bootstrap - */ - clear_c0_status(ST0_IM | ST0_BEV); - - rm7k_cpu_irq_init(); - - /* set up the cascading interrupts */ - setup_irq(8, &cascade_mv64340); /* unmask intControl IM8, IRQ 9 */ - mv64340_irq_init(16); - - set_c0_status(ST0_IM); /* IE in the status register */ - -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status(); - - if (pending & STATUSF_IP0) - do_IRQ(0); - else if (pending & STATUSF_IP1) - do_IRQ(1); - else if (pending & STATUSF_IP2) - do_IRQ(2); - else if (pending & STATUSF_IP3) - do_IRQ(3); - else if (pending & STATUSF_IP4) - do_IRQ(4); - else if (pending & STATUSF_IP5) - do_IRQ(5); - else if (pending & STATUSF_IP6) - do_IRQ(6); - else if (pending & STATUSF_IP7) - do_IRQ(7); - else { - /* - * Now look at the extended interrupts - */ - pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; - - if (pending & STATUSF_IP8) - ll_mv64340_irq(); - else - spurious_interrupt(); - } -} diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h deleted file mode 100644 index 5710a9029f1c..000000000000 --- a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Ocelot-3 Board Register Definitions - * - * (C) 2002 Momentum Computer Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - */ - -#ifndef __OCELOT_3_FPGA_H__ -#define __OCELOT_3_FPGA_H__ - -#define OCELOT_3_REG_BOARDREV 0x0 -#define OCELOT_3_REG_FPGA_REV 0x1 -#define OCELOT_3_REG_FPGA_TYPE 0x2 -#define OCELOT_3_REG_RESET_STATUS 0x3 -#define OCELOT_3_REG_BOARD_STATUS 0x4 -#define OCELOT_3_REG_CPCI_ID 0x5 -#define OCELOT_3_REG_SET 0x6 -#define OCELOT_3_REG_CLR 0x7 -#define OCELOT_3_REG_EEPROM_MODE 0x9 -#define OCELOT_3_REG_INTMASK 0xa -#define OCELOT_3_REG_INTSTAT 0xb -#define OCELOT_3_REG_UART_INTMASK 0xc -#define OCELOT_3_REG_UART_INTSTAT 0xd -#define OCELOT_3_REG_INTSET 0xe -#define OCELOT_3_REG_INTCLR 0xf - -extern unsigned long ocelot_fpga_base; - -#define __FPGA_REG_TO_ADDR(reg) \ - ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg) -#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) -#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) - -#endif diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c deleted file mode 100644 index cb63c82ef650..000000000000 --- a/arch/mips/momentum/ocelot_3/platform.c +++ /dev/null @@ -1,252 +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) 2006, 07 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2007 Dale Farnsworth (dale@farnsworth.org) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ocelot_3_fpga.h" - -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) - -static struct resource mv643xx_eth_shared_resources[] = { - [0] = { - .name = "ethernet shared base", - .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, - .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + - MV643XX_ETH_SHARED_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device mv643xx_eth_shared_device = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), - .resource = mv643xx_eth_shared_resources, -}; - -#define MV_SRAM_BASE 0xfe000000UL -#define MV_SRAM_SIZE (256 * 1024) - -#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) -#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) - -#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE -#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) - -#define MV64x60_IRQ_ETH_0 48 -#define MV64x60_IRQ_ETH_1 49 -#define MV64x60_IRQ_ETH_2 50 - -static struct resource mv64x60_eth0_resources[] = { - [0] = { - .name = "eth0 irq", - .start = MV64x60_IRQ_ETH_0, - .end = MV64x60_IRQ_ETH_0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth0_pd = { - .port_number = 0, - - .tx_sram_addr = MV_SRAM_BASE_ETH0, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth0_device = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), - .resource = mv64x60_eth0_resources, - .dev = { - .platform_data = ð0_pd, - }, -}; - -static struct resource mv64x60_eth1_resources[] = { - [0] = { - .name = "eth1 irq", - .start = MV64x60_IRQ_ETH_1, - .end = MV64x60_IRQ_ETH_1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth1_pd = { - .port_number = 1, - - .tx_sram_addr = MV_SRAM_BASE_ETH1, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth1_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), - .resource = mv64x60_eth1_resources, - .dev = { - .platform_data = ð1_pd, - }, -}; - -static struct resource mv64x60_eth2_resources[] = { - [0] = { - .name = "eth2 irq", - .start = MV64x60_IRQ_ETH_2, - .end = MV64x60_IRQ_ETH_2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth2_pd = { - .port_number = 2, -}; - -static struct platform_device eth2_device = { - .name = MV643XX_ETH_NAME, - .id = 2, - .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), - .resource = mv64x60_eth2_resources, - .dev = { - .platform_data = ð2_pd, - }, -}; - -static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { - &mv643xx_eth_shared_device, - ð0_device, - ð1_device, - ð2_device, -}; - -static u8 __init exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - udelay(1); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - udelay(1); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; -} - -static void __init get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} - -/* - * Copy and increment ethernet MAC address by a small value. - * - * This is useful for systems where the only one MAC address is stored in - * non-volatile memory for multiple ports. - */ -static inline void eth_mac_add(unsigned char *dst, unsigned char *src, - unsigned int add) -{ - int i; - - BUG_ON(add >= 256); - - for (i = ETH_ALEN; i >= 0; i--) { - dst[i] = src[i] + add; - add = dst[i] < src[i]; /* compute carry */ - } - - WARN_ON(add); -} - -static int __init mv643xx_eth_add_pds(void) -{ - unsigned char mac[ETH_ALEN]; - int ret; - - get_mac(mac); - eth_mac_add(eth0_pd.mac_addr, mac, 0); - eth_mac_add(eth1_pd.mac_addr, mac, 1); - eth_mac_add(eth2_pd.mac_addr, mac, 2); - ret = platform_add_devices(mv643xx_eth_pd_devs, - ARRAY_SIZE(mv643xx_eth_pd_devs)); - - return ret; -} - -device_initcall(mv643xx_eth_add_pds); - -#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ - -#define OCELOT3_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) - -static struct plat_serial8250_port uart8250_data[] = { - { - .membase = (signed long) 0xfd000020, - .irq = 6, - .uartclk = 20000000, - .iotype = UPIO_MEM, - .flags = OCELOT3_UART_FLAGS, - .regshift = 2, - }, - { }, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = uart8250_data, - }, -}; - -static int __init uart8250_init(void) -{ - return platform_device_register(&uart8250_device); -} - -module_init(uart8250_init); - -MODULE_AUTHOR("Ralf Baechle "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("8250 UART probe driver for the Ocelot 3"); diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c deleted file mode 100644 index 8e02df63578a..000000000000 --- a/arch/mips/momentum/ocelot_3/prom.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Copyright 2004 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - * - */ -#include -#include -#include - -#include -#include -#include -#include "ocelot_3_fpga.h" - -struct callvectors* debug_vectors; -extern unsigned long marvell_base; -extern unsigned long cpu_clock; - -const char *get_system_type(void) -{ - return "Momentum Ocelot-3"; -} - -#ifdef CONFIG_64BIT - -unsigned long signext(unsigned long addr) -{ - addr &= 0xffffffff; - return (unsigned long)((int)addr); -} - -void *get_arg(unsigned long args, int arc) -{ - unsigned long ul; - unsigned char *puc, uc; - - args += (arc * 4); - ul = (unsigned long)signext(args); - puc = (unsigned char *)ul; - if (puc == 0) - return (void *)0; - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - uc = *puc++; - ul = (unsigned long)uc; - uc = *puc++; - ul |= (((unsigned long)uc) << 8); - uc = *puc++; - ul |= (((unsigned long)uc) << 16); - uc = *puc++; - ul |= (((unsigned long)uc) << 24); -#else /* CONFIG_CPU_LITTLE_ENDIAN */ - uc = *puc++; - ul = ((unsigned long)uc) << 24; - uc = *puc++; - ul |= (((unsigned long)uc) << 16); - uc = *puc++; - ul |= (((unsigned long)uc) << 8); - uc = *puc++; - ul |= ((unsigned long)uc); -#endif /* CONFIG_CPU_LITTLE_ENDIAN */ - ul = signext(ul); - return (void *)ul; -} - -char *arg64(unsigned long addrin, int arg_index) -{ - unsigned long args; - char *p; - - args = signext(addrin); - p = (char *)get_arg(args, arg_index); - - return p; -} -#endif /* CONFIG_64BIT */ - -void __init prom_init(void) -{ - int argc = fw_arg0; - char **arg = (char **) fw_arg1; - char **env = (char **) fw_arg2; - struct callvectors *cv = (struct callvectors *) fw_arg3; - int i; - -#ifdef CONFIG_64BIT - char *ptr; - printk("prom_init - MIPS64\n"); - - /* save the PROM vectors for debugging use */ - debug_vectors = (struct callvectors *)signext((unsigned long)cv); - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - - for (i = 1; i < argc; i++) { - ptr = (char *)arg64((unsigned long)arg, i); - if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= - sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, ptr); - strcat(arcs_cmdline, " "); - } - i = 0; - - while (1) { - ptr = (char *)arg64((unsigned long)env, i); - if (! ptr) - break; - - if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { - marvell_base = simple_strtol(ptr + strlen("gtbase="), - NULL, 16); - - if ((marvell_base & 0xffffffff00000000) == 0) - marvell_base |= 0xffffffff00000000; - - printk("marvell_base set to 0x%016lx\n", marvell_base); - } - if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { - cpu_clock = simple_strtol(ptr + strlen("cpuclock="), - NULL, 10); - printk("cpu_clock set to %d\n", cpu_clock); - } - i++; - } - printk("arcs_cmdline: %s\n", arcs_cmdline); - -#else /* CONFIG_64BIT */ - - /* save the PROM vectors for debugging use */ - debug_vectors = cv; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, arg[i]); - strcat(arcs_cmdline, " "); - } - - while (*env) { - if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { - marvell_base = simple_strtol(*env + strlen("gtbase="), - NULL, 16); - } - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { - cpu_clock = simple_strtol(*env + strlen("cpuclock="), - NULL, 10); - } - env++; - } -#endif /* CONFIG_64BIT */ - - mips_machgroup = MACH_GROUP_MOMENCO; - mips_machtype = MACH_MOMENCO_OCELOT_3; - -#ifndef CONFIG_64BIT - debug_vectors->printf("Booting Linux kernel...\n"); -#endif -} - -void __init prom_free_prom_memory(void) -{ -} - -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ -} diff --git a/arch/mips/momentum/ocelot_3/reset.c b/arch/mips/momentum/ocelot_3/reset.c deleted file mode 100644 index 9d86d2468376..000000000000 --- a/arch/mips/momentum/ocelot_3/reset.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1997, 01, 05 Ralf Baechle - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright (C) 2002 Momentum Computer Inc. - * Author: Matthew Dharm - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Copyright 2004 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - */ -#include -#include -#include -#include -#include -#include -#include -#include - -void momenco_ocelot_restart(char *command) -{ - /* base address of timekeeper portion of part */ - void *nvram = (void *) 0xfc807000L; - - /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); - - /* wait for the watchdog to go off */ - mdelay(100+(1000/16)); - - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); -} - -void momenco_ocelot_halt(void) -{ - printk(KERN_NOTICE "\n** You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); -} - -void momenco_ocelot_power_off(void) -{ - momenco_ocelot_halt(); -} diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c deleted file mode 100644 index ff0829f81116..000000000000 --- a/arch/mips/momentum/ocelot_3/setup.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * setup.c - * - * BRIEF MODULE DESCRIPTION - * Momentum Computer Ocelot-3 board dependent boot routines - * - * Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle - * Copyright (C) 2000 RidgeRun, Inc. - * Copyright (C) 2001 Red Hat, Inc. - * Copyright (C) 2002 Momentum Computer - * - * Author: Matthew Dharm, Momentum Computer - * mdharm@momenco.com - * - * Louis Hamilton, Red Hat, Inc. - * hamilton@redhat.com [MIPS64 modifications] - * - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2004 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ocelot_3_fpga.h" - -/* Marvell Discovery Register Base */ -unsigned long marvell_base = (signed)0xf4000000; - -/* CPU clock */ -unsigned long cpu_clock; - -/* RTC/NVRAM */ -unsigned char* rtc_base = (unsigned char*)(signed)0xfc800000; - -/* FPGA Base */ -unsigned long ocelot_fpga_base = (signed)0xfc000000; - -/* Serial base */ -unsigned long uart_base = (signed)0xfd000000; - -/* - * Marvell Discovery SRAM. This is one place where Ethernet - * Tx and Rx descriptors can be placed to improve performance - */ -extern unsigned long mv64340_sram_base; - -/* These functions are used for rebooting or halting the machine*/ -extern void momenco_ocelot_restart(char *command); -extern void momenco_ocelot_halt(void); -extern void momenco_ocelot_power_off(void); - -void momenco_time_init(void); -static char reset_reason; - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask); - -static inline unsigned long ENTRYLO(unsigned long paddr) -{ - return ((paddr & PAGE_MASK) | - (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL | - _CACHE_UNCACHED)) >> 6; -} - -void __init bus_error_init(void) -{ - /* nothing */ -} - -/* - * setup code for a handoff from a version 2 PMON 2000 PROM - */ -void setup_wired_tlb_entries(void) -{ - write_c0_wired(0); - local_flush_tlb_all(); - - /* marvell and extra space */ - add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), (signed)0xf4000000, PM_64K); - - /* fpga, rtc, and uart */ - add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M); -} - -unsigned long m48t37y_get_time(void) -{ - unsigned int year, month, day, hour, min, sec; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - /* stop the update */ - rtc_base[0x7ff8] = 0x40; - - year = BCD2BIN(rtc_base[0x7fff]); - year += BCD2BIN(rtc_base[0x7ff1]) * 100; - - month = BCD2BIN(rtc_base[0x7ffe]); - - day = BCD2BIN(rtc_base[0x7ffd]); - - hour = BCD2BIN(rtc_base[0x7ffb]); - min = BCD2BIN(rtc_base[0x7ffa]); - sec = BCD2BIN(rtc_base[0x7ff9]); - - /* start the update */ - rtc_base[0x7ff8] = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - return mktime(year, month, day, hour, min, sec); -} - -int m48t37y_set_time(unsigned long sec) -{ - struct rtc_time tm; - unsigned long flags; - - /* convert to a more useful format -- note months count from 0 */ - to_tm(sec, &tm); - tm.tm_mon += 1; - - spin_lock_irqsave(&rtc_lock, flags); - /* enable writing */ - rtc_base[0x7ff8] = 0x80; - - /* year */ - rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); - - /* month */ - rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); - - /* day */ - rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); - - /* hour/min/sec */ - rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); - rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); - rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); - - /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); - - /* disable writing */ - rtc_base[0x7ff8] = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - -void __init plat_timer_setup(struct irqaction *irq) -{ - setup_irq(7, irq); /* Timer interrupt, unmask status IM7 */ -} - -void momenco_time_init(void) -{ - setup_wired_tlb_entries(); - - /* - * Ocelot-3 board has been built with both - * the Rm7900 and the Rm7065C - */ - mips_hpt_frequency = cpu_clock / 2; - - rtc_mips_get_time = m48t37y_get_time; - rtc_mips_set_time = m48t37y_set_time; -} - -/* - * PCI Support for Ocelot-3 - */ - -/* Bus #0 IO and MEM space */ -#define OCELOT_3_PCI_IO_0_START 0xe0000000 -#define OCELOT_3_PCI_IO_0_SIZE 0x08000000 -#define OCELOT_3_PCI_MEM_0_START 0xc0000000 -#define OCELOT_3_PCI_MEM_0_SIZE 0x10000000 - -/* Bus #1 IO and MEM space */ -#define OCELOT_3_PCI_IO_1_START 0xe8000000 -#define OCELOT_3_PCI_IO_1_SIZE 0x08000000 -#define OCELOT_3_PCI_MEM_1_START 0xd0000000 -#define OCELOT_3_PCI_MEM_1_SIZE 0x10000000 - -static struct resource mv_pci_io_mem0_resource = { - .name = "MV64340 PCI0 IO MEM", - .start = OCELOT_3_PCI_IO_0_START, - .end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource mv_pci_io_mem1_resource = { - .name = "MV64340 PCI1 IO MEM", - .start = OCELOT_3_PCI_IO_1_START, - .end = OCELOT_3_PCI_IO_1_START + OCELOT_3_PCI_IO_1_SIZE - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource mv_pci_mem0_resource = { - .name = "MV64340 PCI0 MEM", - .start = OCELOT_3_PCI_MEM_0_START, - .end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct resource mv_pci_mem1_resource = { - .name = "MV64340 PCI1 MEM", - .start = OCELOT_3_PCI_MEM_1_START, - .end = OCELOT_3_PCI_MEM_1_START + OCELOT_3_PCI_MEM_1_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct mv_pci_controller mv_bus0_controller = { - .pcic = { - .pci_ops = &mv_pci_ops, - .mem_resource = &mv_pci_mem0_resource, - .io_resource = &mv_pci_io_mem0_resource, - }, - .config_addr = MV64340_PCI_0_CONFIG_ADDR, - .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, -}; - -static struct mv_pci_controller mv_bus1_controller = { - .pcic = { - .pci_ops = &mv_pci_ops, - .mem_resource = &mv_pci_mem1_resource, - .io_resource = &mv_pci_io_mem1_resource, - }, - .config_addr = MV64340_PCI_1_CONFIG_ADDR, - .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, -}; - -static __init int __init ja_pci_init(void) -{ - uint32_t enable; - extern int pci_probe_only; - - /* PMON will assign PCI resources */ - pci_probe_only = 1; - - enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); - /* - * We require at least one enabled I/O or PCI memory window or we - * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3. - */ - if (enable & (0x01 << 9) || enable & (0x01 << 10)) - register_pci_controller(&mv_bus0_controller.pcic); - - if (enable & (0x01 << 14) || enable & (0x01 << 15)) - register_pci_controller(&mv_bus1_controller.pcic); - - ioport_resource.end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE + - OCELOT_3_PCI_IO_1_SIZE - 1; - - iomem_resource.end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE + - OCELOT_3_PCI_MEM_1_SIZE - 1; - - set_io_port_base(OCELOT_3_PCI_IO_0_START); /* mips_io_port_base */ - - return 0; -} - -arch_initcall(ja_pci_init); - -void __init plat_mem_setup(void) -{ - unsigned int tmpword; - - board_time_init = momenco_time_init; - - _machine_restart = momenco_ocelot_restart; - _machine_halt = momenco_ocelot_halt; - pm_power_off = momenco_ocelot_power_off; - - /* Wired TLB entries */ - setup_wired_tlb_entries(); - - /* shut down ethernet ports, just to be sure our memory doesn't get - * corrupted by random ethernet traffic. - */ - MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); - MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); - do {} - while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); - do {} - while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); - MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), - MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); - MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), - MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); - - /* Turn off the Bit-Error LED */ - OCELOT_FPGA_WRITE(0x80, CLR); - - tmpword = OCELOT_FPGA_READ(BOARDREV); - if (tmpword < 26) - printk("Momenco Ocelot-3: Board Assembly Rev. %c\n", - 'A'+tmpword); - else - printk("Momenco Ocelot-3: Board Assembly Revision #0x%x\n", - tmpword); - - tmpword = OCELOT_FPGA_READ(FPGA_REV); - printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); - tmpword = OCELOT_FPGA_READ(RESET_STATUS); - printk("Reset reason: 0x%x\n", tmpword); - switch (tmpword) { - case 0x1: - printk(" - Power-up reset\n"); - break; - case 0x2: - printk(" - Push-button reset\n"); - break; - case 0x4: - printk(" - cPCI bus reset\n"); - break; - case 0x8: - printk(" - Watchdog reset\n"); - break; - case 0x10: - printk(" - Software reset\n"); - break; - default: - printk(" - Unknown reset cause\n"); - } - reset_reason = tmpword; - OCELOT_FPGA_WRITE(0xff, RESET_STATUS); - - tmpword = OCELOT_FPGA_READ(CPCI_ID); - printk("cPCI ID register: 0x%02x\n", tmpword); - printk(" - Slot number: %d\n", tmpword & 0x1f); - printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no"); - printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no"); - - tmpword = OCELOT_FPGA_READ(BOARD_STATUS); - printk("Board Status register: 0x%02x\n", tmpword); - printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); - printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); - printk(" - L3 cache size: %d MB\n", (1<<((tmpword&12) >> 2))&~1); - - /* Support for 128 MB memory */ - add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM); -} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index cfebf58c8dc6..f26ede001a0b 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -9,7 +9,6 @@ obj-y += pci.o pci-dac.o # obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o -obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o @@ -29,7 +28,6 @@ obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o -obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c deleted file mode 100644 index 702f997b8673..000000000000 --- a/arch/mips/pci/fixup-ocelot3.c +++ /dev/null @@ -1,41 +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) 2004 Montavista Software Inc. - * Author: Manish Lachwani (mlachwani@mvista.com) - * - * Looking at the schematics for the Ocelot-3 board, there are - * two PCI busses and each bus has two PCI slots. - */ -#include -#include -#include -#include - -/* - * Do platform specific device initialization at - * pci_enable_device() time - */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - int bus = dev->bus->number; - - if (bus == 0 && slot == 1) - return 2; /* PCI-X A */ - if (bus == 0 && slot == 2) - return 3; /* PCI-X B */ - if (bus == 1 && slot == 1) - return 4; /* PCI A */ - if (bus == 1 && slot == 2) - return 5; /* PCI B */ - -return 0; - panic("Whooops in pcibios_map_irq"); -} diff --git a/arch/mips/pci/ops-marvell.c b/arch/mips/pci/ops-marvell.c deleted file mode 100644 index 1ac5c59199d1..000000000000 --- a/arch/mips/pci/ops-marvell.c +++ /dev/null @@ -1,93 +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) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) - */ -#include -#include -#include - -#include - -static int mv_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - struct mv_pci_controller *mvbc = bus->sysdata; - unsigned long address_reg, data_reg; - u32 address; - - address_reg = mvbc->config_addr; - data_reg = mvbc->config_vreg; - - /* Accessing device 31 crashes those Marvells. Since years. - Will they ever make sane controllers ... */ - if (PCI_SLOT(devfn) == 31) - return PCIBIOS_DEVICE_NOT_FOUND; - - address = (bus->number << 16) | (devfn << 8) | - (where & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - MV_WRITE(address_reg, address); - - switch (size) { - case 1: - *val = MV_READ_8(data_reg + (where & 0x3)); - break; - - case 2: - *val = MV_READ_16(data_reg + (where & 0x3)); - break; - - case 4: - *val = MV_READ(data_reg); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int mv_write_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - struct mv_pci_controller *mvbc = bus->sysdata; - unsigned long address_reg, data_reg; - u32 address; - - address_reg = mvbc->config_addr; - data_reg = mvbc->config_vreg; - - /* Accessing device 31 crashes those Marvells. Since years. - Will they ever make sane controllers ... */ - if (PCI_SLOT(devfn) == 31) - return PCIBIOS_DEVICE_NOT_FOUND; - - address = (bus->number << 16) | (devfn << 8) | - (where & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - MV_WRITE(address_reg, address); - - switch (size) { - case 1: - MV_WRITE_8(data_reg + (where & 0x3), val); - break; - - case 2: - MV_WRITE_16(data_reg + (where & 0x3), val); - break; - - case 4: - MV_WRITE(data_reg, val); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops mv_pci_ops = { - .read = mv_read_config, - .write = mv_write_config -}; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3d5db2597b88..627316db3744 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2307,7 +2307,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "MV-643XX Ethernet support" - depends on MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) + depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) select MII help This driver supports the gigabit Ethernet on the Marvell MV643XX diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h deleted file mode 100644 index 57a12ded0613..000000000000 --- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h +++ /dev/null @@ -1,48 +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) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.com - * Copyright (C) 2004 Ralf Baechle - */ -#ifndef __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H - -/* - * Momentum Ocelot-3 is based on Rm7900 processor which - * is based on the E9000 core. - */ -#define cpu_has_watch 1 -#define cpu_has_mips16 0 -#define cpu_has_divec 0 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_prefetch 1 -#define cpu_has_mcheck 0 -#define cpu_has_ejtag 0 - -#define cpu_has_llsc 1 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_dsp 0 -#define cpu_icache_snoops_remote_store 0 - -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 1 - -#define cpu_has_inclusive_pcaches 0 - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 - -#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */ diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index 45cb82724830..9de52a5b0f3d 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -183,8 +183,8 @@ */ #if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MIPS_ATLAS) || \ defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MOMENCO_OCELOT) || \ - defined(CONFIG_MOMENCO_OCELOT_3) || defined(CONFIG_PMC_YOSEMITE) || \ - defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC) + defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_SGI_IP32) || \ + defined(CONFIG_WR_PPMC) #define ICACHE_REFILLS_WORKAROUND_WAR 1 #endif diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index c6d4ab86b83c..b021b3a2b65a 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h @@ -13,10 +13,6 @@ #ifndef __ASM_MV643XX_H #define __ASM_MV643XX_H -#ifdef __mips__ -#include -#include -#endif #include /****************************************/ From 46cc84bf412f95610b25e59d575aada6a5512f3a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 9 Jul 2007 19:20:20 +0100 Subject: [PATCH 523/551] [MIPS] MIPSsim: Enable MIPSsim virtual network driver. Signed-off-by: Ralf Baechle --- arch/mips/configs/mipssim_defconfig | 33 +++++++++-------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index bc3246b2c808..6abad6f88313 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -492,36 +492,23 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # -# CONFIG_NET_ETHERNET is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MIPS_SIM_NET=y +# CONFIG_DM9000 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set From bf74b964775009071cf12f9d59d4dd5e388fbe0b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 08:14:15 +0100 Subject: [PATCH 524/551] [MIPS] DEC: Fix modpost warning. LD vmlinux SYSMAP System.map SYSMAP .tmp_System.map MODPOST vmlinux WARNING: drivers/built-in.o(.data+0x2480): Section mismatch: reference to .init.text: (between 'sercons' and 'ds_parms') Signed-off-by: Ralf Baechle --- drivers/tc/zs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 61de78a9f6ee..4fff61b32dcb 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -143,7 +143,7 @@ static struct console sercons; static unsigned long break_pressed; /* break, really ... */ #endif -static unsigned char zs_init_regs[16] __initdata = { +static unsigned char zs_init_regs[16] = { 0, /* write 0 */ 0, /* write 1 */ 0, /* write 2 */ @@ -1581,7 +1581,7 @@ static void __init show_serial_version(void) /* Initialize Z8530s zs_channels */ -static void __init probe_sccs(void) +static void probe_sccs(void) { struct dec_serial **pp; int i, n, n_chips = 0, n_channels, chip, channel; @@ -1923,7 +1923,7 @@ static struct tty_driver *serial_console_device(struct console *c, int *index) * - initialize the serial port * Return non-zero if we didn't find a serial port. */ -static int __init serial_console_setup(struct console *co, char *options) +static int serial_console_setup(struct console *co, char *options) { struct dec_serial *info; int baud = 9600; From 35c700c0955c43e168c45d375f90a0670be8f054 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 08:59:17 +0100 Subject: [PATCH 525/551] [MIPS] Non-FPAFF: Fix warning. Signed-off-by: Ralf Baechle --- include/asm-mips/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index be64fc55562a..46bdb3f566f9 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -56,7 +56,7 @@ do { \ } while(0) #else -#define __mips_mt_fpaff_switch_to(prev) do { (prev); } while (0) +#define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0) #endif #define switch_to(prev,next,last) \ From 070c7b8611e852099370b17eaeb470407cb80ffe Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 09:35:12 +0100 Subject: [PATCH 526/551] [MIPS] Alchemy: Fix modpost warnings. MODPOST vmlinux WARNING: arch/mips/au1000/common/built-in.o(.text+0x1750): Section mismatch: reference to .init.data: (between 'au1xxx_platform_init' and '__fixup_bigphys_addr') WARNING: arch/mips/au1000/common/built-in.o(.text+0x1754): Section mismatch: reference to .init.data: (between 'au1xxx_platform_init' and '__fixup_bigphys_addr') Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 8fd203d4a339..d51e18fb789b 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -289,7 +289,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { #endif }; -int au1xxx_platform_init(void) +int __init au1xxx_platform_init(void) { return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices)); } From f2c4b47f26c9d3ba32fb51e574d8cacce30f744d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 15:04:06 +0100 Subject: [PATCH 527/551] [MIPS] PNX: Fix modpost warnings. MODPOST vmlinux WARNING: arch/mips/philips/pnx8550/common/built-in.o(.text+0xd40): Section mismatch: reference to .init.data: (after 'pnx8550_platform_init') WARNING: arch/mips/philips/pnx8550/common/built-in.o(.text+0xd44): Section mismatch: reference to .init.data: (after 'pnx8550_platform_init') Signed-off-by: Ralf Baechle --- arch/mips/philips/pnx8550/common/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c index d43f56e2cd78..c839436bd012 100644 --- a/arch/mips/philips/pnx8550/common/platform.c +++ b/arch/mips/philips/pnx8550/common/platform.c @@ -123,7 +123,7 @@ static struct platform_device *pnx8550_platform_devices[] __initdata = { &pnx8550_uart_device, }; -int pnx8550_platform_init(void) +static int __init pnx8550_platform_init(void) { return platform_add_devices(pnx8550_platform_devices, ARRAY_SIZE(pnx8550_platform_devices)); From 62b396358e837549f20068ed9c3d2bcf99d9ad2d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 16:10:56 +0100 Subject: [PATCH 528/551] [MIPS] SB1: Fix modpost warning. MODPOST vmlinux WARNING: arch/mips/mm/built-in.o(.text+0x1978): Section mismatch: reference to .init.text:except_vec2_sb1 (between 'sb1_cache_init' and 'sb1_flush_cache_sigtramp') WARNING: arch/mips/mm/built-in.o(.text+0x1988): Section mismatch: reference to .init.text:except_vec2_sb1 (between 'sb1_cache_init' and 'sb1_flush_cache_sigtramp') Signed-off-by: Ralf Baechle --- arch/mips/mm/c-sb1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 9ea460b16bda..6f9bd7fbd481 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -476,7 +476,7 @@ static __init void probe_cache_sizes(void) * memory management function pointers, as well as initialize * the caches and tlbs */ -void sb1_cache_init(void) +void __init sb1_cache_init(void) { extern char except_vec2_sb1; From 7e95a016f844fc660bf80065413998a784a78988 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 11 Jul 2007 00:24:14 +0900 Subject: [PATCH 529/551] [MIPS] Change names of local variables to silence sparse This patch is an workaround for these sparse warnings: linux/include/linux/calc64.h:25:17: warning: symbol '__quot' shadows an earlier one linux/include/linux/calc64.h:25:17: originally declared here linux/include/linux/calc64.h:25:17: warning: symbol '__mod' shadows an earlier one linux/include/linux/calc64.h:25:17: originally declared here Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/div64.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h index 66189f5f6399..716371bd0980 100644 --- a/include/asm-mips/div64.h +++ b/include/asm-mips/div64.h @@ -20,7 +20,7 @@ */ #define do_div64_32(res, high, low, base) ({ \ - unsigned long __quot, __mod; \ + unsigned long __quot32, __mod32; \ unsigned long __cf, __tmp, __tmp2, __i; \ \ __asm__(".set push\n\t" \ @@ -48,12 +48,13 @@ "bnez %4, 0b\n\t" \ " srl %5, %1, 0x1f\n\t" \ ".set pop" \ - : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \ + : "=&r" (__mod32), "=&r" (__tmp), \ + "=&r" (__quot32), "=&r" (__cf), \ "=&r" (__i), "=&r" (__tmp2) \ : "Jr" (base), "0" (high), "1" (low)); \ \ - (res) = __quot; \ - __mod; }) + (res) = __quot32; \ + __mod32; }) #define do_div(n, base) ({ \ unsigned long long __quot; \ From 44659f29a0a26dcdbf516a82b0ff96d6ba464724 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 16:31:19 +0100 Subject: [PATCH 530/551] [MIPS] Yosemite: Fix modpost warnings. MODPOST vmlinux WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x974): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x980): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x978): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x984): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x98c): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') WARNING: arch/mips/pmc-sierra/yosemite/built-in.o(.text+0x990): Section mismatch: reference to .init.data: (between 'prom_boot_secondary' and 'prom_cpus_done') Signed-off-by: Ralf Baechle --- arch/mips/pmc-sierra/yosemite/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 305491e74dbe..d83c4ada14f3 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -77,7 +77,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) * stack so the first thing we do is throw away that stuff and load useful * values into the registers ... */ -void prom_boot_secondary(int cpu, struct task_struct *idle) +void __init prom_boot_secondary(int cpu, struct task_struct *idle) { unsigned long gp = (unsigned long) task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); From 569fb7536ea66e3364a8ff0b26598c6c9874d657 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 10 Jul 2007 16:56:33 +0100 Subject: [PATCH 531/551] [MIPS] WRPPMC: Fix build. Using another systems defines is a safe way to get your code broken by accident when that system is removed. Signed-off-by: Ralf Baechle --- arch/mips/gt64120/wrppmc/setup.c | 4 ++-- include/asm-mips/bootinfo.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c index 121188d5ec4a..ea965529e5e0 100644 --- a/arch/mips/gt64120/wrppmc/setup.c +++ b/arch/mips/gt64120/wrppmc/setup.c @@ -158,8 +158,8 @@ const char *get_system_type(void) */ void __init prom_init(void) { - mips_machgroup = MACH_GROUP_GALILEO; - mips_machtype = MACH_EV64120A; + mips_machgroup = MACH_GROUP_WINDRIVER; + mips_machtype = MACH_WRPPMC; add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 075a4d3de326..087126a5faf9 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -218,6 +218,9 @@ #define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */ #define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */ +#define MACH_GROUP_WINDRIVER 28 /* Windriver boards */ +#define MACH_WRPPMC 1 + #define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); From 105b1bca4d7bed85bb296f7e7caec2fc643e9fbf Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 10 Jul 2007 06:37:56 -0400 Subject: [PATCH 532/551] [MIPS] PNX8550: Cleanup proc code. Here's a slightly cleaner way of creating the /proc structure for the pnx8850. mostly, it creates a directory with default mode 555, since the one you're creating is mode 444, which is somewhat unusual for a directory under /proc. Signed-off-by: Ralf Baechle --- arch/mips/philips/pnx8550/common/proc.c | 30 ++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c index 3f097558ef13..92311e95b700 100644 --- a/arch/mips/philips/pnx8550/common/proc.c +++ b/arch/mips/philips/pnx8550/common/proc.c @@ -78,29 +78,33 @@ static int pnx8550_proc_init( void ) { // Create /proc/pnx8550 - pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL); + pnx8550_dir = proc_mkdir("pnx8550", NULL); if (!pnx8550_dir) { printk(KERN_ERR "Can't create pnx8550 proc dir\n"); return -1; } // Create /proc/pnx8550/timers - pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir ); - if (pnx8550_timers){ - pnx8550_timers->read_proc = pnx8550_timers_read; - } - else { + pnx8550_timers = create_proc_read_entry( + "timers", + 0, + pnx8550_dir, + pnx8550_timers_read, + NULL); + + if (!pnx8550_timers) printk(KERN_ERR "Can't create pnx8550 timers proc file\n"); - } // Create /proc/pnx8550/registers - pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir ); - if (pnx8550_registers){ - pnx8550_registers->read_proc = pnx8550_registers_read; - } - else { + pnx8550_registers = create_proc_read_entry( + "registers", + 0, + pnx8550_dir, + pnx8550_registers_read, + NULL); + + if (!pnx8550_registers) printk(KERN_ERR "Can't create pnx8550 registers proc file\n"); - } return 0; } From 825a2ff1896ec3ead94bebef60c71f57254da58a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 3 Jul 2007 16:53:09 +0100 Subject: [PATCH 533/551] AX88796 network driver Support for the Asix AX88796 network controller, an NE2000 compatible 10/100 ethernet device with internal PHY. The driver supports PHY settings via either ioctl() or the ethtool driver ops. Signed-off-by: Ben Dooks Signed-off-by: Jeff Garzik --- drivers/net/8390.h | 11 + drivers/net/Kconfig | 8 + drivers/net/Makefile | 1 + drivers/net/ax88796.c | 952 ++++++++++++++++++++++++++++++++++++++++++ include/net/ax88796.h | 27 ++ 5 files changed, 999 insertions(+) create mode 100644 drivers/net/ax88796.c create mode 100644 include/net/ax88796.h diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 414de5bd228f..04ddec0f4c61 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -73,6 +73,9 @@ struct ei_device { u32 *reg_offset; /* Register mapping table */ spinlock_t page_lock; /* Page register locks */ unsigned long priv; /* Private field to store bus IDs etc. */ +#ifdef AX88796_PLATFORM + unsigned char rxcr_base; /* default value for RXCR */ +#endif }; /* The maximum number of 8390 interrupt service routines called per IRQ. */ @@ -86,11 +89,19 @@ struct ei_device { /* Some generic ethernet register configurations. */ #define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ #define E8390_RX_IRQ_MASK 0x5 + +#ifdef AX88796_PLATFORM +#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04) +#define E8390_RXOFF (ei_status.rxcr_base | 0x20) +#else #define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ #define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ +#endif + #define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ #define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ + /* Register accessed at EN_CMD, the 8390 base addr. */ #define E8390_STOP 0x01 /* Stop and reset the chip */ #define E8390_START 0x02 /* Start the chip, clear reset */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4f23ad7b13c1..09c68984c887 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -197,6 +197,14 @@ config MACB source "drivers/net/arm/Kconfig" +config AX88796 + tristate "ASIX AX88796 NE2000 clone support" + select CRC32 + select MII + help + AX88796 driver, using platform bus to provide + chip detection and resources + config MACE tristate "MACE (Power Mac ethernet) support" depends on PPC_PMAC && PPC32 diff --git a/drivers/net/Makefile b/drivers/net/Makefile index eb62fb48e4b7..515ca660b936 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -107,6 +107,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o obj-$(CONFIG_B44) += b44.o obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o +obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c new file mode 100644 index 000000000000..d19874bf0706 --- /dev/null +++ b/drivers/net/ax88796.c @@ -0,0 +1,952 @@ +/* drivers/net/ax88796.c + * + * Copyright 2005,2007 Simtec Electronics + * Ben Dooks + * + * Asix AX88796 10/100 Ethernet controller support + * Based on ne.c, by Donald Becker, et-al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +static int phy_debug = 0; + +/* Rename the lib8390.c functions to show that they are in this driver */ +#define __ei_open ax_ei_open +#define __ei_close ax_ei_close +#define __ei_poll ax_ei_poll +#define __ei_tx_timeout ax_ei_tx_timeout +#define __ei_interrupt ax_ei_interrupt +#define ____alloc_ei_netdev ax__alloc_ei_netdev +#define __NS8390_init ax_NS8390_init + +/* force unsigned long back to 'void __iomem *' */ +#define ax_convert_addr(_a) ((void __force __iomem *)(_a)) + +#define ei_inb(_a) readb(ax_convert_addr(_a)) +#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a)) + +#define ei_inb_p(_a) ei_inb(_a) +#define ei_outb_p(_v, _a) ei_outb(_v, _a) + +/* define EI_SHIFT() to take into account our register offsets */ +#define EI_SHIFT(x) (ei_local->reg_offset[(x)]) + +/* Ensure we have our RCR base value */ +#define AX88796_PLATFORM + +static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n"; + +#include "lib8390.c" + +#define DRV_NAME "ax88796" +#define DRV_VERSION "1.00" + +/* from ne.c */ +#define NE_CMD EI_SHIFT(0x00) +#define NE_RESET EI_SHIFT(0x1f) +#define NE_DATAPORT EI_SHIFT(0x10) + +#define NE1SM_START_PG 0x20 /* First page of TX buffer */ +#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ +#define NESM_START_PG 0x40 /* First page of TX buffer */ +#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ + +/* device private data */ + +struct ax_device { + struct timer_list mii_timer; + spinlock_t mii_lock; + struct mii_if_info mii; + + u32 msg_enable; + void __iomem *map2; + struct platform_device *dev; + struct resource *mem; + struct resource *mem2; + struct ax_plat_data *plat; + + unsigned char running; + unsigned char resume_open; + + u32 reg_offsets[0x20]; +}; + +static inline struct ax_device *to_ax_dev(struct net_device *dev) +{ + struct ei_device *ei_local = netdev_priv(dev); + return (struct ax_device *)(ei_local+1); +} + +/* ax_initial_check + * + * do an initial probe for the card to check wether it exists + * and is functional + */ + +static int ax_initial_check(struct net_device *dev) +{ + struct ei_device *ei_local = netdev_priv(dev); + void __iomem *ioaddr = ei_local->mem; + int reg0; + int regd; + + reg0 = ei_inb(ioaddr); + if (reg0 == 0xFF) + return -ENODEV; + + ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); + regd = ei_inb(ioaddr + 0x0d); + ei_outb(0xff, ioaddr + 0x0d); + ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); + ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ + if (ei_inb(ioaddr + EN0_COUNTER0) != 0) { + ei_outb(reg0, ioaddr); + ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */ + return -ENODEV; + } + + return 0; +} + +/* Hard reset the card. This used to pause for the same period that a + 8390 reset command required, but that shouldn't be necessary. */ + +static void ax_reset_8390(struct net_device *dev) +{ + struct ei_device *ei_local = netdev_priv(dev); + unsigned long reset_start_time = jiffies; + void __iomem *addr = (void __iomem *)dev->base_addr; + + if (ei_debug > 1) + printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); + + ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); + + ei_status.txing = 0; + ei_status.dmaing = 0; + + /* This check _should_not_ be necessary, omit eventually. */ + while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { + if (jiffies - reset_start_time > 2*HZ/100) { + printk(KERN_WARNING "%s: %s did not complete.\n", + __FUNCTION__, dev->name); + break; + } + } + + ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */ +} + + +static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, + int ring_page) +{ + struct ei_device *ei_local = netdev_priv(dev); + void __iomem *nic_base = ei_local->mem; + + /* This *shouldn't* happen. If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n", + dev->name, __FUNCTION__, + ei_status.dmaing, ei_status.irqlock); + return; + } + + ei_status.dmaing |= 0x01; + ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); + ei_outb(0, nic_base + EN0_RCNTHI); + ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */ + ei_outb(ring_page, nic_base + EN0_RSARHI); + ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + if (ei_status.word16) + readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); + else + readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); + + ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; + + le16_to_cpus(&hdr->count); +} + + +/* Block input and output, similar to the Crynwr packet driver. If you + are porting to a new ethercard, look at the packet driver source for hints. + The NEx000 doesn't share the on-board packet memory -- you have to put + the packet out through the "remote DMA" dataport using ei_outb. */ + +static void ax_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset) +{ + struct ei_device *ei_local = netdev_priv(dev); + void __iomem *nic_base = ei_local->mem; + char *buf = skb->data; + + if (ei_status.dmaing) { + printk(KERN_EMERG "%s: DMAing conflict in ax_block_input " + "[DMAstat:%d][irqlock:%d].\n", + dev->name, ei_status.dmaing, ei_status.irqlock); + return; + } + + ei_status.dmaing |= 0x01; + + ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + ei_outb(count & 0xff, nic_base + EN0_RCNTLO); + ei_outb(count >> 8, nic_base + EN0_RCNTHI); + ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO); + ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI); + ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + if (ei_status.word16) { + readsw(nic_base + NE_DATAPORT, buf, count >> 1); + if (count & 0x01) + buf[count-1] = ei_inb(nic_base + NE_DATAPORT); + + } else { + readsb(nic_base + NE_DATAPORT, buf, count); + } + + ei_status.dmaing &= ~1; +} + +static void ax_block_output(struct net_device *dev, int count, + const unsigned char *buf, const int start_page) +{ + struct ei_device *ei_local = netdev_priv(dev); + void __iomem *nic_base = ei_local->mem; + unsigned long dma_start; + + /* Round the count up for word writes. Do we need to do this? + What effect will an odd byte count have on the 8390? + I should check someday. */ + + if (ei_status.word16 && (count & 0x01)) + count++; + + /* This *shouldn't* happen. If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk(KERN_EMERG "%s: DMAing conflict in %s." + "[DMAstat:%d][irqlock:%d]\n", + dev->name, __FUNCTION__, + ei_status.dmaing, ei_status.irqlock); + return; + } + + ei_status.dmaing |= 0x01; + /* We should already be in page 0, but to be safe... */ + ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); + + ei_outb(ENISR_RDC, nic_base + EN0_ISR); + + /* Now the normal output. */ + ei_outb(count & 0xff, nic_base + EN0_RCNTLO); + ei_outb(count >> 8, nic_base + EN0_RCNTHI); + ei_outb(0x00, nic_base + EN0_RSARLO); + ei_outb(start_page, nic_base + EN0_RSARHI); + + ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); + if (ei_status.word16) { + writesw(nic_base + NE_DATAPORT, buf, count>>1); + } else { + writesb(nic_base + NE_DATAPORT, buf, count); + } + + dma_start = jiffies; + + while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ + printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); + ax_reset_8390(dev); + ax_NS8390_init(dev,1); + break; + } + } + + ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; + return; +} + +/* definitions for accessing MII/EEPROM interface */ + +#define AX_MEMR EI_SHIFT(0x14) +#define AX_MEMR_MDC (1<<0) +#define AX_MEMR_MDIR (1<<1) +#define AX_MEMR_MDI (1<<2) +#define AX_MEMR_MDO (1<<3) +#define AX_MEMR_EECS (1<<4) +#define AX_MEMR_EEI (1<<5) +#define AX_MEMR_EEO (1<<6) +#define AX_MEMR_EECLK (1<<7) + +/* ax_mii_ei_outbits + * + * write the specified set of bits to the phy +*/ + +static void +ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) +{ + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; + unsigned int memr; + + /* clock low, data to output mode */ + memr = ei_inb(memr_addr); + memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR); + ei_outb(memr, memr_addr); + + for (len--; len >= 0; len--) { + if (bits & (1 << len)) + memr |= AX_MEMR_MDO; + else + memr &= ~AX_MEMR_MDO; + + ei_outb(memr, memr_addr); + + /* clock high */ + + ei_outb(memr | AX_MEMR_MDC, memr_addr); + udelay(1); + + /* clock low */ + ei_outb(memr, memr_addr); + } + + /* leaves the clock line low, mdir input */ + memr |= AX_MEMR_MDIR; + ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR); +} + +/* ax_phy_ei_inbits + * + * read a specified number of bits from the phy +*/ + +static unsigned int +ax_phy_ei_inbits(struct net_device *dev, int no) +{ + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); + void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; + unsigned int memr; + unsigned int result = 0; + + /* clock low, data to input mode */ + memr = ei_inb(memr_addr); + memr &= ~AX_MEMR_MDC; + memr |= AX_MEMR_MDIR; + ei_outb(memr, memr_addr); + + for (no--; no >= 0; no--) { + ei_outb(memr | AX_MEMR_MDC, memr_addr); + + udelay(1); + + if (ei_inb(memr_addr) & AX_MEMR_MDI) + result |= (1<page_lock, flags); + + ax_phy_issueaddr(dev, phy_addr, reg, 2); + + result = ax_phy_ei_inbits(dev, 17); + result &= ~(3<<16); + + spin_unlock_irqrestore(&ei_local->page_lock, flags); + + if (phy_debug) + pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__, + phy_addr, reg, result); + + return result; +} + +static void +ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) +{ + struct ei_device *ei = (struct ei_device *) netdev_priv(dev); + unsigned long flags; + + printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n", + __FUNCTION__, dev, phy_addr, reg, value); + + spin_lock_irqsave(&ei->page_lock, flags); + + ax_phy_issueaddr(dev, phy_addr, reg, 1); + ax_mii_ei_outbits(dev, 2, 2); /* send TA */ + ax_mii_ei_outbits(dev, value, 16); + + spin_unlock_irqrestore(&ei->page_lock, flags); +} + +static void ax_mii_expiry(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct ax_device *ax = to_ax_dev(dev); + unsigned long flags; + + spin_lock_irqsave(&ax->mii_lock, flags); + mii_check_media(&ax->mii, netif_msg_link(ax), 0); + spin_unlock_irqrestore(&ax->mii_lock, flags); + + if (ax->running) { + ax->mii_timer.expires = jiffies + HZ*2; + add_timer(&ax->mii_timer); + } +} + +static int ax_open(struct net_device *dev) +{ + struct ax_device *ax = to_ax_dev(dev); + struct ei_device *ei_local = netdev_priv(dev); + int ret; + + dev_dbg(ax->dev, "%s: open\n", dev->name); + + ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev); + if (ret) + return ret; + + ret = ax_ei_open(dev); + if (ret) + return ret; + + /* turn the phy on (if turned off) */ + + ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17)); + ax->running = 1; + + /* start the MII timer */ + + init_timer(&ax->mii_timer); + + ax->mii_timer.expires = jiffies+1; + ax->mii_timer.data = (unsigned long) dev; + ax->mii_timer.function = ax_mii_expiry; + + add_timer(&ax->mii_timer); + + return 0; +} + +static int ax_close(struct net_device *dev) +{ + struct ax_device *ax = to_ax_dev(dev); + struct ei_device *ei_local = netdev_priv(dev); + + dev_dbg(ax->dev, "%s: close\n", dev->name); + + /* turn the phy off */ + + ei_outb(ax->plat->gpoc_val | (1<<6), + ei_local->mem + EI_SHIFT(0x17)); + + ax->running = 0; + wmb(); + + del_timer_sync(&ax->mii_timer); + ax_ei_close(dev); + + free_irq(dev->irq, dev); + return 0; +} + +static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd) +{ + struct ax_device *ax = to_ax_dev(dev); + unsigned long flags; + int rc; + + if (!netif_running(dev)) + return -EINVAL; + + spin_lock_irqsave(&ax->mii_lock, flags); + rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL); + spin_unlock_irqrestore(&ax->mii_lock, flags); + + return rc; +} + +/* ethtool ops */ + +static void ax_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct ax_device *ax = to_ax_dev(dev); + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, ax->dev->name); +} + +static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ax_device *ax = to_ax_dev(dev); + unsigned long flags; + + spin_lock_irqsave(&ax->mii_lock, flags); + mii_ethtool_gset(&ax->mii, cmd); + spin_lock_irqsave(&ax->mii_lock, flags); + + return 0; +} + +static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ax_device *ax = to_ax_dev(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&ax->mii_lock, flags); + rc = mii_ethtool_sset(&ax->mii, cmd); + spin_lock_irqsave(&ax->mii_lock, flags); + + return rc; +} + +static int ax_nway_reset(struct net_device *dev) +{ + struct ax_device *ax = to_ax_dev(dev); + return mii_nway_restart(&ax->mii); +} + +static u32 ax_get_link(struct net_device *dev) +{ + struct ax_device *ax = to_ax_dev(dev); + return mii_link_ok(&ax->mii); +} + +static const struct ethtool_ops ax_ethtool_ops = { + .get_drvinfo = ax_get_drvinfo, + .get_settings = ax_get_settings, + .set_settings = ax_set_settings, + .nway_reset = ax_nway_reset, + .get_link = ax_get_link, + .get_perm_addr = ethtool_op_get_perm_addr, +}; + +/* setup code */ + +static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) +{ + void __iomem *ioaddr = ei_local->mem; + struct ax_device *ax = to_ax_dev(dev); + + /* Select page 0*/ + ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD); + + /* set to byte access */ + ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG); + ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17)); +} + +/* ax_init_dev + * + * initialise the specified device, taking care to note the MAC + * address it may already have (if configured), ensure + * the device is ready to be used by lib8390.c and registerd with + * the network layer. + */ + +static int ax_init_dev(struct net_device *dev, int first_init) +{ + struct ei_device *ei_local = netdev_priv(dev); + struct ax_device *ax = to_ax_dev(dev); + void __iomem *ioaddr = ei_local->mem; + unsigned int start_page; + unsigned int stop_page; + int ret; + int i; + + ret = ax_initial_check(dev); + if (ret) + goto err_out; + + /* setup goes here */ + + ax_initial_setup(dev, ei_local); + + /* read the mac from the card prom if we need it */ + + if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) { + unsigned char SA_prom[32]; + + for(i = 0; i < sizeof(SA_prom); i+=2) { + SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT); + SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT); + } + + if (ax->plat->wordlength == 2) + for (i = 0; i < 16; i++) + SA_prom[i] = SA_prom[i+i]; + + memcpy(dev->dev_addr, SA_prom, 6); + } + + if (ax->plat->wordlength == 2) { + /* We must set the 8390 for word mode. */ + ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG); + start_page = NESM_START_PG; + stop_page = NESM_STOP_PG; + } else { + start_page = NE1SM_START_PG; + stop_page = NE1SM_STOP_PG; + } + + /* load the mac-address from the device if this is the + * first time we've initialised */ + + if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) { + ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, + ei_local->mem + E8390_CMD); /* 0x61 */ + + for (i = 0 ; i < ETHER_ADDR_LEN ; i++) + dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); + } + + ax_reset_8390(dev); + + ei_status.name = "AX88796"; + ei_status.tx_start_page = start_page; + ei_status.stop_page = stop_page; + ei_status.word16 = (ax->plat->wordlength == 2); + ei_status.rx_start_page = start_page + TX_PAGES; + +#ifdef PACKETBUF_MEMSIZE + /* Allow the packet buffer size to be overridden by know-it-alls. */ + ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; +#endif + + ei_status.reset_8390 = &ax_reset_8390; + ei_status.block_input = &ax_block_input; + ei_status.block_output = &ax_block_output; + ei_status.get_8390_hdr = &ax_get_8390_hdr; + ei_status.priv = 0; + + dev->open = ax_open; + dev->stop = ax_close; + dev->do_ioctl = ax_ioctl; + dev->ethtool_ops = &ax_ethtool_ops; + + ax->msg_enable = NETIF_MSG_LINK; + ax->mii.phy_id_mask = 0x1f; + ax->mii.reg_num_mask = 0x1f; + ax->mii.phy_id = 0x10; /* onboard phy */ + ax->mii.force_media = 0; + ax->mii.full_duplex = 0; + ax->mii.mdio_read = ax_phy_read; + ax->mii.mdio_write = ax_phy_write; + ax->mii.dev = dev; + +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = ax_ei_poll; +#endif + ax_NS8390_init(dev, 0); + + if (first_init) { + printk("AX88796: %dbit, irq %d, %lx, MAC: ", + ei_status.word16 ? 16:8, dev->irq, dev->base_addr); + + for (i = 0; i < ETHER_ADDR_LEN; i++) + printk("%2.2x%c", dev->dev_addr[i], + (i < (ETHER_ADDR_LEN-1) ? ':' : ' ')); + + printk("\n"); + } + + ret = register_netdev(dev); + if (ret) + goto out_irq; + + return 0; + + out_irq: + /* cleanup irq */ + free_irq(dev->irq, dev); + err_out: + return ret; +} + +static int ax_remove(struct platform_device *_dev) +{ + struct net_device *dev = platform_get_drvdata(_dev); + struct ax_device *ax; + + ax = to_ax_dev(dev); + + unregister_netdev(dev); + free_irq(dev->irq, dev); + + iounmap(ei_status.mem); + release_resource(ax->mem); + kfree(ax->mem); + + if (ax->map2) { + iounmap(ax->map2); + release_resource(ax->mem2); + kfree(ax->mem2); + } + + free_netdev(dev); + + return 0; +} + +/* ax_probe + * + * This is the entry point when the platform device system uses to + * notify us of a new device to attach to. Allocate memory, find + * the resources and information passed, and map the necessary registers. +*/ + +static int ax_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct ax_device *ax; + struct resource *res; + size_t size; + int ret; + + dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); + if (dev == NULL) + return -ENOMEM; + + /* ok, let's setup our device */ + ax = to_ax_dev(dev); + + memset(ax, 0, sizeof(struct ax_device)); + + spin_lock_init(&ax->mii_lock); + + ax->dev = pdev; + ax->plat = pdev->dev.platform_data; + platform_set_drvdata(pdev, dev); + + ei_status.rxcr_base = ax->plat->rcr_val; + + /* find the platform resources */ + + dev->irq = platform_get_irq(pdev, 0); + if (dev->irq < 0) { + dev_err(&pdev->dev, "no IRQ specified\n"); + ret = -ENXIO; + goto exit_mem; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no MEM specified\n"); + ret = -ENXIO; + goto exit_mem; + } + + size = (res->end - res->start) + 1; + + /* setup the register offsets from either the platform data + * or by using the size of the resource provided */ + + if (ax->plat->reg_offsets) + ei_status.reg_offset = ax->plat->reg_offsets; + else { + ei_status.reg_offset = ax->reg_offsets; + for (ret = 0; ret < 0x18; ret++) + ax->reg_offsets[ret] = (size / 0x18) * ret; + } + + ax->mem = request_mem_region(res->start, size, pdev->name); + if (ax->mem == NULL) { + dev_err(&pdev->dev, "cannot reserve registers\n"); + ret = -ENXIO; + goto exit_mem; + } + + ei_status.mem = ioremap(res->start, size); + dev->base_addr = (long)ei_status.mem; + + if (ei_status.mem == NULL) { + dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n", + res->start, res->end); + + ret = -ENXIO; + goto exit_req; + } + + /* look for reset area */ + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res == NULL) { + if (!ax->plat->reg_offsets) { + for (ret = 0; ret < 0x20; ret++) + ax->reg_offsets[ret] = (size / 0x20) * ret; + } + + ax->map2 = NULL; + } else { + size = (res->end - res->start) + 1; + + ax->mem2 = request_mem_region(res->start, size, pdev->name); + if (ax->mem == NULL) { + dev_err(&pdev->dev, "cannot reserve registers\n"); + ret = -ENXIO; + goto exit_mem1; + } + + ax->map2 = ioremap(res->start, size); + if (ax->map2 == NULL) { + dev_err(&pdev->dev, "cannot map reset register"); + ret = -ENXIO; + goto exit_mem2; + } + + ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem; + } + + /* got resources, now initialise and register device */ + + ret = ax_init_dev(dev, 1); + if (!ret) + return 0; + + if (ax->map2 == NULL) + goto exit_mem1; + + iounmap(ax->map2); + + exit_mem2: + release_resource(ax->mem2); + kfree(ax->mem2); + + exit_mem1: + iounmap(ei_status.mem); + + exit_req: + release_resource(ax->mem); + kfree(ax->mem); + + exit_mem: + free_netdev(dev); + + return ret; +} + +/* suspend and resume */ + +#ifdef CONFIG_PM +static int ax_suspend(struct platform_device *dev, pm_message_t state) +{ + struct net_device *ndev = platform_get_drvdata(dev); + struct ax_device *ax = to_ax_dev(ndev); + + ax->resume_open = ax->running; + + netif_device_detach(ndev); + ax_close(ndev); + + return 0; +} + +static int ax_resume(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct ax_device *ax = to_ax_dev(ndev); + + ax_initial_setup(ndev, netdev_priv(ndev)); + ax_NS8390_init(ndev, ax->resume_open); + netif_device_attach(ndev); + + if (ax->resume_open) + ax_open(ndev); + + return 0; +} + +#else +#define ax_suspend NULL +#define ax_resume NULL +#endif + +static struct platform_driver axdrv = { + .driver = { + .name = "ax88796", + .owner = THIS_MODULE, + }, + .probe = ax_probe, + .remove = ax_remove, + .suspend = ax_suspend, + .resume = ax_resume, +}; + +static int __init axdrv_init(void) +{ + return platform_driver_register(&axdrv); +} + +static void __exit axdrv_exit(void) +{ + platform_driver_unregister(&axdrv); +} + +module_init(axdrv_init); +module_exit(axdrv_exit); + +MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver"); +MODULE_AUTHOR("Ben Dooks, "); +MODULE_LICENSE("GPL v2"); diff --git a/include/net/ax88796.h b/include/net/ax88796.h new file mode 100644 index 000000000000..ee786a043b3d --- /dev/null +++ b/include/net/ax88796.h @@ -0,0 +1,27 @@ +/* include/net/ax88796.h + * + * Copyright 2005 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#ifndef __NET_AX88796_PLAT_H +#define __NET_AX88796_PLAT_H + +#define AXFLG_HAS_EEPROM (1<<0) +#define AXFLG_MAC_FROMDEV (1<<1) /* device already has MAC */ + +struct ax_plat_data { + unsigned int flags; + unsigned char wordlength; /* 1 or 2 */ + unsigned char dcr_val; /* default value for DCR */ + unsigned char rcr_val; /* default value for RCR */ + unsigned char gpoc_val; /* default value for GPOC */ + u32 *reg_offsets; /* register offsets */ +}; + +#endif /* __NET_AX88796_PLAT_H */ From e54792396fb658b97e2f7b0541c6334020e1a3ec Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 3 Jul 2007 16:23:46 -0500 Subject: [PATCH 534/551] phylib: cleanup marvell.c a bit Simplify the marvell driver init a bit: Make the supported devices an array instead of explicitly registering each structure. This makes it considerably easier to add new devices down the road. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/phy/marvell.c | 110 ++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index fbe1104e9a07..21cb3aa4ae7e 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -254,77 +254,71 @@ static int m88e1145_config_init(struct phy_device *phydev) return 0; } -static struct phy_driver m88e1101_driver = { - .phy_id = 0x01410c60, - .phy_id_mask = 0xfffffff0, - .name = "Marvell 88E1101", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = {.owner = THIS_MODULE,}, -}; - -static struct phy_driver m88e1111_driver = { - .phy_id = 0x01410cc0, - .phy_id_mask = 0xfffffff0, - .name = "Marvell 88E1111", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .config_init = &m88e1111_config_init, - .driver = {.owner = THIS_MODULE,}, -}; - -static struct phy_driver m88e1145_driver = { - .phy_id = 0x01410cd0, - .phy_id_mask = 0xfffffff0, - .name = "Marvell 88E1145", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1145_config_init, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = {.owner = THIS_MODULE,}, +static struct phy_driver marvell_drivers[] = { + { + .phy_id = 0x01410c60, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1101", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg = &marvell_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = {.owner = THIS_MODULE,}, + }, + { + .phy_id = 0x01410cc0, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1111", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1111_config_init, + .config_aneg = &marvell_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = {.owner = THIS_MODULE,}, + }, + { + .phy_id = 0x01410cd0, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1145", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1145_config_init, + .config_aneg = &marvell_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = {.owner = THIS_MODULE,}, + } }; static int __init marvell_init(void) { int ret; + int i; - ret = phy_driver_register(&m88e1101_driver); - if (ret) - return ret; + for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) { + ret = phy_driver_register(&marvell_drivers[i]); - ret = phy_driver_register(&m88e1111_driver); - if (ret) - goto err1111; - - ret = phy_driver_register(&m88e1145_driver); - if (ret) - goto err1145; + if (ret) { + while (i-- > 0) + phy_driver_unregister(&marvell_drivers[i]); + return ret; + } + } return 0; - -err1145: - phy_driver_unregister(&m88e1111_driver); -err1111: - phy_driver_unregister(&m88e1101_driver); - return ret; } static void __exit marvell_exit(void) { - phy_driver_unregister(&m88e1101_driver); - phy_driver_unregister(&m88e1111_driver); - phy_driver_unregister(&m88e1145_driver); + int i; + + for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) + phy_driver_unregister(&marvell_drivers[i]); } module_init(marvell_init); From 85cfb534280dd6a7c7ac399bb2888e1b8b286ece Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 3 Jul 2007 16:24:32 -0500 Subject: [PATCH 535/551] phylib: Add Marvell 88E1112 phy id Add 88E1112 PHY ID to the marvell driver. Seems to do fine with the 88E1111 inits. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/phy/marvell.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 21cb3aa4ae7e..d2ede5ff9fff 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -267,6 +267,19 @@ static struct phy_driver marvell_drivers[] = { .config_intr = &marvell_config_intr, .driver = {.owner = THIS_MODULE,}, }, + { + .phy_id = 0x01410c90, + .phy_id_mask = 0xfffffff0, + .name = "Marvell 88E1112", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1111_config_init, + .config_aneg = &marvell_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .driver = {.owner = THIS_MODULE,}, + }, { .phy_id = 0x01410cc0, .phy_id_mask = 0xfffffff0, From 8abd531e3f77188de2fc41e677d075cc66e61631 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Wed, 4 Jul 2007 00:31:44 +0200 Subject: [PATCH 536/551] eeprom_93cx6: shorten pulse timing to match spec (bis) Based on an original idea by John W. Linville. It is the missing part of 42d45ccd60636c28e35c2016f091783bc14ad99c Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/misc/eeprom_93cx6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c index ac515b0ef67c..ea55654e5948 100644 --- a/drivers/misc/eeprom_93cx6.c +++ b/drivers/misc/eeprom_93cx6.c @@ -55,10 +55,10 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) /* * Add a short delay for the pulse to work. - * According to the specifications the minimal time - * should be 450ns so a 1us delay is sufficient. + * According to the specifications the "maximum minimum" + * time should be 450ns. */ - udelay(1); + ndelay(450); } static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom) From 4638aef1e2d8d938e52cd49f6492e9d414b38380 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 5 Jul 2007 16:13:55 -0700 Subject: [PATCH 537/551] netxen: deinline and sparse fix Get rid of dubious casts to (void *) which causes a sparse warning. And move largeish function from inline to the one file that uses the code, the compiler can then decide to inline it. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 103 --------------------------- drivers/net/netxen/netxen_nic_main.c | 97 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 103 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 619503742b7d..325269d8ae38 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1097,109 +1097,6 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_nic_set_mac(struct net_device *netdev, void *p); struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); -static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) -{ - uint32_t mask = 0x7ff; - int retries = 32; - - DPRINTK(1, INFO, "Entered ISR Disable \n"); - - switch (adapter->portnum) { - case 0: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); - break; - case 1: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); - break; - case 2: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); - break; - case 3: - writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); - break; - } - - if (adapter->intr_scheme != -1 && - adapter->intr_scheme != INTR_SCHEME_PERPORT) { - writel(mask, - (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); - } - - /* Window = 0 or 1 */ - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - do { - writel(0xffffffff, (void *) - (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS))); - mask = readl((void *) - (pci_base_offset(adapter, ISR_INT_VECTOR))); - if (!(mask & 0x80)) - break; - udelay(10); - } while (--retries); - - if (!retries) { - printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", - netxen_nic_driver_name); - } - } - - DPRINTK(1, INFO, "Done with Disable Int\n"); - - return; -} - -static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) -{ - u32 mask; - - DPRINTK(1, INFO, "Entered ISR Enable \n"); - - if (adapter->intr_scheme != -1 && - adapter->intr_scheme != INTR_SCHEME_PERPORT) { - switch (adapter->ahw.board_type) { - case NETXEN_NIC_GBE: - mask = 0x77b; - break; - case NETXEN_NIC_XGBE: - mask = 0x77f; - break; - default: - mask = 0x7ff; - break; - } - - writel(mask, - (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); - } - switch (adapter->portnum) { - case 0: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); - break; - case 1: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); - break; - case 2: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); - break; - case 3: - writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); - break; - } - - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - mask = 0xbff; - if (adapter->intr_scheme != -1 && - adapter->intr_scheme != INTR_SCHEME_PERPORT) { - writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - } - writel(mask, - (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); - } - - DPRINTK(1, INFO, "Done with enable Int\n"); - - return; -} /* * NetXen Board information diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a66ff58366cf..56f8197b953b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -156,6 +156,103 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter #define ADAPTER_LIST_SIZE 12 int netxen_cards_found; +static void netxen_nic_disable_int(struct netxen_adapter *adapter) +{ + uint32_t mask = 0x7ff; + int retries = 32; + + DPRINTK(1, INFO, "Entered ISR Disable \n"); + + switch (adapter->portnum) { + case 0: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); + break; + case 1: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); + break; + case 2: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); + break; + case 3: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); + break; + } + + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) + writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); + + /* Window = 0 or 1 */ + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + do { + writel(0xffffffff, + PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)); + mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); + if (!(mask & 0x80)) + break; + udelay(10); + } while (--retries); + + if (!retries) { + printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", + netxen_nic_driver_name); + } + } + + DPRINTK(1, INFO, "Done with Disable Int\n"); +} + +static void netxen_nic_enable_int(struct netxen_adapter *adapter) +{ + u32 mask; + + DPRINTK(1, INFO, "Entered ISR Enable \n"); + + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) { + switch (adapter->ahw.board_type) { + case NETXEN_NIC_GBE: + mask = 0x77b; + break; + case NETXEN_NIC_XGBE: + mask = 0x77f; + break; + default: + mask = 0x7ff; + break; + } + + writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); + } + + switch (adapter->portnum) { + case 0: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); + break; + case 1: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); + break; + case 2: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); + break; + case 3: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); + break; + } + + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + mask = 0xbff; + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) { + writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + } + writel(mask, + PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)); + } + + DPRINTK(1, INFO, "Done with enable Int\n"); +} + /* * netxen_nic_probe() * From 9514bfe5d92000a9fd6f3c44aa775819b5d78aaf Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 3 Jul 2007 00:46:42 +0200 Subject: [PATCH 538/551] Cleanup usbnet_probe() return value handling usbnet_probe() handles a positive return value from the driver bind() function as success, but will later only setup the status handler if the return value was zero, leading to confusion. Patch adjusts this to accept positive values as success in both checks. Signed-off-by: Peter Korsgaard Signed-off-by: Jeff Garzik --- drivers/net/usb/usbnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 86b690843362..37bf4f2c0a44 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1213,7 +1213,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) status = 0; } - if (status == 0 && dev->status) + if (status >= 0 && dev->status) status = init_status (dev, udev); if (status < 0) goto out3; From 099575b6cb7eaf18211ba72de56264f67651b90b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 6 Jul 2007 18:57:13 +0400 Subject: [PATCH 539/551] macmace: use "unsigned long flags;" Code will do local_irq_save() on it. Signed-off-by: Alexey Dobriyan Signed-off-by: Jeff Garzik --- drivers/net/macmace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index fef3193121f9..9a343b965975 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -577,7 +577,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) struct mace_data *mp = netdev_priv(dev); volatile struct mace *mb = mp->mace; int intr, fs; - unsigned int flags; + unsigned long flags; /* don't want the dma interrupt handler to fire */ local_irq_save(flags); From 89c0d26be7037cd5bbce3bbf12580ba70ed8f382 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 6 Jul 2007 19:05:25 +0400 Subject: [PATCH 540/551] atl1: remove write-only var in tx handler Signed-off-by: Alexey Dobriyan Signed-off-by: Jeff Garzik --- drivers/net/atl1/atl1_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 6862c11ff864..3bb40dd4a410 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -634,14 +634,13 @@ static void atl1_intr_tx(struct atl1_adapter *adapter) struct atl1_buffer *buffer_info; u16 sw_tpd_next_to_clean; u16 cmb_tpd_next_to_clean; - u8 update = 0; sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean); cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { struct tx_packet_desc *tpd; - update = 1; + tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; if (buffer_info->dma) { From c2edacf80e155ef54ae4774379d461b60896bc2e Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Mon, 9 Jul 2007 10:42:47 -0700 Subject: [PATCH 541/551] bonding / ipv6: no addrconf for slaves separately from master At present, when a device is enslaved to bonding, if ipv6 is active then addrconf will be initated on the slave (because it is closed then opened during the enslavement processing). This causes DAD and RS packets to be sent from the slave. These packets in turn can confuse switches that perform ipv6 snooping, causing them to incorrectly update their forwarding tables (if, e.g., the slave being added is an inactve backup that won't be used right away) and direct traffic away from the active slave to a backup slave (where the incoming packets will be dropped). This patch alters the behavior so that addrconf will only run on the master device itself. I believe this is logically correct, as it prevents slaves from having an IPv6 identity independent from the master. This is consistent with the IPv4 behavior for bonding. This is accomplished by (a) having bonding set IFF_SLAVE sooner in the enslavement processing than currently occurs (before open, not after), and (b) having ipv6 addrconf ignore UP and CHANGE events on slave devices. The eql driver also uses the IFF_SLAVE flag. I inspected eql, and I believe this change is reasonable for its usage of IFF_SLAVE, but I did not test it. Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik --- drivers/net/bonding/bond_main.c | 11 +++++------ net/ipv6/addrconf.c | 3 +++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6287ffbda7f7..2bb70e052090 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1390,6 +1390,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) goto err_free; } + res = netdev_set_master(slave_dev, bond_dev); + if (res) { + dprintk("Error %d calling netdev_set_master\n", res); + goto err_close; + } /* open the slave since the application closed it */ res = dev_open(slave_dev); if (res) { @@ -1397,12 +1402,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) goto err_restore_mac; } - res = netdev_set_master(slave_dev, bond_dev); - if (res) { - dprintk("Error %d calling netdev_set_master\n", res); - goto err_close; - } - new_slave->dev = slave_dev; slave_dev->priv_flags |= IFF_BONDING; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index f96ed76d8fa4..79b79f3de24c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2268,6 +2268,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; case NETDEV_UP: case NETDEV_CHANGE: + if (dev->flags & IFF_SLAVE) + break; + if (event == NETDEV_UP) { if (!netif_carrier_ok(dev)) { /* device is not ready yet. */ From cd6f5b8051efe03b90a1dd6d63a642f78ec4e60d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 10 Jul 2007 14:44:49 +0200 Subject: [PATCH 542/551] sunhme.c:quattro_pci_find() must be __devinit This patch fixes the following section mismatch: <-- snip --> ... MODPOST vmlinux WARNING: drivers/built-in.o(.text+0x272f8b): Section mismatch: reference to .init.text:quattro_pci_find (between 'happy_meal_pci_probe' and 'happy_meal_pci_remove') ... <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/sunhme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 51c3fe2108a3..15146a119230 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2625,7 +2625,7 @@ static void quattro_sbus_free_irqs(void) #endif /* CONFIG_SBUS */ #ifdef CONFIG_PCI -static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) +static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev) { struct pci_dev *bdev = pdev->bus->self; struct quattro *qp; From e1abecc48938fbe1966ea6e78267fc673fa59295 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 10 Jul 2007 12:58:33 -0400 Subject: [PATCH 543/551] Remove sk98lin ethernet driver. Unmaintained, superceded by skge. Prodded to deletion by Adrian Bunk. Acked by Stephen Hemminger. Signed-off-by: Jeff Garzik --- Documentation/feature-removal-schedule.txt | 8 - Documentation/networking/00-INDEX | 3 - Documentation/networking/sk98lin.txt | 568 -- drivers/net/Kconfig | 89 +- drivers/net/Makefile | 1 - drivers/net/sk98lin/Makefile | 87 - drivers/net/sk98lin/h/lm80.h | 179 - drivers/net/sk98lin/h/skaddr.h | 285 - drivers/net/sk98lin/h/skcsum.h | 213 - drivers/net/sk98lin/h/skdebug.h | 74 - drivers/net/sk98lin/h/skdrv1st.h | 188 - drivers/net/sk98lin/h/skdrv2nd.h | 447 -- drivers/net/sk98lin/h/skerror.h | 55 - drivers/net/sk98lin/h/skgedrv.h | 51 - drivers/net/sk98lin/h/skgehw.h | 2126 ----- drivers/net/sk98lin/h/skgehwt.h | 48 - drivers/net/sk98lin/h/skgei2c.h | 210 - drivers/net/sk98lin/h/skgeinit.h | 797 -- drivers/net/sk98lin/h/skgepnm2.h | 334 - drivers/net/sk98lin/h/skgepnmi.h | 962 --- drivers/net/sk98lin/h/skgesirq.h | 110 - drivers/net/sk98lin/h/ski2c.h | 174 - drivers/net/sk98lin/h/skqueue.h | 94 - drivers/net/sk98lin/h/skrlmt.h | 438 -- drivers/net/sk98lin/h/sktimer.h | 63 - drivers/net/sk98lin/h/sktypes.h | 69 - drivers/net/sk98lin/h/skversion.h | 38 - drivers/net/sk98lin/h/skvpd.h | 248 - drivers/net/sk98lin/h/xmac_ii.h | 1579 ---- drivers/net/sk98lin/skaddr.c | 1788 ----- drivers/net/sk98lin/skdim.c | 742 -- drivers/net/sk98lin/skethtool.c | 628 -- drivers/net/sk98lin/skge.c | 5211 ------------- drivers/net/sk98lin/skgehwt.c | 171 - drivers/net/sk98lin/skgeinit.c | 2005 ----- drivers/net/sk98lin/skgemib.c | 1075 --- drivers/net/sk98lin/skgepnmi.c | 8210 -------------------- drivers/net/sk98lin/skgesirq.c | 2229 ------ drivers/net/sk98lin/ski2c.c | 1296 --- drivers/net/sk98lin/sklm80.c | 141 - drivers/net/sk98lin/skqueue.c | 179 - drivers/net/sk98lin/skrlmt.c | 3257 -------- drivers/net/sk98lin/sktimer.c | 250 - drivers/net/sk98lin/skvpd.c | 1091 --- drivers/net/sk98lin/skxmac2.c | 4160 ---------- 45 files changed, 1 insertion(+), 41970 deletions(-) delete mode 100644 Documentation/networking/sk98lin.txt delete mode 100644 drivers/net/sk98lin/Makefile delete mode 100644 drivers/net/sk98lin/h/lm80.h delete mode 100644 drivers/net/sk98lin/h/skaddr.h delete mode 100644 drivers/net/sk98lin/h/skcsum.h delete mode 100644 drivers/net/sk98lin/h/skdebug.h delete mode 100644 drivers/net/sk98lin/h/skdrv1st.h delete mode 100644 drivers/net/sk98lin/h/skdrv2nd.h delete mode 100644 drivers/net/sk98lin/h/skerror.h delete mode 100644 drivers/net/sk98lin/h/skgedrv.h delete mode 100644 drivers/net/sk98lin/h/skgehw.h delete mode 100644 drivers/net/sk98lin/h/skgehwt.h delete mode 100644 drivers/net/sk98lin/h/skgei2c.h delete mode 100644 drivers/net/sk98lin/h/skgeinit.h delete mode 100644 drivers/net/sk98lin/h/skgepnm2.h delete mode 100644 drivers/net/sk98lin/h/skgepnmi.h delete mode 100644 drivers/net/sk98lin/h/skgesirq.h delete mode 100644 drivers/net/sk98lin/h/ski2c.h delete mode 100644 drivers/net/sk98lin/h/skqueue.h delete mode 100644 drivers/net/sk98lin/h/skrlmt.h delete mode 100644 drivers/net/sk98lin/h/sktimer.h delete mode 100644 drivers/net/sk98lin/h/sktypes.h delete mode 100644 drivers/net/sk98lin/h/skversion.h delete mode 100644 drivers/net/sk98lin/h/skvpd.h delete mode 100644 drivers/net/sk98lin/h/xmac_ii.h delete mode 100644 drivers/net/sk98lin/skaddr.c delete mode 100644 drivers/net/sk98lin/skdim.c delete mode 100644 drivers/net/sk98lin/skethtool.c delete mode 100644 drivers/net/sk98lin/skge.c delete mode 100644 drivers/net/sk98lin/skgehwt.c delete mode 100644 drivers/net/sk98lin/skgeinit.c delete mode 100644 drivers/net/sk98lin/skgemib.c delete mode 100644 drivers/net/sk98lin/skgepnmi.c delete mode 100644 drivers/net/sk98lin/skgesirq.c delete mode 100644 drivers/net/sk98lin/ski2c.c delete mode 100644 drivers/net/sk98lin/sklm80.c delete mode 100644 drivers/net/sk98lin/skqueue.c delete mode 100644 drivers/net/sk98lin/skrlmt.c delete mode 100644 drivers/net/sk98lin/sktimer.c delete mode 100644 drivers/net/sk98lin/skvpd.c delete mode 100644 drivers/net/sk98lin/skxmac2.c diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 51b369e7fc70..3a159dac04f5 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -248,14 +248,6 @@ Who: Len Brown --------------------------- -What: sk98lin network driver -When: July 2007 -Why: In kernel tree version of driver is unmaintained. Sk98lin driver - replaced by the skge driver. -Who: Stephen Hemminger - ---------------------------- - What: Compaq touchscreen device emulation When: Oct 2007 Files: drivers/input/tsdev.c diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index 153d84d281e6..d63f480afb74 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -96,9 +96,6 @@ routing.txt - the new routing mechanism shaper.txt - info on the module that can shape/limit transmitted traffic. -sk98lin.txt - - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit - Ethernet Adapter family driver info skfp.txt - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt deleted file mode 100644 index 8590a954df1d..000000000000 --- a/Documentation/networking/sk98lin.txt +++ /dev/null @@ -1,568 +0,0 @@ -(C)Copyright 1999-2004 Marvell(R). -All rights reserved -=========================================================================== - -sk98lin.txt created 13-Feb-2004 - -Readme File for sk98lin v6.23 -Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX - -This file contains - 1 Overview - 2 Required Files - 3 Installation - 3.1 Driver Installation - 3.2 Inclusion of adapter at system start - 4 Driver Parameters - 4.1 Per-Port Parameters - 4.2 Adapter Parameters - 5 Large Frame Support - 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) - 7 Troubleshooting - -=========================================================================== - - -1 Overview -=========== - -The sk98lin driver supports the Marvell Yukon and SysKonnect -SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has -been tested with Linux on Intel/x86 machines. -*** - - -2 Required Files -================= - -The linux kernel source. -No additional files required. -*** - - -3 Installation -=============== - -It is recommended to download the latest version of the driver from the -SysKonnect web site www.syskonnect.com. If you have downloaded the latest -driver, the Linux kernel has to be patched before the driver can be -installed. For details on how to patch a Linux kernel, refer to the -patch.txt file. - -3.1 Driver Installation ------------------------- - -The following steps describe the actions that are required to install -the driver and to start it manually. These steps should be carried -out for the initial driver setup. Once confirmed to be ok, they can -be included in the system start. - -NOTE 1: To perform the following tasks you need 'root' access. - -NOTE 2: In case of problems, please read the section "Troubleshooting" - below. - -The driver can either be integrated into the kernel or it can be compiled -as a module. Select the appropriate option during the kernel -configuration. - -Compile/use the driver as a module ----------------------------------- -To compile the driver, go to the directory /usr/src/linux and -execute the command "make menuconfig" or "make xconfig" and proceed as -follows: - -To integrate the driver permanently into the kernel, proceed as follows: - -1. Select the menu "Network device support" and then "Ethernet(1000Mbit)" -2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" - with (*) -3. Build a new kernel when the configuration of the above options is - finished. -4. Install the new kernel. -5. Reboot your system. - -To use the driver as a module, proceed as follows: - -1. Enable 'loadable module support' in the kernel. -2. For automatic driver start, enable the 'Kernel module loader'. -3. Select the menu "Network device support" and then "Ethernet(1000Mbit)" -4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" - with (M) -5. Execute the command "make modules". -6. Execute the command "make modules_install". - The appropriate modules will be installed. -7. Reboot your system. - - -Load the module manually ------------------------- -To load the module manually, proceed as follows: - -1. Enter "modprobe sk98lin". -2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in - your computer and you have a /proc file system, execute the command: - "ls /proc/net/sk98lin/" - This should produce an output containing a line with the following - format: - eth0 eth1 ... - which indicates that your adapter has been found and initialized. - - NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx - adapter installed, the adapters will be listed as 'eth0', - 'eth1', 'eth2', etc. - For each adapter, repeat steps 3 and 4 below. - - NOTE 2: If you have other Ethernet adapters installed, your Marvell - Yukon or SysKonnect SK-98xx adapter will be mapped to the - next available number, e.g. 'eth1'. The mapping is executed - automatically. - The module installation message (displayed either in a system - log file or on the console) prints a line for each adapter - found containing the corresponding 'ethX'. - -3. Select an IP address and assign it to the respective adapter by - entering: - ifconfig eth0 - With this command, the adapter is connected to the Ethernet. - - SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter - is now active, the link status LED of the primary port is active and - the link status LED of the secondary port (on dual port adapters) is - blinking (if the ports are connected to a switch or hub). - SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active. - In addition, you will receive a status message on the console stating - "ethX: network connection up using port Y" and showing the selected - connection parameters (x stands for the ethernet device number - (0,1,2, etc), y stands for the port name (A or B)). - - NOTE: If you are in doubt about IP addresses, ask your network - administrator for assistance. - -4. Your adapter should now be fully operational. - Use 'ping ' to verify the connection to other computers - on your network. -5. To check the adapter configuration view /proc/net/sk98lin/[devicename]. - For example by executing: - "cat /proc/net/sk98lin/eth0" - -Unload the module ------------------ -To stop and unload the driver modules, proceed as follows: - -1. Execute the command "ifconfig eth0 down". -2. Execute the command "rmmod sk98lin". - -3.2 Inclusion of adapter at system start ------------------------------------------ - -Since a large number of different Linux distributions are -available, we are unable to describe a general installation procedure -for the driver module. -Because the driver is now integrated in the kernel, installation should -be easy, using the standard mechanism of your distribution. -Refer to the distribution's manual for installation of ethernet adapters. - -*** - -4 Driver Parameters -==================== - -Parameters can be set at the command line after the module has been -loaded with the command 'modprobe'. -In some distributions, the configuration tools are able to pass parameters -to the driver module. - -If you use the kernel module loader, you can set driver parameters -in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier). -To set the driver parameters in this file, proceed as follows: - -1. Insert a line of the form : - options sk98lin ... - For "...", the same syntax is required as described for the command - line parameters of modprobe below. -2. To activate the new parameters, either reboot your computer - or - unload and reload the driver. - The syntax of the driver parameters is: - - modprobe sk98lin parameter=value1[,value2[,value3...]] - - where value1 refers to the first adapter, value2 to the second etc. - -NOTE: All parameters are case sensitive. Write them exactly as shown - below. - -Example: -Suppose you have two adapters. You want to set auto-negotiation -on the first adapter to ON and on the second adapter to OFF. -You also want to set DuplexCapabilities on the first adapter -to FULL, and on the second adapter to HALF. -Then, you must enter: - - modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half - -NOTE: The number of adapters that can be configured this way is - limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM). - The current limit is 16. If you happen to install - more adapters, adjust this and recompile. - - -4.1 Per-Port Parameters ------------------------- - -These settings are available for each port on the adapter. -In the following description, '?' stands for the port for -which you set the parameter (A or B). - -Speed ------ -Parameter: Speed_? -Values: 10, 100, 1000, Auto -Default: Auto - -This parameter is used to set the speed capabilities. It is only valid -for the SK-98xx V2.0 copper adapters. -Usually, the speed is negotiated between the two ports during link -establishment. If this fails, a port can be forced to a specific setting -with this parameter. - -Auto-Negotiation ----------------- -Parameter: AutoNeg_? -Values: On, Off, Sense -Default: On - -The "Sense"-mode automatically detects whether the link partner supports -auto-negotiation or not. - -Duplex Capabilities -------------------- -Parameter: DupCap_? -Values: Half, Full, Both -Default: Both - -This parameters is only relevant if auto-negotiation for this port is -not set to "Sense". If auto-negotiation is set to "On", all three values -are possible. If it is set to "Off", only "Full" and "Half" are allowed. -This parameter is useful if your link partner does not support all -possible combinations. - -Flow Control ------------- -Parameter: FlowCtrl_? -Values: Sym, SymOrRem, LocSend, None -Default: SymOrRem - -This parameter can be used to set the flow control capabilities the -port reports during auto-negotiation. It can be set for each port -individually. -Possible modes: - -- Sym = Symmetric: both link partners are allowed to send - PAUSE frames - -- SymOrRem = SymmetricOrRemote: both or only remote partner - are allowed to send PAUSE frames - -- LocSend = LocalSend: only local link partner is allowed - to send PAUSE frames - -- None = no link partner is allowed to send PAUSE frames - -NOTE: This parameter is ignored if auto-negotiation is set to "Off". - -Role in Master-Slave-Negotiation (1000Base-T only) --------------------------------------------------- -Parameter: Role_? -Values: Auto, Master, Slave -Default: Auto - -This parameter is only valid for the SK-9821 and SK-9822 adapters. -For two 1000Base-T ports to communicate, one must take the role of the -master (providing timing information), while the other must be the -slave. Usually, this is negotiated between the two ports during link -establishment. If this fails, a port can be forced to a specific setting -with this parameter. - - -4.2 Adapter Parameters ------------------------ - -Connection Type (SK-98xx V2.0 copper adapters only) ---------------- -Parameter: ConType -Values: Auto, 100FD, 100HD, 10FD, 10HD -Default: Auto - -The parameter 'ConType' is a combination of all five per-port parameters -within one single parameter. This simplifies the configuration of both ports -of an adapter card! The different values of this variable reflect the most -meaningful combinations of port parameters. - -The following table shows the values of 'ConType' and the corresponding -combinations of the per-port parameters: - - ConType | DupCap AutoNeg FlowCtrl Role Speed - ----------+------------------------------------------------------ - Auto | Both On SymOrRem Auto Auto - 100FD | Full Off None Auto (ignored) 100 - 100HD | Half Off None Auto (ignored) 100 - 10FD | Full Off None Auto (ignored) 10 - 10HD | Half Off None Auto (ignored) 10 - -Stating any other port parameter together with this 'ConType' variable -will result in a merged configuration of those settings. This due to -the fact, that the per-port parameters (e.g. Speed_? ) have a higher -priority than the combined variable 'ConType'. - -NOTE: This parameter is always used on both ports of the adapter card. - -Interrupt Moderation --------------------- -Parameter: Moderation -Values: None, Static, Dynamic -Default: None - -Interrupt moderation is employed to limit the maximum number of interrupts -the driver has to serve. That is, one or more interrupts (which indicate any -transmit or receive packet to be processed) are queued until the driver -processes them. When queued interrupts are to be served, is determined by the -'IntsPerSec' parameter, which is explained later below. - -Possible modes: - - -- None - No interrupt moderation is applied on the adapter card. - Therefore, each transmit or receive interrupt is served immediately - as soon as it appears on the interrupt line of the adapter card. - - -- Static - Interrupt moderation is applied on the adapter card. - All transmit and receive interrupts are queued until a complete - moderation interval ends. If such a moderation interval ends, all - queued interrupts are processed in one big bunch without any delay. - The term 'static' reflects the fact, that interrupt moderation is - always enabled, regardless how much network load is currently - passing via a particular interface. In addition, the duration of - the moderation interval has a fixed length that never changes while - the driver is operational. - - -- Dynamic - Interrupt moderation might be applied on the adapter card, - depending on the load of the system. If the driver detects that the - system load is too high, the driver tries to shield the system against - too much network load by enabling interrupt moderation. If - at a later - time - the CPU utilization decreases again (or if the network load is - negligible) the interrupt moderation will automatically be disabled. - -Interrupt moderation should be used when the driver has to handle one or more -interfaces with a high network load, which - as a consequence - leads also to a -high CPU utilization. When moderation is applied in such high network load -situations, CPU load might be reduced by 20-30%. - -NOTE: The drawback of using interrupt moderation is an increase of the round- -trip-time (RTT), due to the queueing and serving of interrupts at dedicated -moderation times. - -Interrupts per second ---------------------- -Parameter: IntsPerSec -Values: 30...40000 (interrupts per second) -Default: 2000 - -This parameter is only used if either static or dynamic interrupt moderation -is used on a network adapter card. Using this parameter if no moderation is -applied will lead to no action performed. - -This parameter determines the length of any interrupt moderation interval. -Assuming that static interrupt moderation is to be used, an 'IntsPerSec' -parameter value of 2000 will lead to an interrupt moderation interval of -500 microseconds. - -NOTE: The duration of the moderation interval is to be chosen with care. -At first glance, selecting a very long duration (e.g. only 100 interrupts per -second) seems to be meaningful, but the increase of packet-processing delay -is tremendous. On the other hand, selecting a very short moderation time might -compensate the use of any moderation being applied. - - -Preferred Port --------------- -Parameter: PrefPort -Values: A, B -Default: A - -This is used to force the preferred port to A or B (on dual-port network -adapters). The preferred port is the one that is used if both are detected -as fully functional. - -RLMT Mode (Redundant Link Management Technology) ------------------------------------------------- -Parameter: RlmtMode -Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet -Default: CheckLinkState - -RLMT monitors the status of the port. If the link of the active port -fails, RLMT switches immediately to the standby link. The virtual link is -maintained as long as at least one 'physical' link is up. - -Possible modes: - - -- CheckLinkState - Check link state only: RLMT uses the link state - reported by the adapter hardware for each individual port to - determine whether a port can be used for all network traffic or - not. - - -- CheckLocalPort - In this mode, RLMT monitors the network path - between the two ports of an adapter by regularly exchanging packets - between them. This mode requires a network configuration in which - the two ports are able to "see" each other (i.e. there must not be - any router between the ports). - - -- CheckSeg - Check local port and segmentation: This mode supports the - same functions as the CheckLocalPort mode and additionally checks - network segmentation between the ports. Therefore, this mode is only - to be used if Gigabit Ethernet switches are installed on the network - that have been configured to use the Spanning Tree protocol. - - -- DualNet - In this mode, ports A and B are used as separate devices. - If you have a dual port adapter, port A will be configured as eth0 - and port B as eth1. Both ports can be used independently with - distinct IP addresses. The preferred port setting is not used. - RLMT is turned off. - -NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations - where a network path between the ports on one adapter exists. - Moreover, they are not designed to work where adapters are connected - back-to-back. -*** - - -5 Large Frame Support -====================== - -The driver supports large frames (also called jumbo frames). Using large -frames can result in an improved throughput if transferring large amounts -of data. -To enable large frames, set the MTU (maximum transfer unit) of the -interface to the desired value (up to 9000), execute the following -command: - ifconfig eth0 mtu 9000 -This will only work if you have two adapters connected back-to-back -or if you use a switch that supports large frames. When using a switch, -it should be configured to allow large frames and auto-negotiation should -be set to OFF. The setting must be configured on all adapters that can be -reached by the large frames. If one adapter is not set to receive large -frames, it will simply drop them. - -You can switch back to the standard ethernet frame size by executing the -following command: - ifconfig eth0 mtu 1500 - -To permanently configure this setting, add a script with the 'ifconfig' -line to the system startup sequence (named something like "S99sk98lin" -in /etc/rc.d/rc2.d). -*** - - -6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) -================================================================== - -The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and -Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. -These features are only available after installation of open source -modules available on the Internet: -For VLAN go to: http://www.candelatech.com/~greear/vlan.html -For Link Aggregation go to: http://www.st.rim.or.jp/~yumo - -NOTE: SysKonnect GmbH does not offer any support for these open source - modules and does not take the responsibility for any kind of - failures or problems arising in connection with these modules. - -NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may - cause problems when unloading the driver. - - -7 Troubleshooting -================== - -If any problems occur during the installation process, check the -following list: - - -Problem: The SK-98xx adapter cannot be found by the driver. -Solution: In /proc/pci search for the following entry: - 'Ethernet controller: SysKonnect SK-98xx ...' - If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has - been found by the system and should be operational. - If this entry does not exist or if the file '/proc/pci' is not - found, there may be a hardware problem or the PCI support may - not be enabled in your kernel. - The adapter can be checked using the diagnostics program which - is available on the SysKonnect web site: - www.syskonnect.com - - Some COMPAQ machines have problems dealing with PCI under Linux. - This problem is described in the 'PCI howto' document - (included in some distributions or available from the - web, e.g. at 'www.linux.org'). - - -Problem: Programs such as 'ifconfig' or 'route' cannot be found or the - error message 'Operation not permitted' is displayed. -Reason: You are not logged in as user 'root'. -Solution: Logout and login as 'root' or change to 'root' via 'su'. - - -Problem: Upon use of the command 'ping
' the message - "ping: sendto: Network is unreachable" is displayed. -Reason: Your route is not set correctly. -Solution: If you are using RedHat, you probably forgot to set up the - route in the 'network configuration'. - Check the existing routes with the 'route' command and check - if an entry for 'eth0' exists, and if so, if it is set correctly. - - -Problem: The driver can be started, the adapter is connected to the - network, but you cannot receive or transmit any packets; - e.g. 'ping' does not work. -Reason: There is an incorrect route in your routing table. -Solution: Check the routing table with the command 'route' and read the - manual help pages dealing with routes (enter 'man route'). - -NOTE: Although the 2.2.x kernel versions generate the routing entry - automatically, problems of this kind may occur here as well. We've - come across a situation in which the driver started correctly at - system start, but after the driver has been removed and reloaded, - the route of the adapter's network pointed to the 'dummy0'device - and had to be corrected manually. - - -Problem: Your computer should act as a router between multiple - IP subnetworks (using multiple adapters), but computers in - other subnetworks cannot be reached. -Reason: Either the router's kernel is not configured for IP forwarding - or the routing table and gateway configuration of at least one - computer is not working. - -Problem: Upon driver start, the following error message is displayed: - "eth0: -- ERROR -- - Class: internal Software error - Nr: 0xcc - Msg: SkGeInitPort() cannot init running ports" -Reason: You are using a driver compiled for single processor machines - on a multiprocessor machine with SMP (Symmetric MultiProcessor) - kernel. -Solution: Configure your kernel appropriately and recompile the kernel or - the modules. - - - -If your problem is not listed here, please contact SysKonnect's technical -support for help (linux@syskonnect.de). -When contacting our technical support, please ensure that the following -information is available: -- System Manufacturer and HW Informations (CPU, Memory... ) -- PCI-Boards in your system -- Distribution -- Kernel version -- Driver version -*** - - - -***End of Readme File*** diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 09c68984c887..a3bef229a125 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2113,7 +2113,7 @@ config SKGE with better performance and more complete ethtool support. It does not support the link failover and network management - features that "portable" vendor supplied sk98lin driver does. + features available in the hardware. This driver supports adapters based on the original Yukon chipset: Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T, @@ -2151,93 +2151,6 @@ config SKY2_DEBUG If unsure, say N. -config SK98LIN - tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" - depends on PCI - ---help--- - Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx - compliant Gigabit Ethernet Adapter. - - This driver supports the original Yukon chipset. This driver is - deprecated and will be removed from the kernel in the near future, - it has been replaced by the skge driver. skge is cleaner and - seems to work better. - - This driver does not support the newer Yukon2 chipset. A separate - driver, sky2, is provided to support Yukon2-based adapters. - - The following adapters are supported by this driver: - - 3Com 3C940 Gigabit LOM Ethernet Adapter - - 3Com 3C941 Gigabit LOM Ethernet Adapter - - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter - - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter - - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter - - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter - - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter - - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter - - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter - - Allied Telesyn AT-2971T Gigabit Ethernet Adapter - - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 - - EG1032 v2 Instant Gigabit Network Adapter - - EG1064 v2 Instant Gigabit Network Adapter - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) - - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel) - - Marvell RDK-8001 Adapter - - Marvell RDK-8002 Adapter - - Marvell RDK-8003 Adapter - - Marvell RDK-8004 Adapter - - Marvell RDK-8006 Adapter - - Marvell RDK-8007 Adapter - - Marvell RDK-8008 Adapter - - Marvell RDK-8009 Adapter - - Marvell RDK-8010 Adapter - - Marvell RDK-8011 Adapter - - Marvell RDK-8012 Adapter - - Marvell RDK-8052 Adapter - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) - - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) - - SK-9521 10/100/1000Base-T Adapter - - SK-9521 V2.0 10/100/1000Base-T Adapter - - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) - - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter - - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) - - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) - - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter - - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) - - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) - - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) - - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) - - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter - - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) - - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) - - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter - - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) - - SMC EZ Card 1000 (SMC9452TXV.2) - - The adapters support Jumbo Frames. - The dual link adapters support link-failover and dual port features. - Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support - the scatter-gather functionality with sendfile(). Please refer to - for more information about - optional driver parameters. - Questions concerning this driver may be addressed to: - - - If you want to compile this driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The module will - be called sk98lin. This is recommended. - config VIA_VELOCITY tristate "VIA Velocity support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 515ca660b936..77bd8222ab44 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -63,7 +63,6 @@ obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o -obj-$(CONFIG_SK98LIN) += sk98lin/ obj-$(CONFIG_SKFP) += skfp/ obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile deleted file mode 100644 index afd900d5d730..000000000000 --- a/drivers/net/sk98lin/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -# -# Makefile for the SysKonnect SK-98xx device driver. -# - - -# -# Standalone driver params -# SKPARAM += -DSK_KERNEL_24 -# SKPARAM += -DSK_KERNEL_24_26 -# SKPARAM += -DSK_KERNEL_26 -# SKPARAM += -DSK_KERNEL_22_24 - -obj-$(CONFIG_SK98LIN) += sk98lin.o -sk98lin-objs := \ - skge.o \ - skethtool.o \ - skdim.o \ - skaddr.o \ - skgehwt.o \ - skgeinit.o \ - skgepnmi.o \ - skgesirq.o \ - ski2c.o \ - sklm80.o \ - skqueue.o \ - skrlmt.o \ - sktimer.o \ - skvpd.o \ - skxmac2.o - -# DBGDEF = \ -# -DDEBUG - -ifdef DEBUG -DBGDEF += \ --DSK_DEBUG_CHKMOD=0x00000000L \ --DSK_DEBUG_CHKCAT=0x00000000L -endif - - -# **** possible debug modules for SK_DEBUG_CHKMOD ***************** -# SK_DBGMOD_MERR 0x00000001L /* general module error indication */ -# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */ -# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */ -# SK_DBGMOD_VPD 0x00000008L /* VPD module */ -# SK_DBGMOD_I2C 0x00000010L /* I2C module */ -# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */ -# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */ -# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ -# SK_DBGMOD_DRV 0x00010000L /* DRV module */ - -# **** possible debug categories for SK_DEBUG_CHKCAT ************** -# *** common modules *** -# SK_DBGCAT_INIT 0x00000001L module/driver initialization -# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL) -# SK_DBGCAT_ERR 0x00000004L error handling paths -# SK_DBGCAT_TX 0x00000008L transmit path -# SK_DBGCAT_RX 0x00000010L receive path -# SK_DBGCAT_IRQ 0x00000020L general IRQ handling -# SK_DBGCAT_QUEUE 0x00000040L any queue management -# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump -# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump - -# *** driver (file skge.c) *** -# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points -# SK_DBGCAT_DRV_??? 0x00020000 not used -# SK_DBGCAT_DRV_MCA 0x00040000 multicast -# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path -# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path -# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime -# SK_DBGCAT_DRV_??? 0x00400000 not used -# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode -# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames -# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions -# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources -# SK_DBGCAT_DRV_EVENT 0x08000000 driver events - -EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) - -clean: - rm -f core *.o *.a *.s - - - - - - diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h deleted file mode 100644 index 4e2dbbf78000..000000000000 --- a/drivers/net/sk98lin/h/lm80.h +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************** - * - * Name: lm80.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.6 $ - * Date: $Date: 2003/05/13 17:26:52 $ - * Purpose: Contains all defines for the LM80 Chip - * (National Semiconductor). - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_LM80_H -#define __INC_LM80_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* defines ********************************************************************/ - -/* - * LM80 register definition - * - * All registers are 8 bit wide - */ -#define LM80_CFG 0x00 /* Configuration Register */ -#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */ -#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */ -#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */ -#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */ -#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */ -#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */ - /* 0x07 - 0x1f reserved */ - /* current values */ -#define LM80_VT0_IN 0x20 /* current Voltage 0 value */ -#define LM80_VT1_IN 0x21 /* current Voltage 1 value */ -#define LM80_VT2_IN 0x22 /* current Voltage 2 value */ -#define LM80_VT3_IN 0x23 /* current Voltage 3 value */ -#define LM80_VT4_IN 0x24 /* current Voltage 4 value */ -#define LM80_VT5_IN 0x25 /* current Voltage 5 value */ -#define LM80_VT6_IN 0x26 /* current Voltage 6 value */ -#define LM80_TEMP_IN 0x27 /* current Temperature value */ -#define LM80_FAN1_IN 0x28 /* current Fan 1 count */ -#define LM80_FAN2_IN 0x29 /* current Fan 2 count */ - /* limit values */ -#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */ -#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */ -#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */ -#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */ -#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */ -#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */ -#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */ -#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */ -#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */ -#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */ -#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */ -#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */ -#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */ -#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */ -#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */ -#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */ -#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */ -#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */ -#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */ -#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */ - /* 0x3e - 0x3f reserved */ - -/* - * LM80 bit definitions - */ - -/* LM80_CFG Configuration Register */ -#define LM80_CFG_START (1<<0) /* start monitoring operation */ -#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */ -#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */ -#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */ -#define LM80_CFG_RESET (1<<4) /* signals a reset */ -#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */ -#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */ -#define LM80_CFG_INIT (1<<7) /* restore power on defaults */ - -/* LM80_ISRC_1 Interrupt Status Register 1 */ -/* LM80_IMSK_1 Interrupt Mask Register 1 */ -#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */ -#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */ -#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */ -#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */ -#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */ -#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */ -#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */ -#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */ - -/* LM80_ISRC_2 Interrupt Status Register 2 */ -/* LM80_IMSK_2 Interrupt Mask Register 2 */ -#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */ -#define LM80_IS_BTI (1<<1) /* state of BTI# pin */ -#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */ -#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */ -#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */ -#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */ - /* bit 6 and 7 are reserved in LM80_ISRC_2 */ -#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */ -#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */ - -/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */ -#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */ -#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */ -#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */ -#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */ -#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/ -#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */ - -/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */ -#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */ -#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */ -#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */ -#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/ -#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */ -#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */ - - /* 0x07 - 0x1f reserved */ -/* LM80_VT0_IN current Voltage 0 value */ -/* LM80_VT1_IN current Voltage 1 value */ -/* LM80_VT2_IN current Voltage 2 value */ -/* LM80_VT3_IN current Voltage 3 value */ -/* LM80_VT4_IN current Voltage 4 value */ -/* LM80_VT5_IN current Voltage 5 value */ -/* LM80_VT6_IN current Voltage 6 value */ -/* LM80_TEMP_IN current temperature value */ -/* LM80_FAN1_IN current Fan 1 count */ -/* LM80_FAN2_IN current Fan 2 count */ -/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */ -/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */ -/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */ -/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */ -/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */ -/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */ -/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */ -/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */ -/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */ -/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */ -/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */ -/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */ -/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */ -/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */ -/* LM80_THOT_LIM_UP hot temperature limit (high) */ -/* LM80_THOT_LIM_LO hot temperature limit (low) */ -/* LM80_TOS_LIM_UP OS temperature limit (high) */ -/* LM80_TOS_LIM_LO OS temperature limit (low) */ -/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */ -/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */ - /* 0x3e - 0x3f reserved */ - -#define LM80_ADDR 0x28 /* LM80 default addr */ - -/* typedefs *******************************************************************/ - - -/* function prototypes ********************************************************/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_LM80_H */ diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h deleted file mode 100644 index 423ad063d09b..000000000000 --- a/drivers/net/sk98lin/h/skaddr.h +++ /dev/null @@ -1,285 +0,0 @@ -/****************************************************************************** - * - * Name: skaddr.h - * Project: Gigabit Ethernet Adapters, ADDR-Modul - * Version: $Revision: 1.29 $ - * Date: $Date: 2003/05/13 16:57:24 $ - * Purpose: Header file for Address Management (MC, UC, Prom). - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This module is intended to manage multicast addresses and promiscuous mode - * on GEnesis adapters. - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * ... - * "sktypes.h" - * "skqueue.h" - * "skaddr.h" - * ... - * "skdrv2nd.h" - * - ******************************************************************************/ - -#ifndef __INC_SKADDR_H -#define __INC_SKADDR_H - -#ifdef __cplusplus -extern "C" { -#endif /* cplusplus */ - -/* defines ********************************************************************/ - -#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */ -#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */ - -/* ----- Common return values ----- */ - -#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */ -#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */ -#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */ - -/* ----- Clear/Add flag bits ----- */ - -#define SK_ADDR_PERMANENT 1 /* RLMT Address */ - -/* ----- Additional Clear flag bits ----- */ - -#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */ - -/* ----- Override flag bits ----- */ - -#define SK_ADDR_LOGICAL_ADDRESS 0 -#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */ -#define SK_ADDR_PHYSICAL_ADDRESS 1 -#define SK_ADDR_CLEAR_LOGICAL 2 -#define SK_ADDR_SET_LOGICAL 4 - -/* ----- Override return values ----- */ - -#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS) -#define SK_ADDR_DUPLICATE_ADDRESS 1 -#define SK_ADDR_MULTICAST_ADDRESS 2 - -/* ----- Partitioning of excact match table ----- */ - -#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */ - -#define SK_ADDR_FIRST_MATCH_RLMT 1 -#define SK_ADDR_LAST_MATCH_RLMT 2 -#define SK_ADDR_FIRST_MATCH_DRV 3 -#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1) - -/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */ - -#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */ -#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */ - -/* ----- Additional SkAddrMcAdd return values ----- */ - -#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */ -#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */ -#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */ - -/* Promiscuous mode bits ----- */ - -#define SK_PROM_MODE_NONE 0 /* Normal receive. */ -#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */ -#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */ -/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */ - -/* Macros */ - -#ifdef OLD_STUFF -#ifndef SK_ADDR_EQUAL -/* - * "&" instead of "&&" allows better optimization on IA-64. - * The replacement is safe here, as all bytes exist. - */ -#ifndef SK_ADDR_DWORD_COMPARE -#define SK_ADDR_EQUAL(A1,A2) ( \ - (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \ - (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \ - (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \ - (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \ - (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \ - (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0])) -#else /* SK_ADDR_DWORD_COMPARE */ -#define SK_ADDR_EQUAL(A1,A2) ( \ - (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \ - (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))) -#endif /* SK_ADDR_DWORD_COMPARE */ -#endif /* SK_ADDR_EQUAL */ -#endif /* 0 */ - -#ifndef SK_ADDR_EQUAL -#ifndef SK_ADDR_DWORD_COMPARE -#define SK_ADDR_EQUAL(A1,A2) ( \ - (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \ - (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \ - (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \ - (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \ - (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \ - (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0])) -#else /* SK_ADDR_DWORD_COMPARE */ -#define SK_ADDR_EQUAL(A1,A2) ( \ - (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \ - *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \ - (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \ - *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0]))) -#endif /* SK_ADDR_DWORD_COMPARE */ -#endif /* SK_ADDR_EQUAL */ - -/* typedefs *******************************************************************/ - -typedef struct s_MacAddr { - SK_U8 a[SK_MAC_ADDR_LEN]; -} SK_MAC_ADDR; - - -/* SK_FILTER is used to ensure alignment of the filter. */ -typedef union s_InexactFilter { - SK_U8 Bytes[8]; - SK_U64 Val; /* Dummy entry for alignment only. */ -} SK_FILTER64; - - -typedef struct s_AddrNet SK_ADDR_NET; - - -typedef struct s_AddrPort { - -/* ----- Public part (read-only) ----- */ - - SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */ - SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */ - int PromMode; /* Promiscuous Mode. */ - -/* ----- Private part ----- */ - - SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */ - SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */ - SK_U8 Align01; - - SK_U32 FirstExactMatchRlmt; - SK_U32 NextExactMatchRlmt; - SK_U32 FirstExactMatchDrv; - SK_U32 NextExactMatchDrv; - SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES]; - SK_FILTER64 InexactFilter; /* For 64-bit hash register. */ - SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */ - SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */ -} SK_ADDR_PORT; - - -struct s_AddrNet { -/* ----- Public part (read-only) ----- */ - - SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */ - SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */ - -/* ----- Private part ----- */ - - SK_U32 ActivePort; /* View of module ADDR. */ - SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */ - SK_U8 Align01; - SK_U16 Align02; -}; - - -typedef struct s_Addr { - -/* ----- Public part (read-only) ----- */ - - SK_ADDR_NET Net[SK_MAX_NETS]; - SK_ADDR_PORT Port[SK_MAX_MACS]; - -/* ----- Private part ----- */ -} SK_ADDR; - -/* function prototypes ********************************************************/ - -#ifndef SK_KR_PROTO - -/* Functions provided by SkAddr */ - -/* ANSI/C++ compliant function prototypes */ - -extern int SkAddrInit( - SK_AC *pAC, - SK_IOC IoC, - int Level); - -extern int SkAddrMcClear( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int Flags); - -extern int SkAddrMcAdd( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - SK_MAC_ADDR *pMc, - int Flags); - -extern int SkAddrMcUpdate( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber); - -extern int SkAddrOverride( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - SK_MAC_ADDR SK_FAR *pNewAddr, - int Flags); - -extern int SkAddrPromiscuousChange( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int NewPromMode); - -#ifndef SK_SLIM -extern int SkAddrSwap( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 FromPortNumber, - SK_U32 ToPortNumber); -#endif - -#else /* defined(SK_KR_PROTO)) */ - -/* Non-ANSI/C++ compliant function prototypes */ - -#error KR-style prototypes are not yet provided. - -#endif /* defined(SK_KR_PROTO)) */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_SKADDR_H */ diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h deleted file mode 100644 index 6e256bd9a28c..000000000000 --- a/drivers/net/sk98lin/h/skcsum.h +++ /dev/null @@ -1,213 +0,0 @@ -/****************************************************************************** - * - * Name: skcsum.h - * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) - * Version: $Revision: 1.10 $ - * Date: $Date: 2003/08/20 13:59:57 $ - * Purpose: Store/verify Internet checksum in send/receive packets. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2001 SysKonnect GmbH. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * Public header file for the "GEnesis" common module "CSUM". - * - * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon" - * and is the code name of this SysKonnect project. - * - * Compilation Options: - * - * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an - * empty module. - * - * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id - * definitions. In this case, all SKCS_PROTO_xxx definitions must be made - * external. - * - * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status - * definitions. In this case, all SKCS_STATUS_xxx definitions must be made - * external. - * - * Include File Hierarchy: - * - * "h/skcsum.h" - * "h/sktypes.h" - * "h/skqueue.h" - * - ******************************************************************************/ - -#ifndef __INC_SKCSUM_H -#define __INC_SKCSUM_H - -#include "h/sktypes.h" -#include "h/skqueue.h" - -/* defines ********************************************************************/ - -/* - * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user - * overwrite. - */ -#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */ -#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */ -#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */ -#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */ - -/* Indices for protocol statistics. */ -#define SKCS_PROTO_STATS_IP 0 -#define SKCS_PROTO_STATS_UDP 1 -#define SKCS_PROTO_STATS_TCP 2 -#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */ -#endif /* !SKCS_OVERWRITE_PROTO */ - -/* - * Define the default SKCS_STATUS type and values if no user overwrite. - * - * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame. - * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error. - * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame. - * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame - * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok). - * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame). - * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok). - * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok). - * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok. - * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok. - * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum. - */ -#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */ -#define SKCS_STATUS int /* Define status type. */ - -#define SKCS_STATUS_UNKNOWN_IP_VERSION 1 -#define SKCS_STATUS_IP_CSUM_ERROR 2 -#define SKCS_STATUS_IP_FRAGMENT 3 -#define SKCS_STATUS_IP_CSUM_OK 4 -#define SKCS_STATUS_TCP_CSUM_ERROR 5 -#define SKCS_STATUS_UDP_CSUM_ERROR 6 -#define SKCS_STATUS_TCP_CSUM_OK 7 -#define SKCS_STATUS_UDP_CSUM_OK 8 -/* needed for Microsoft */ -#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9 -#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10 -/* UDP checksum may be omitted */ -#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11 -#endif /* !SKCS_OVERWRITE_STATUS */ - -/* Clear protocol statistics event. */ -#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1 - -/* - * Add two values in one's complement. - * - * Note: One of the two input values may be "longer" than 16-bit, but then the - * resulting sum may be 17 bits long. In this case, add zero to the result using - * SKCS_OC_ADD() again. - * - * Result = Value1 + Value2 - */ -#define SKCS_OC_ADD(Result, Value1, Value2) { \ - unsigned long Sum; \ - \ - Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \ - /* Add-in any carry. */ \ - (Result) = (Sum & 0xffff) + (Sum >> 16); \ -} - -/* - * Subtract two values in one's complement. - * - * Result = Value1 - Value2 - */ -#define SKCS_OC_SUB(Result, Value1, Value2) \ - SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff) - -/* typedefs *******************************************************************/ - -/* - * SKCS_PROTO_STATS - The CSUM protocol statistics structure. - * - * There is one instance of this structure for each protocol supported. - */ -typedef struct s_CsProtocolStatistics { - SK_U64 RxOkCts; /* Receive checksum ok. */ - SK_U64 RxUnableCts; /* Unable to verify receive checksum. */ - SK_U64 RxErrCts; /* Receive checksum error. */ - SK_U64 TxOkCts; /* Transmit checksum ok. */ - SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */ -} SKCS_PROTO_STATS; - -/* - * s_Csum - The CSUM module context structure. - */ -typedef struct s_Csum { - /* Enabled receive SK_PROTO_XXX bit flags. */ - unsigned ReceiveFlags[SK_MAX_NETS]; -#ifdef TX_CSUM - unsigned TransmitFlags[SK_MAX_NETS]; -#endif /* TX_CSUM */ - - /* The protocol statistics structure; one per supported protocol. */ - SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS]; -} SK_CSUM; - -/* - * SKCS_PACKET_INFO - The packet information structure. - */ -typedef struct s_CsPacketInfo { - /* Bit field specifiying the desired/found protocols. */ - unsigned ProtocolFlags; - - /* Length of complete IP header, including any option fields. */ - unsigned IpHeaderLength; - - /* IP header checksum. */ - unsigned IpHeaderChecksum; - - /* TCP/UDP pseudo header checksum. */ - unsigned PseudoHeaderChecksum; -} SKCS_PACKET_INFO; - -/* function prototypes ********************************************************/ - -#ifndef SK_CS_CALCULATE_CHECKSUM -extern unsigned SkCsCalculateChecksum( - void *pData, - unsigned Length); -#endif /* SK_CS_CALCULATE_CHECKSUM */ - -extern int SkCsEvent( - SK_AC *pAc, - SK_IOC Ioc, - SK_U32 Event, - SK_EVPARA Param); - -extern SKCS_STATUS SkCsGetReceiveInfo( - SK_AC *pAc, - void *pIpHeader, - unsigned Checksum1, - unsigned Checksum2, - int NetNumber); - -extern void SkCsSetReceiveFlags( - SK_AC *pAc, - unsigned ReceiveFlags, - unsigned *pChecksum1Offset, - unsigned *pChecksum2Offset, - int NetNumber); - -#endif /* __INC_SKCSUM_H */ diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h deleted file mode 100644 index 3cba171d74b2..000000000000 --- a/drivers/net/sk98lin/h/skdebug.h +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** - * - * Name: skdebug.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.14 $ - * Date: $Date: 2003/05/13 17:26:00 $ - * Purpose: SK specific DEBUG support - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_SKDEBUG_H -#define __INC_SKDEBUG_H - -#ifdef DEBUG -#ifndef SK_DBG_MSG -#define SK_DBG_MSG(pAC,comp,cat,arg) \ - if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \ - ((cat) & SK_DBG_CHKCAT(pAC)) ) { \ - SK_DBG_PRINTF arg ; \ - } -#endif -#else -#define SK_DBG_MSG(pAC,comp,lev,arg) -#endif - -/* PLS NOTE: - * ========= - * Due to any restrictions of kernel printf routines do not use other - * format identifiers as: %x %d %c %s . - * Never use any combined format identifiers such as: %lx %ld in your - * printf - argument (arg) because some OS specific kernel printfs may - * only support some basic identifiers. - */ - -/* Debug modules */ - -#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */ -#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */ -#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */ -#define SK_DBGMOD_VPD 0x00000008L /* VPD module */ -#define SK_DBGMOD_I2C 0x00000010L /* I2C module */ -#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */ -#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */ -#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ -#define SK_DBGMOD_PECP 0x00000100L /* PECP module */ -#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */ - -/* Debug events */ - -#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */ -#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */ -#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */ -#define SK_DBGCAT_TX 0x00000008L /* transmit path */ -#define SK_DBGCAT_RX 0x00000010L /* receive path */ -#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */ -#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */ -#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */ -#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */ - -#endif /* __INC_SKDEBUG_H */ diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h deleted file mode 100644 index 91b8d4f45904..000000000000 --- a/drivers/net/sk98lin/h/skdrv1st.h +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * - * Name: skdrv1st.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.4 $ - * Date: $Date: 2003/11/12 14:28:14 $ - * Purpose: First header file for driver and all other modules - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This is the first include file of the driver, which includes all - * neccessary system header files and some of the GEnesis header files. - * It also defines some basic items. - * - * Include File Hierarchy: - * - * see skge.c - * - ******************************************************************************/ - -#ifndef __INC_SKDRV1ST_H -#define __INC_SKDRV1ST_H - -typedef struct s_AC SK_AC; - -/* Set card versions */ -#define SK_FAR - -/* override some default functions with optimized linux functions */ - -#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2) -#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4) -#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8) -#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2) -#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4) -#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8) - -#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define SK_CS_CALCULATE_CHECKSUM -#ifndef CONFIG_X86_64 -#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) -#else -#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff) -#endif - -#include "h/sktypes.h" -#include "h/skerror.h" -#include "h/skdebug.h" -#include "h/lm80.h" -#include "h/xmac_ii.h" - -#ifdef __LITTLE_ENDIAN -#define SK_LITTLE_ENDIAN -#else -#define SK_BIG_ENDIAN -#endif - -#define SK_NET_DEVICE net_device - - -/* we use gethrtime(), return unit: nanoseconds */ -#define SK_TICKS_PER_SEC 100 - -#define SK_MEM_MAPPED_IO - -// #define SK_RLMT_SLOW_LOOKAHEAD - -#define SK_MAX_MACS 2 -#define SK_MAX_NETS 2 - -#define SK_IOC char __iomem * - -typedef struct s_DrvRlmtMbuf SK_MBUF; - -#define SK_CONST64 INT64_C -#define SK_CONSTU64 UINT64_C - -#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size) -#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size) -#define SK_MEMSET(dest,val,size) memset(dest,val,size) -#define SK_STRLEN(pStr) strlen((char*)(pStr)) -#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size) -#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2)) - -/* macros to access the adapter */ -#define SK_OUT8(b,a,v) writeb((v), ((b)+(a))) -#define SK_OUT16(b,a,v) writew((v), ((b)+(a))) -#define SK_OUT32(b,a,v) writel((v), ((b)+(a))) -#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a))) -#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a))) -#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a))) - -#define int8_t char -#define int16_t short -#define int32_t long -#define int64_t long long -#define uint8_t u_char -#define uint16_t u_short -#define uint32_t u_long -#define uint64_t unsigned long long -#define t_scalar_t int -#define t_uscalar_t unsigned int -#define uintptr_t unsigned long - -#define __CONCAT__(A,B) A##B - -#define INT32_C(a) __CONCAT__(a,L) -#define INT64_C(a) __CONCAT__(a,LL) -#define UINT32_C(a) __CONCAT__(a,UL) -#define UINT64_C(a) __CONCAT__(a,ULL) - -#ifdef DEBUG -#define SK_DBG_PRINTF printk -#ifndef SK_DEBUG_CHKMOD -#define SK_DEBUG_CHKMOD 0 -#endif -#ifndef SK_DEBUG_CHKCAT -#define SK_DEBUG_CHKCAT 0 -#endif -/* those come from the makefile */ -#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD) -#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT) - -extern void SkDbgPrintf(const char *format,...); - -#define SK_DBGMOD_DRV 0x00010000 - -/**** possible driver debug categories ********************************/ -#define SK_DBGCAT_DRV_ENTRY 0x00010000 -#define SK_DBGCAT_DRV_SAP 0x00020000 -#define SK_DBGCAT_DRV_MCA 0x00040000 -#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 -#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 -#define SK_DBGCAT_DRV_PROGRESS 0x00200000 -#define SK_DBGCAT_DRV_MSG 0x00400000 -#define SK_DBGCAT_DRV_PROM 0x00800000 -#define SK_DBGCAT_DRV_TX_FRAME 0x01000000 -#define SK_DBGCAT_DRV_ERROR 0x02000000 -#define SK_DBGCAT_DRV_INT_SRC 0x04000000 -#define SK_DBGCAT_DRV_EVENT 0x08000000 - -#endif - -#define SK_ERR_LOG SkErrorLog - -extern void SkErrorLog(SK_AC*, int, int, char*); - -#endif - diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h deleted file mode 100644 index 3fa67171e832..000000000000 --- a/drivers/net/sk98lin/h/skdrv2nd.h +++ /dev/null @@ -1,447 +0,0 @@ -/****************************************************************************** - * - * Name: skdrv2nd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.10 $ - * Date: $Date: 2003/12/11 16:04:45 $ - * Purpose: Second header file for driver and all other modules - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This is the second include file of the driver, which includes all other - * neccessary files and defines all structures and constants used by the - * driver and the common modules. - * - * Include File Hierarchy: - * - * see skge.c - * - ******************************************************************************/ - -#ifndef __INC_SKDRV2ND_H -#define __INC_SKDRV2ND_H - -#include "h/skqueue.h" -#include "h/skgehwt.h" -#include "h/sktimer.h" -#include "h/ski2c.h" -#include "h/skgepnmi.h" -#include "h/skvpd.h" -#include "h/skgehw.h" -#include "h/skgeinit.h" -#include "h/skaddr.h" -#include "h/skgesirq.h" -#include "h/skcsum.h" -#include "h/skrlmt.h" -#include "h/skgedrv.h" - - -extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned); -extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*); -extern SK_U64 SkOsGetTime(SK_AC*); -extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*); -extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*); -extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*); -extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16); -extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); -extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); - -#ifdef SK_DIAG_SUPPORT -extern int SkDrvEnterDiagMode(SK_AC *pAc); -extern int SkDrvLeaveDiagMode(SK_AC *pAc); -#endif - -struct s_DrvRlmtMbuf { - SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ - SK_U8 *pData; /* Data buffer (virtually contig.). */ - unsigned Size; /* Data buffer size. */ - unsigned Length; /* Length of packet (<= Size). */ - SK_U32 PortIdx; /* Receiving/transmitting port. */ -#ifdef SK_RLMT_MBUF_PRIVATE - SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */ -#endif /* SK_RLMT_MBUF_PRIVATE */ - struct sk_buff *pOs; /* Pointer to message block */ -}; - - -/* - * Time macros - */ -#if SK_TICKS_PER_SEC == 100 -#define SK_PNMI_HUNDREDS_SEC(t) (t) -#else -#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \ - (SK_TICKS_PER_SEC)) -#endif - -/* - * New SkOsGetTime - */ -#define SkOsGetTimeCurrent(pAC, pUsec) {\ - struct timeval t;\ - do_gettimeofday(&t);\ - *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\ -} - - -/* - * ioctl definitions - */ -#define SK_IOCTL_BASE (SIOCDEVPRIVATE) -#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0) -#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) -#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) -#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) -#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) - -typedef struct s_IOCTL SK_GE_IOCTL; - -struct s_IOCTL { - char __user * pData; - unsigned int Len; -}; - - -/* - * define sizes of descriptor rings in bytes - */ - -#define TX_RING_SIZE (8*1024) -#define RX_RING_SIZE (24*1024) - -/* - * Buffer size for ethernet packets - */ -#define ETH_BUF_SIZE 1540 -#define ETH_MAX_MTU 1514 -#define ETH_MIN_MTU 60 -#define ETH_MULTICAST_BIT 0x01 -#define SK_JUMBO_MTU 9000 - -/* - * transmit priority selects the queue: LOW=asynchron, HIGH=synchron - */ -#define TX_PRIO_LOW 0 -#define TX_PRIO_HIGH 1 - -/* - * alignment of rx/tx descriptors - */ -#define DESCR_ALIGN 64 - -/* - * definitions for pnmi. TODO - */ -#define SK_DRIVER_RESET(pAC, IoC) 0 -#define SK_DRIVER_SENDEVENT(pAC, IoC) 0 -#define SK_DRIVER_SELFTEST(pAC, IoC) 0 -/* For get mtu you must add an own function */ -#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0 -#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0 -#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0 - -/* -** Interim definition of SK_DRV_TIMER placed in this file until -** common modules have been finalized -*/ -#define SK_DRV_TIMER 11 -#define SK_DRV_MODERATION_TIMER 1 -#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */ -#define SK_DRV_RX_CLEANUP_TIMER 2 -#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */ - -/* -** Definitions regarding transmitting frames -** any calculating any checksum. -*/ -#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6 -#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6 -#define C_LEN_ETHERMAC_HEADER_LENTYPE 2 -#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \ - (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \ - (C_LEN_ETHERMAC_HEADER_LENTYPE) ) - -#define C_LEN_ETHERMTU_MINSIZE 46 -#define C_LEN_ETHERMTU_MAXSIZE_STD 1500 -#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000 - -#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \ - (C_LEN_ETHERMTU_MINSIZE) ) - -#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER -#define C_OFFSET_IPHEADER_IPPROTO 9 -#define C_OFFSET_TCPHEADER_TCPCS 16 -#define C_OFFSET_UDPHEADER_UDPCS 6 - -#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \ - (C_OFFSET_IPHEADER_IPPROTO) ) - -#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */ -#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */ - -/* TX and RX descriptors *****************************************************/ - -typedef struct s_RxD RXD; /* the receive descriptor */ - -struct s_RxD { - volatile SK_U32 RBControl; /* Receive Buffer Control */ - SK_U32 VNextRxd; /* Next receive descriptor,low dword */ - SK_U32 VDataLow; /* Receive buffer Addr, low dword */ - SK_U32 VDataHigh; /* Receive buffer Addr, high dword */ - SK_U32 FrameStat; /* Receive Frame Status word */ - SK_U32 TimeStamp; /* Time stamp from XMAC */ - SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */ - SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */ - RXD *pNextRxd; /* Pointer to next Rxd */ - struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ -}; - -typedef struct s_TxD TXD; /* the transmit descriptor */ - -struct s_TxD { - volatile SK_U32 TBControl; /* Transmit Buffer Control */ - SK_U32 VNextTxd; /* Next transmit descriptor,low dword */ - SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */ - SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */ - SK_U32 FrameStat; /* Transmit Frame Status Word */ - SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */ - SK_U16 TcpSumSt; /* TCP Sum Start */ - SK_U16 TcpSumWr; /* TCP Sum Write */ - SK_U32 TcpReserved; /* not used */ - TXD *pNextTxd; /* Pointer to next Txd */ - struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ -}; - -/* Used interrupt bits in the interrupts source register *********************/ - -#define DRIVER_IRQS ((IS_IRQ_SW) | \ - (IS_R1_F) |(IS_R2_F) | \ - (IS_XS1_F) |(IS_XA1_F) | \ - (IS_XS2_F) |(IS_XA2_F)) - -#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \ - (IS_EXT_REG) |(IS_TIMINT) | \ - (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \ - (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \ - (IS_MAC1) |(IS_LNK_SYNC_M1)| \ - (IS_MAC2) |(IS_LNK_SYNC_M2)| \ - (IS_R1_C) |(IS_R2_C) | \ - (IS_XS1_C) |(IS_XA1_C) | \ - (IS_XS2_C) |(IS_XA2_C)) - -#define IRQ_MASK ((IS_IRQ_SW) | \ - (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \ - (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \ - (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \ - (IS_HW_ERR) |(IS_I2C_READY)| \ - (IS_EXT_REG) |(IS_TIMINT) | \ - (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \ - (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \ - (IS_MAC1) |(IS_MAC2) | \ - (IS_R1_C) |(IS_R2_C) | \ - (IS_XS1_C) |(IS_XA1_C) | \ - (IS_XS2_C) |(IS_XA2_C)) - -#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ - -typedef struct s_DevNet DEV_NET; - -struct s_DevNet { - int PortNr; - int NetNr; - SK_AC *pAC; -}; - -typedef struct s_TxPort TX_PORT; - -struct s_TxPort { - /* the transmit descriptor rings */ - caddr_t pTxDescrRing; /* descriptor area memory */ - SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */ - TXD *pTxdRingHead; /* Head of Tx rings */ - TXD *pTxdRingTail; /* Tail of Tx rings */ - TXD *pTxdRingPrev; /* descriptor sent previously */ - int TxdRingFree; /* # of free entrys */ - spinlock_t TxDesRingLock; /* serialize descriptor accesses */ - SK_IOC HwAddr; /* bmu registers address */ - int PortIndex; /* index number of port (0 or 1) */ -}; - -typedef struct s_RxPort RX_PORT; - -struct s_RxPort { - /* the receive descriptor rings */ - caddr_t pRxDescrRing; /* descriptor area memory */ - SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */ - RXD *pRxdRingHead; /* Head of Rx rings */ - RXD *pRxdRingTail; /* Tail of Rx rings */ - RXD *pRxdRingPrev; /* descriptor given to BMU previously */ - int RxdRingFree; /* # of free entrys */ - int RxCsum; /* use receive checksum hardware */ - spinlock_t RxDesRingLock; /* serialize descriptor accesses */ - int RxFillLimit; /* limit for buffers in ring */ - SK_IOC HwAddr; /* bmu registers address */ - int PortIndex; /* index number of port (0 or 1) */ -}; - -/* Definitions needed for interrupt moderation *******************************/ - -#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F)) -#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F)) -#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX)) -#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F)) -#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS) -#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY)) -#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY)) -#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) -#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) - -#define C_INT_MOD_NONE 1 -#define C_INT_MOD_STATIC 2 -#define C_INT_MOD_DYNAMIC 4 - -#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */ -#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */ - -#define C_INTS_PER_SEC_DEFAULT 2000 -#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */ -#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */ -#define C_INT_MOD_IPS_LOWER_RANGE 30 -#define C_INT_MOD_IPS_UPPER_RANGE 40000 - - -typedef struct s_DynIrqModInfo DIM_INFO; -struct s_DynIrqModInfo { - unsigned long PrevTimeVal; - unsigned int PrevSysLoad; - unsigned int PrevUsedTime; - unsigned int PrevTotalTime; - int PrevUsedDescrRatio; - int NbrProcessedDescr; - SK_U64 PrevPort0RxIntrCts; - SK_U64 PrevPort1RxIntrCts; - SK_U64 PrevPort0TxIntrCts; - SK_U64 PrevPort1TxIntrCts; - SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */ - - int MaxModIntsPerSec; /* Moderation Threshold */ - int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ - int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ - - long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */ - SK_BOOL DisplayStats; /* Stats yes/no */ - SK_BOOL AutoSizing; /* Resize DIM-timer on/off */ - int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */ - - SK_TIMER ModTimer; /* just some timer */ -}; - -typedef struct s_PerStrm PER_STRM; - -#define SK_ALLOC_IRQ 0x00000001 - -#ifdef SK_DIAG_SUPPORT -#define DIAG_ACTIVE 1 -#define DIAG_NOTACTIVE 0 -#endif - -/**************************************************************************** - * Per board structure / Adapter Context structure: - * Allocated within attach(9e) and freed within detach(9e). - * Contains all 'per device' necessary handles, flags, locks etc.: - */ -struct s_AC { - SK_GEINIT GIni; /* GE init struct */ - SK_PNMI Pnmi; /* PNMI data struct */ - SK_VPD vpd; /* vpd data struct */ - SK_QUEUE Event; /* Event queue */ - SK_HWT Hwt; /* Hardware Timer control struct */ - SK_TIMCTRL Tim; /* Software Timer control struct */ - SK_I2C I2c; /* I2C relevant data structure */ - SK_ADDR Addr; /* for Address module */ - SK_CSUM Csum; /* for checksum module */ - SK_RLMT Rlmt; /* for rlmt module */ - spinlock_t SlowPathLock; /* Normal IRQ lock */ - struct timer_list BlinkTimer; /* for LED blinking */ - int LedsOn; - SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */ - int RlmtMode; /* link check mode to set */ - int RlmtNets; /* Number of nets */ - - SK_IOC IoBase; /* register set of adapter */ - int BoardLevel; /* level of active hw init (0-2) */ - - SK_U32 AllocFlag; /* flag allocation of resources */ - struct pci_dev *PciDev; /* for access to pci config space */ - struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ - - int RxBufSize; /* length of receive buffers */ - struct net_device_stats stats; /* linux 'netstat -i' statistics */ - int Index; /* internal board index number */ - - /* adapter RAM sizes for queues of active port */ - int RxQueueSize; /* memory used for receive queue */ - int TxSQueueSize; /* memory used for sync. tx queue */ - int TxAQueueSize; /* memory used for async. tx queue */ - - int PromiscCount; /* promiscuous mode counter */ - int AllMultiCount; /* allmulticast mode counter */ - int MulticCount; /* number of different MC */ - /* addresses for this board */ - /* (may be more than HW can)*/ - - int HWRevision; /* Hardware revision */ - int ActivePort; /* the active XMAC port */ - int MaxPorts; /* number of activated ports */ - int TxDescrPerRing; /* # of descriptors per tx ring */ - int RxDescrPerRing; /* # of descriptors per rx ring */ - - caddr_t pDescrMem; /* Pointer to the descriptor area */ - dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ - - /* the port structures with descriptor rings */ - TX_PORT TxPort[SK_MAX_MACS][2]; - RX_PORT RxPort[SK_MAX_MACS]; - - SK_BOOL CheckQueue; /* check event queue soon */ - SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */ - DIM_INFO DynIrqModInfo; /* all data related to DIM */ - - /* Only for tests */ - int PortDown; - int ChipsetType; /* Chipset family type - * 0 == Genesis family support - * 1 == Yukon family support - */ -#ifdef SK_DIAG_SUPPORT - SK_U32 DiagModeActive; /* is diag active? */ - SK_BOOL DiagFlowCtrl; /* for control purposes */ - SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */ - SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while - * DIAG is busy with NIC - */ -#endif - -}; - - -#endif /* __INC_SKDRV2ND_H */ - diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h deleted file mode 100644 index da062f766238..000000000000 --- a/drivers/net/sk98lin/h/skerror.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** - * - * Name: skerror.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.7 $ - * Date: $Date: 2003/05/13 17:25:13 $ - * Purpose: SK specific Error log support - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _INC_SKERROR_H_ -#define _INC_SKERROR_H_ - -/* - * Define Error Classes - */ -#define SK_ERRCL_OTHER (0) /* Other error */ -#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */ -#define SK_ERRCL_INIT (1L<<1) /* Initialization error */ -#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */ -#define SK_ERRCL_SW (1L<<3) /* Internal Software error */ -#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */ -#define SK_ERRCL_COMM (1L<<5) /* Communication error */ - - -/* - * Define Error Code Bases - */ -#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */ -#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */ -#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */ -#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */ -#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */ -#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */ -#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */ -#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */ -#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */ -#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */ -#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */ - -#endif /* _INC_SKERROR_H_ */ diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h deleted file mode 100644 index 44fd4c3de818..000000000000 --- a/drivers/net/sk98lin/h/skgedrv.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * - * Name: skgedrv.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.10 $ - * Date: $Date: 2003/07/04 12:25:01 $ - * Purpose: Interface with the driver - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_SKGEDRV_H_ -#define __INC_SKGEDRV_H_ - -/* defines ********************************************************************/ - -/* - * Define the driver events. - * Usually the events are defined by the destination module. - * In case of the driver we put the definition of the events here. - */ -#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */ -#define SK_DRV_NET_UP 2 /* The net is operational */ -#define SK_DRV_NET_DOWN 3 /* The net is down */ -#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */ -#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */ -#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */ -#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */ -#define SK_DRV_PORT_FAIL 8 /* One port fails */ -#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */ -#define SK_DRV_POWER_DOWN 10 /* Power down mode */ -#define SK_DRV_TIMER 11 /* Timer for free use */ -#ifdef SK_NO_RLMT -#define SK_DRV_LINK_UP 12 /* Link Up event for driver */ -#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */ -#endif -#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */ -#endif /* __INC_SKGEDRV_H_ */ diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h deleted file mode 100644 index f6282b7956db..000000000000 --- a/drivers/net/sk98lin/h/skgehw.h +++ /dev/null @@ -1,2126 +0,0 @@ -/****************************************************************************** - * - * Name: skgehw.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.56 $ - * Date: $Date: 2003/09/23 09:01:00 $ - * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_SKGEHW_H -#define __INC_SKGEHW_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* defines ********************************************************************/ - -#define BIT_31 (1UL << 31) -#define BIT_30 (1L << 30) -#define BIT_29 (1L << 29) -#define BIT_28 (1L << 28) -#define BIT_27 (1L << 27) -#define BIT_26 (1L << 26) -#define BIT_25 (1L << 25) -#define BIT_24 (1L << 24) -#define BIT_23 (1L << 23) -#define BIT_22 (1L << 22) -#define BIT_21 (1L << 21) -#define BIT_20 (1L << 20) -#define BIT_19 (1L << 19) -#define BIT_18 (1L << 18) -#define BIT_17 (1L << 17) -#define BIT_16 (1L << 16) -#define BIT_15 (1L << 15) -#define BIT_14 (1L << 14) -#define BIT_13 (1L << 13) -#define BIT_12 (1L << 12) -#define BIT_11 (1L << 11) -#define BIT_10 (1L << 10) -#define BIT_9 (1L << 9) -#define BIT_8 (1L << 8) -#define BIT_7 (1L << 7) -#define BIT_6 (1L << 6) -#define BIT_5 (1L << 5) -#define BIT_4 (1L << 4) -#define BIT_3 (1L << 3) -#define BIT_2 (1L << 2) -#define BIT_1 (1L << 1) -#define BIT_0 1L - -#define BIT_15S (1U << 15) -#define BIT_14S (1 << 14) -#define BIT_13S (1 << 13) -#define BIT_12S (1 << 12) -#define BIT_11S (1 << 11) -#define BIT_10S (1 << 10) -#define BIT_9S (1 << 9) -#define BIT_8S (1 << 8) -#define BIT_7S (1 << 7) -#define BIT_6S (1 << 6) -#define BIT_5S (1 << 5) -#define BIT_4S (1 << 4) -#define BIT_3S (1 << 3) -#define BIT_2S (1 << 2) -#define BIT_1S (1 << 1) -#define BIT_0S 1 - -#define SHIFT31(x) ((x) << 31) -#define SHIFT30(x) ((x) << 30) -#define SHIFT29(x) ((x) << 29) -#define SHIFT28(x) ((x) << 28) -#define SHIFT27(x) ((x) << 27) -#define SHIFT26(x) ((x) << 26) -#define SHIFT25(x) ((x) << 25) -#define SHIFT24(x) ((x) << 24) -#define SHIFT23(x) ((x) << 23) -#define SHIFT22(x) ((x) << 22) -#define SHIFT21(x) ((x) << 21) -#define SHIFT20(x) ((x) << 20) -#define SHIFT19(x) ((x) << 19) -#define SHIFT18(x) ((x) << 18) -#define SHIFT17(x) ((x) << 17) -#define SHIFT16(x) ((x) << 16) -#define SHIFT15(x) ((x) << 15) -#define SHIFT14(x) ((x) << 14) -#define SHIFT13(x) ((x) << 13) -#define SHIFT12(x) ((x) << 12) -#define SHIFT11(x) ((x) << 11) -#define SHIFT10(x) ((x) << 10) -#define SHIFT9(x) ((x) << 9) -#define SHIFT8(x) ((x) << 8) -#define SHIFT7(x) ((x) << 7) -#define SHIFT6(x) ((x) << 6) -#define SHIFT5(x) ((x) << 5) -#define SHIFT4(x) ((x) << 4) -#define SHIFT3(x) ((x) << 3) -#define SHIFT2(x) ((x) << 2) -#define SHIFT1(x) ((x) << 1) -#define SHIFT0(x) ((x) << 0) - -/* - * Configuration Space header - * Since this module is used for different OS', those may be - * duplicate on some of them (e.g. Linux). But to keep the - * common source, we have to live with this... - */ -#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */ -#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */ -#define PCI_COMMAND 0x04 /* 16 bit Command */ -#define PCI_STATUS 0x06 /* 16 bit Status */ -#define PCI_REV_ID 0x08 /* 8 bit Revision ID */ -#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */ -#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */ -#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */ -#define PCI_HEADER_T 0x0e /* 8 bit Header Type */ -#define PCI_BIST 0x0f /* 8 bit Built-in selftest */ -#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */ -#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */ - /* Byte 0x18..0x2b: reserved */ -#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */ -#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */ -#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */ -#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */ - /* Byte 0x35..0x3b: reserved */ -#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */ -#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */ -#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */ -#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */ - /* Device Dependent Region */ -#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */ -#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */ - /* Power Management Region */ -#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */ -#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */ -#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */ -#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */ - /* Byte 0x4e: reserved */ -#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */ - /* VPD Region */ -#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ -#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */ -#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ -#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ - /* Byte 0x58..0x59: reserved */ -#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */ - /* Byte 0x5c..0xff: reserved */ - -/* - * I2C Address (PCI Config) - * - * Note: The temperature and voltage sensors are relocated on a different - * I2C bus. - */ -#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */ - -/* - * Define Bits and Values of the registers - */ -/* PCI_COMMAND 16 bit Command */ - /* Bit 15..11: reserved */ -#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */ -#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */ -#define PCI_SERREN BIT_8S /* SERR enable */ -#define PCI_ADSTEP BIT_7S /* Address Stepping */ -#define PCI_PERREN BIT_6S /* Parity Report Response enable */ -#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */ -#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */ -#define PCI_SCYCEN BIT_3S /* Special Cycle enable */ -#define PCI_BMEN BIT_2S /* Bus Master enable */ -#define PCI_MEMEN BIT_1S /* Memory Space Access enable */ -#define PCI_IOEN BIT_0S /* I/O Space Access enable */ - -#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\ - PCI_BMEN | PCI_MEMEN | PCI_IOEN) - -/* PCI_STATUS 16 bit Status */ -#define PCI_PERR BIT_15S /* Parity Error */ -#define PCI_SERR BIT_14S /* Signaled SERR */ -#define PCI_RMABORT BIT_13S /* Received Master Abort */ -#define PCI_RTABORT BIT_12S /* Received Target Abort */ - /* Bit 11: reserved */ -#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */ -#define PCI_DEV_FAST (0<<9) /* fast */ -#define PCI_DEV_MEDIUM (1<<9) /* medium */ -#define PCI_DEV_SLOW (2<<9) /* slow */ -#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */ -#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */ -#define PCI_UDF BIT_6S /* User Defined Features */ -#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */ -#define PCI_NEWCAP BIT_4S /* New cap. list implemented */ -#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */ - /* Bit 2.. 0: reserved */ - -#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\ - PCI_DATAPERR) - -/* PCI_CLASS_CODE 24 bit Class Code */ -/* Byte 2: Base Class (02) */ -/* Byte 1: SubClass (00) */ -/* Byte 0: Programming Interface (00) */ - -/* PCI_CACHE_LSZ 8 bit Cache Line Size */ -/* Possible values: 0,2,4,8,16,32,64,128 */ - -/* PCI_HEADER_T 8 bit Header Type */ -#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */ -#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */ - -/* PCI_BIST 8 bit Built-in selftest */ -/* Built-in Self test not supported (optional) */ - -/* PCI_BASE_1ST 32 bit 1st Base address */ -#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */ -#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */ -#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */ -#define PCI_PREFEN BIT_3 /* Prefetchable */ -#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */ -#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */ -#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */ -#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */ -#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */ - -/* PCI_BASE_2ND 32 bit 2nd Base address */ -#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */ -#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */ - /* Bit 1: reserved */ -#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */ - -/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */ -#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */ -#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */ -#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */ - /* Bit 10.. 1: reserved */ -#define PCI_ROMEN BIT_0 /* Address Decode enable */ - -/* Device Dependent Region */ -/* PCI_OUR_REG_1 32 bit Our Register 1 */ - /* Bit 31..29: reserved */ -#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */ -#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */ -#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */ -#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */ -#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */ -#define PCI_EN_IO BIT_23 /* Mapping to I/O space */ -#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */ - /* 1 = Map Flash to memory */ - /* 0 = Disable addr. dec */ -#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */ -#define PCI_PAGE_16 (0L<<20) /* 16 k pages */ -#define PCI_PAGE_32K (1L<<20) /* 32 k pages */ -#define PCI_PAGE_64K (2L<<20) /* 64 k pages */ -#define PCI_PAGE_128K (3L<<20) /* 128 k pages */ - /* Bit 19: reserved */ -#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */ -#define PCI_NOTAR BIT_15 /* No turnaround cycle */ -#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */ -#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */ -#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */ -#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */ -#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */ -#define PCI_BURST_DIS BIT_9 /* Burst Disable */ -#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */ -#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */ -#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */ - - -/* PCI_OUR_REG_2 32 bit Our Register 2 */ -#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */ -#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */ -#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */ - /* Bit 13..12: reserved */ -#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */ -#define PCI_PATCH_DIR_3 BIT_11 -#define PCI_PATCH_DIR_2 BIT_10 -#define PCI_PATCH_DIR_1 BIT_9 -#define PCI_PATCH_DIR_0 BIT_8 -#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */ -#define PCI_EXT_PATCH_3 BIT_7 -#define PCI_EXT_PATCH_2 BIT_6 -#define PCI_EXT_PATCH_1 BIT_5 -#define PCI_EXT_PATCH_0 BIT_4 -#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */ -#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */ - /* Bit 1: reserved */ -#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */ - - -/* Power Management Region */ -/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */ -#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */ -#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */ -#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */ -#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */ -#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */ -#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */ -#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */ -#define PCI_PM_D1_SUP BIT_9S /* D1 Support */ - /* Bit 8.. 6: reserved */ -#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */ -#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */ -#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */ -#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */ - -/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */ -#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */ -#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */ -#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */ -#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */ - /* Bit 7.. 2: reserved */ -#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */ - -#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */ -#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */ -#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */ -#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */ - -/* VPD Region */ -/* PCI_VPD_ADR_REG 16 bit VPD Address Register */ -#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */ -#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */ - -/* Control Register File (Address Map) */ - -/* - * Bank 0 - */ -#define B0_RAP 0x0000 /* 8 bit Register Address Port */ - /* 0x0001 - 0x0003: reserved */ -#define B0_CTST 0x0004 /* 16 bit Control/Status register */ -#define B0_LED 0x0006 /* 8 Bit LED register */ -#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */ -#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */ -#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */ -#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */ -#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */ -#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */ - /* 0x001c: reserved */ - -/* B0 XMAC 1 registers (GENESIS only) */ -#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/ - /* 0x0022 - 0x0027: reserved */ -#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */ - /* 0x002a - 0x002f: reserved */ -#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */ - /* 0x0032 - 0x0033: reserved */ -#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */ - /* 0x0036 - 0x003f: reserved */ - -/* B0 XMAC 2 registers (GENESIS only) */ -#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/ - /* 0x0042 - 0x0047: reserved */ -#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */ - /* 0x004a - 0x004f: reserved */ -#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */ - /* 0x0052 - 0x0053: reserved */ -#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */ - /* 0x0056 - 0x005f: reserved */ - -/* BMU Control Status Registers */ -#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */ -#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */ -#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ -#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/ -#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ -#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/ - /* 0x0078 - 0x007f: reserved */ - -/* - * Bank 1 - * - completely empty (this is the RAP Block window) - * Note: if RAP = 1 this page is reserved - */ - -/* - * Bank 2 - */ -/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */ -#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */ - /* 0x0106 - 0x0107: reserved */ -#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */ - /* 0x010e - 0x010f: reserved */ -#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */ - /* 0x0116 - 0x0117: reserved */ -#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */ -#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */ -#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */ -#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */ - /* Eprom registers are currently of no use */ -#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */ -#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */ -#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */ -#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */ -#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ -#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */ - /* 0x0125 - 0x0127: reserved */ -#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */ -#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */ - /* 0x012a - 0x012f: reserved */ -#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */ -#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */ -#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */ -#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */ - /* 0x013a - 0x013f: reserved */ -#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/ -#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */ -#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */ -#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */ -#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */ -#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */ - /* 0x0154 - 0x0157: reserved */ -#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */ -#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */ - /* 0x015a - 0x015b: reserved */ -#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */ -#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */ -#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */ -#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */ -#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */ - -/* Blink Source Counter (GENESIS only) */ -#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */ -#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */ -#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */ -#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */ -#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */ - /* 0x017c - 0x017f: reserved */ - -/* - * Bank 3 - */ -/* RAM Random Registers */ -#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */ -#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */ -#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */ - /* 0x018c - 0x018f: reserved */ - -/* RAM Interface Registers */ -/* - * The HW-Spec. calls this registers Timeout Value 0..11. But this names are - * not usable in SW. Please notice these are NOT real timeouts, these are - * the number of qWords transferred continuously. - */ -#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */ -#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */ -#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */ -#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */ -#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */ -#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */ -#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */ -#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */ -#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */ -#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */ -#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/ -#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/ -#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */ - /* 0x019d - 0x019f: reserved */ -#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */ -#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */ - /* 0x01a3 - 0x01af: reserved */ - -/* MAC Arbiter Registers (GENESIS only) */ -/* these are the no. of qWord transferred continuously and NOT real timeouts */ -#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */ -#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */ -#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */ -#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */ -#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */ -#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */ -#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */ -#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */ -#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */ -#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */ - /* 0x01bc - 0x01bf: reserved */ -#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */ -#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */ -#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */ -#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */ -#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */ -#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */ -#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */ -#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */ -#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */ -#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */ - /* 0x01cc - 0x01cf: reserved */ - -/* Packet Arbiter Registers (GENESIS only) */ -/* these are real timeouts */ -#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */ - /* 0x01d2 - 0x01d3: reserved */ -#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */ - /* 0x01d6 - 0x01d7: reserved */ -#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */ - /* 0x01da - 0x01db: reserved */ -#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */ - /* 0x01de - 0x01df: reserved */ -#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */ - /* 0x01e2 - 0x01e3: reserved */ -#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */ - /* 0x01e6 - 0x01e7: reserved */ -#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */ - /* 0x01ea - 0x01eb: reserved */ -#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */ - /* 0x01ee - 0x01ef: reserved */ -#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */ -#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */ - /* 0x01f4 - 0x01ff: reserved */ - -/* - * Bank 4 - 5 - */ -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ -#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/ -#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */ -#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */ -#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */ -#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */ -#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */ -#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */ - /* 0x0213 - 0x027f: reserved */ - /* 0x0280 - 0x0292: MAC 2 */ - /* 0x0213 - 0x027f: reserved */ - -/* - * Bank 6 - */ -/* External registers (GENESIS only) */ -#define B6_EXT_REG 0x0300 - -/* - * Bank 7 - */ -/* This is a copy of the Configuration register file (lower half) */ -#define B7_CFG_SPC 0x0380 - -/* - * Bank 8 - 15 - */ -/* Receive and Transmit Queue Registers, use Q_ADDR() to access */ -#define B8_Q_REGS 0x0400 - -/* Queue Register Offsets, use Q_ADDR() to access */ -#define Q_D 0x00 /* 8*32 bit Current Descriptor */ -#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */ -#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */ -#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */ -#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */ -#define Q_BC 0x30 /* 32 bit Current Byte Counter */ -#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */ -#define Q_F 0x38 /* 32 bit Flag Register */ -#define Q_T1 0x3c /* 32 bit Test Register 1 */ -#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */ -#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */ -#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */ -#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */ -#define Q_T2 0x40 /* 32 bit Test Register 2 */ -#define Q_T3 0x44 /* 32 bit Test Register 3 */ - /* 0x48 - 0x7f: reserved */ - -/* - * Bank 16 - 23 - */ -/* RAM Buffer Registers */ -#define B16_RAM_REGS 0x0800 - -/* RAM Buffer Register Offsets, use RB_ADDR() to access */ -#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */ -#define RB_END 0x04 /* 32 bit RAM Buffer End Address */ -#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */ -#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */ -#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */ -#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */ -#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */ -#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */ - /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */ -#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */ -#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */ -#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */ -#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */ -#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */ - /* 0x2c - 0x7f: reserved */ - -/* - * Bank 24 - */ -/* - * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only) - * use MR_ADDR() to access - */ -#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */ -#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */ - /* 0x0c08 - 0x0c0b: reserved */ -#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */ -#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */ -#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */ -#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/ -#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */ -#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */ -#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/ -#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */ -#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */ - /* 0x0c1f: reserved */ -#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */ -#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */ -#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */ -#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */ - /* 0x0c2a - 0x0c2f: reserved */ -#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */ -#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */ -#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */ -#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */ - /* 0x0c3a - 0x0c3b: reserved */ -#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */ - /* 0x0c3d - 0x0c3f: reserved */ - -/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */ -#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */ -#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */ -#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */ -#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */ -#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */ - /* 0x0c54 - 0x0c5f: reserved */ -#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */ - /* 0x0c64 - 0x0c67: reserved */ -#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */ - /* 0x0c6c - 0x0c6f: reserved */ -#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */ - /* 0x0c74 - 0x0c77: reserved */ -#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */ - /* 0x0c7c - 0x0c7f: reserved */ - -/* - * Bank 25 - */ - /* 0x0c80 - 0x0cbf: MAC 2 */ - /* 0x0cc0 - 0x0cff: reserved */ - -/* - * Bank 26 - */ -/* - * Transmit MAC FIFO and Transmit LED Registers (GENESIS only), - * use MR_ADDR() to access - */ -#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */ -#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */ -#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */ -#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */ -#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */ -#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */ -#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */ -#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */ - /* 0x0c1b: reserved */ -#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */ -#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */ -#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */ - /* 0x0d1f: reserved */ -#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */ -#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */ -#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */ -#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */ - /* 0x0d2a - 0x0d3f: reserved */ - -/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */ -#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */ -#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ -#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */ - /* 0x0d4c - 0x0d5f: reserved */ -#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */ -#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */ -#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */ - /* 0x0d6c - 0x0d6f: reserved */ -#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */ -#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */ -#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */ - /* 0x0d7c - 0x0d7f: reserved */ - -/* - * Bank 27 - */ - /* 0x0d80 - 0x0dbf: MAC 2 */ - /* 0x0daa - 0x0dff: reserved */ - -/* - * Bank 28 - */ -/* Descriptor Poll Timer Registers */ -#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */ -#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */ -#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */ - /* 0x0e09: reserved */ -#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */ - /* 0x0e0b: reserved */ - -/* Time Stamp Timer Registers (YUKON only) */ - /* 0x0e10: reserved */ -#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */ -#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */ - /* 0x0e19: reserved */ -#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */ - /* 0x0e1b - 0x0e7f: reserved */ - -/* - * Bank 29 - */ - /* 0x0e80 - 0x0efc: reserved */ - -/* - * Bank 30 - */ -/* GMAC and GPHY Control Registers (YUKON only) */ -#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */ -#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */ -#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */ - /* 0x0f09 - 0x0f0b: reserved */ -#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */ - /* 0x0f0d - 0x0f0f: reserved */ -#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */ - /* 0x0f14 - 0x0f1f: reserved */ - -/* Wake-up Frame Pattern Match Control Registers (YUKON only) */ - -#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */ - -#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */ -#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */ -#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */ -#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */ -#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */ -#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */ - -/* use this macro to access above registers */ -#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs)) - - -/* WOL Pattern Length Registers (YUKON only) */ - -#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */ -#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */ - -/* WOL Pattern Counter Registers (YUKON only) */ - -#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */ -#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */ - /* 0x0f40 - 0x0f7f: reserved */ - -/* - * Bank 31 - */ -/* 0x0f80 - 0x0fff: reserved */ - -/* - * Bank 32 - 33 - */ -#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */ - -/* - * Bank 0x22 - 0x3f - */ -/* 0x1100 - 0x1fff: reserved */ - -/* - * Bank 0x40 - 0x4f - */ -#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */ - -/* - * Bank 0x50 - 0x5f - */ - -#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */ - -/* - * Bank 0x60 - 0x6f - */ -#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */ - -/* - * Bank 0x70 - 0x7f - */ -#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */ - -/* - * Control Register Bit Definitions: - */ -/* B0_RAP 8 bit Register Address Port */ - /* Bit 7: reserved */ -#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ - -/* B0_CTST 16 bit Control/Status register */ - /* Bit 15..14: reserved */ -#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */ -#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */ -#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */ -#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */ -#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */ -#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */ -#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */ -#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */ -#define CS_STOP_DONE BIT_5S /* Stop Master is finished */ -#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */ -#define CS_MRST_CLR BIT_3S /* Clear Master reset */ -#define CS_MRST_SET BIT_2S /* Set Master reset */ -#define CS_RST_CLR BIT_1S /* Clear Software reset */ -#define CS_RST_SET BIT_0S /* Set Software reset */ - -/* B0_LED 8 Bit LED register */ - /* Bit 7.. 2: reserved */ -#define LED_STAT_ON BIT_1S /* Status LED on */ -#define LED_STAT_OFF BIT_0S /* Status LED off */ - -/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */ -#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */ -#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */ -#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */ -#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */ -#define PC_VAUX_ON BIT_3 /* Switch VAUX On */ -#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */ -#define PC_VCC_ON BIT_1 /* Switch VCC On */ -#define PC_VCC_OFF BIT_0 /* Switch VCC Off */ - -/* B0_ISRC 32 bit Interrupt Source Register */ -/* B0_IMSK 32 bit Interrupt Mask Register */ -/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ -/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */ -#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */ -#define IS_HW_ERR BIT_31 /* Interrupt HW Error */ - /* Bit 30: reserved */ -#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */ -#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */ -#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */ -#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */ -#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */ -#define IS_IRQ_SW BIT_24 /* SW forced IRQ */ -#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */ - /* IRQ from PHY (YUKON only) */ -#define IS_TIMINT BIT_22 /* IRQ from Timer */ -#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */ -#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */ -#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */ -#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */ -/* Receive Queue 1 */ -#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */ -#define IS_R1_F BIT_16 /* Q_R1 End of Frame */ -#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */ -/* Receive Queue 2 */ -#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */ -#define IS_R2_F BIT_13 /* Q_R2 End of Frame */ -#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */ -/* Synchronous Transmit Queue 1 */ -#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */ -#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */ -#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */ -/* Asynchronous Transmit Queue 1 */ -#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */ -#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */ -#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */ -/* Synchronous Transmit Queue 2 */ -#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */ -#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */ -#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */ -/* Asynchronous Transmit Queue 2 */ -#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */ -#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */ -#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ - - -/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ -/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ -/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ -#define IS_ERR_MSK 0x00000fffL /* All Error bits */ - /* Bit 31..14: reserved */ -#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */ -#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */ -#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */ -#define IS_IRQ_STAT BIT_10 /* IRQ status exception */ -#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */ -#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */ -#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */ -#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */ -#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */ -#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */ -#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */ -#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */ -#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ -#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ - -/* B2_CONN_TYP 8 bit Connector type */ -/* B2_PMD_TYP 8 bit PMD type */ -/* Values of connector and PMD type comply to SysKonnect internal std */ - -/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ -#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */ - /* Bit 3.. 2: reserved */ -#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */ -#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/ - -/* B2_CHIP_ID 8 bit Chip Identification Number */ -#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ -#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ -#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */ -#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */ - -#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */ -#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */ - -/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ -#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ - -/* B2_LD_CTRL 8 bit EPROM loader control register */ -/* Bits are currently reserved */ - -/* B2_LD_TEST 8 bit EPROM loader test register */ - /* Bit 7.. 4: reserved */ -#define LD_T_ON BIT_3S /* Loader Test mode on */ -#define LD_T_OFF BIT_2S /* Loader Test mode off */ -#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */ -#define LD_START BIT_0S /* Start loading FPROM */ - -/* - * Timer Section - */ -/* B2_TI_CTRL 8 bit Timer control */ -/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ - /* Bit 7.. 3: reserved */ -#define TIM_START BIT_2S /* Start Timer */ -#define TIM_STOP BIT_1S /* Stop Timer */ -#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */ - -/* B2_TI_TEST 8 Bit Timer Test */ -/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */ -/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */ - /* Bit 7.. 3: reserved */ -#define TIM_T_ON BIT_2S /* Test mode on */ -#define TIM_T_OFF BIT_1S /* Test mode off */ -#define TIM_T_STEP BIT_0S /* Test step */ - -/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */ -/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */ - /* Bit 31..24: reserved */ -#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */ - -/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */ - /* Bit 7.. 2: reserved */ -#define DPT_START BIT_1S /* Start Descriptor Poll Timer */ -#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */ - -/* B2_E_3 8 bit lower 4 bits used for HW self test result */ -#define B2_E3_RES_MASK 0x0f - -/* B2_TST_CTRL1 8 bit Test Control Register 1 */ -#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */ -#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */ -#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */ -#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */ -#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */ -#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */ -#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */ -#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */ - -/* B2_TST_CTRL2 8 bit Test Control Register 2 */ - /* Bit 7.. 4: reserved */ - /* force the following error on the next master read/write */ -#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */ -#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */ -#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */ -#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */ - -/* B2_GP_IO 32 bit General Purpose I/O Register */ - /* Bit 31..26: reserved */ -#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */ -#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */ -#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */ -#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */ -#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */ -#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */ -#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */ -#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */ -#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */ -#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */ - /* Bit 15..10: reserved */ -#define GP_IO_9 BIT_9 /* IO_9 pin */ -#define GP_IO_8 BIT_8 /* IO_8 pin */ -#define GP_IO_7 BIT_7 /* IO_7 pin */ -#define GP_IO_6 BIT_6 /* IO_6 pin */ -#define GP_IO_5 BIT_5 /* IO_5 pin */ -#define GP_IO_4 BIT_4 /* IO_4 pin */ -#define GP_IO_3 BIT_3 /* IO_3 pin */ -#define GP_IO_2 BIT_2 /* IO_2 pin */ -#define GP_IO_1 BIT_1 /* IO_1 pin */ -#define GP_IO_0 BIT_0 /* IO_0 pin */ - -/* B2_I2C_CTRL 32 bit I2C HW Control Register */ -#define I2C_FLAG BIT_31 /* Start read/write if WR */ -#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ -#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ - /* Bit 8.. 5: reserved */ -#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */ -#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ -#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */ -#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */ -#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */ -#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */ -#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */ -#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */ -#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */ -#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */ -#define I2C_STOP BIT_0 /* Interrupt I2C transfer */ - -/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */ - /* Bit 31.. 1 reserved */ -#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */ - -/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ - /* Bit 7.. 3: reserved */ -#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */ -#define I2C_DATA BIT_1S /* I2C Data Port */ -#define I2C_CLK BIT_0S /* I2C Clock Port */ - -/* - * I2C Address - */ -#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ - - -/* B2_BSC_CTRL 8 bit Blink Source Counter Control */ - /* Bit 7.. 2: reserved */ -#define BSC_START BIT_1S /* Start Blink Source Counter */ -#define BSC_STOP BIT_0S /* Stop Blink Source Counter */ - -/* B2_BSC_STAT 8 bit Blink Source Counter Status */ - /* Bit 7.. 1: reserved */ -#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */ - -/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */ -#define BSC_T_ON BIT_2S /* Test mode on */ -#define BSC_T_OFF BIT_1S /* Test mode off */ -#define BSC_T_STEP BIT_0S /* Test step */ - - -/* B3_RAM_ADDR 32 bit RAM Address, to read or write */ - /* Bit 31..19: reserved */ -#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */ - -/* RAM Interface Registers */ -/* B3_RI_CTRL 16 bit RAM Iface Control Register */ - /* Bit 15..10: reserved */ -#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ -#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/ - /* Bit 7.. 2: reserved */ -#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */ -#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */ - -/* B3_RI_TEST 8 bit RAM Iface Test Register */ - /* Bit 15.. 4: reserved */ -#define RI_T_EV BIT_3S /* Timeout Event occured */ -#define RI_T_ON BIT_2S /* Timeout Timer Test On */ -#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */ -#define RI_T_STEP BIT_0S /* Timeout Timer Step */ - -/* MAC Arbiter Registers */ -/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ - /* Bit 15.. 4: reserved */ -#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */ -#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */ -#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */ -#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */ - -/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */ - /* Bit 15.. 8: reserved */ -#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */ -#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */ -#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */ -#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */ -#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */ -#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */ -#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */ -#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */ - -/* Packet Arbiter Registers */ -/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ - /* Bit 15..14: reserved */ -#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */ -#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */ -#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */ -#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */ -#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */ -#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */ -#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */ -#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */ -#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */ -#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */ -#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */ -#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */ -#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */ -#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */ - -#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\ - PA_ENA_TO_TX1 | PA_ENA_TO_TX2) - -/* Rx/Tx Path related Arbiter Test Registers */ -/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ -/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ -/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ -/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ -#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */ -#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */ -#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */ -#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */ -#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */ -#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */ -#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */ -#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */ -#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */ -#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */ -#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */ -#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */ -#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */ -#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */ -#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */ -#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */ - - -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ -/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ -/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ -/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ -/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */ - /* Bit 31..24: reserved */ -#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */ - -/* TXA_CTRL 8 bit Tx Arbiter Control Register */ -#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */ -#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */ -#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */ -#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */ -#define TXA_START_RC BIT_3S /* Start sync Rate Control */ -#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */ -#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */ -#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */ - -/* TXA_TEST 8 bit Tx Arbiter Test Register */ - /* Bit 7.. 6: reserved */ -#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */ -#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */ -#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */ -#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */ -#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */ -#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */ - -/* TXA_STAT 8 bit Tx Arbiter Status Register */ - /* Bit 7.. 1: reserved */ -#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */ - -/* Q_BC 32 bit Current Byte Counter */ - /* Bit 31..16: reserved */ -#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ - -/* BMU Control Status Registers */ -/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ -/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ -/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ -/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */ -/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */ -/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */ -/* Q_CSR 32 bit BMU Control/Status Register */ - /* Bit 31..25: reserved */ -#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */ - /* Bit 23..22: reserved */ -#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */ -#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */ -#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */ -#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */ -#define CSR_HPI_RUN BIT_17 /* Release HPI SM */ -#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */ -#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */ -#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */ -#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */ -#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */ -#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */ -#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */ -#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */ -#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */ -#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */ -#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */ -#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */ -#define CSR_START BIT_4 /* Start Rx/Tx Queue */ -#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */ -#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */ -#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */ -#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */ - -#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\ - CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\ - CSR_TRANS_RST) -#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\ - CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ - CSR_TRANS_RUN) - -/* Q_F 32 bit Flag Register */ - /* Bit 31..28: reserved */ -#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */ -#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */ -#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */ -#define F_WM_REACHED BIT_25 /* Watermark reached */ - /* reserved */ -#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */ - /* Bit 15..11: reserved */ -#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */ - -/* Q_T1 32 bit Test Register 1 */ -/* Holds four State Machine control Bytes */ -#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */ -#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */ -#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */ -#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */ - -/* Q_T1_TR 8 bit Test Register 1 Transfer SM */ -/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */ -/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */ -/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */ - -/* The control status byte of each machine looks like ... */ -#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */ -#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */ -#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */ -#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */ -#define SM_STEP BIT_0S /* Step the State Machine */ -/* The encoding of the states is not supported by the Diagnostics Tool */ - -/* Q_T2 32 bit Test Register 2 */ - /* Bit 31.. 8: reserved */ -#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */ -#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */ -#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */ -#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */ -#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */ -#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */ -#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */ -#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */ - -/* Q_T3 32 bit Test Register 3 */ - /* Bit 31.. 7: reserved */ -#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */ - /* Bit 3: reserved */ -#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */ - -/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */ -/* RB_START 32 bit RAM Buffer Start Address */ -/* RB_END 32 bit RAM Buffer End Address */ -/* RB_WP 32 bit RAM Buffer Write Pointer */ -/* RB_RP 32 bit RAM Buffer Read Pointer */ -/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */ -/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */ -/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */ -/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */ -/* RB_PC 32 bit RAM Buffer Packet Counter */ -/* RB_LEV 32 bit RAM Buffer Level Register */ - /* Bit 31..19: reserved */ -#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */ - -/* RB_TST2 8 bit RAM Buffer Test Register 2 */ - /* Bit 7.. 4: reserved */ -#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */ -#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */ -#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */ -#define RB_PC_INC BIT_0S /* Packet Counter Increm */ - -/* RB_TST1 8 bit RAM Buffer Test Register 1 */ - /* Bit 7: reserved */ -#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */ -#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */ -#define RB_WP_INC BIT_4S /* Write Pointer Increm */ - /* Bit 3: reserved */ -#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */ -#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */ -#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */ - -/* RB_CTRL 8 bit RAM Buffer Control Register */ - /* Bit 7.. 6: reserved */ -#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */ -#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */ -#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */ -#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */ -#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */ -#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */ - - -/* Receive and Transmit MAC FIFO Registers (GENESIS only) */ - -/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ -/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ -/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ -/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ -/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ -/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ -/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ -/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ -/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ -/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ -/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */ - /* Bit 31.. 6: reserved */ -#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */ - -/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */ - /* Bit 15..14: reserved */ -#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */ -#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */ -#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */ -#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */ -#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */ -#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */ -#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */ -#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */ -#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */ -#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */ -#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */ -#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */ -#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */ -#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */ - -#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT - -/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */ -#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */ - /* Bit 14: reserved */ -#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */ -#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */ -/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */ -/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */ -/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */ -/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */ -#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */ -#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */ -/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */ -/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */ -#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */ -#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */ -#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */ -#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */ - -#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH) - -/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */ -/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */ - /* Bit 7: reserved */ -#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */ -#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */ -#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */ -#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */ -#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */ -#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */ -#define MFF_PC_INC BIT_0S /* Packet Counter Increment */ - -/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */ -/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */ - /* Bit 7: reserved */ -#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */ -#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */ -#define MFF_WP_INC BIT_4S /* Write Pointer Increm */ - /* Bit 3: reserved */ -#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */ -#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */ -#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */ - -/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */ -/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */ - /* Bit 7..4: reserved */ -#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */ -#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */ -#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */ -#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */ - - -/* Link LED Counter Registers (GENESIS only) */ - -/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */ -/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */ -/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */ - /* Bit 7.. 3: reserved */ -#define LED_START BIT_2S /* Start Timer */ -#define LED_STOP BIT_1S /* Stop Timer */ -#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */ -#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */ - -/* RX_LED_TST 8 bit Receive LED Cnt Test Register */ -/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */ -/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */ - /* Bit 7.. 3: reserved */ -#define LED_T_ON BIT_2S /* LED Counter Test mode On */ -#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */ -#define LED_T_STEP BIT_0S /* LED Counter Step */ - -/* LNK_LED_REG 8 bit Link LED Register */ - /* Bit 7.. 6: reserved */ -#define LED_BLK_ON BIT_5S /* Link LED Blinking On */ -#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */ -#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */ -#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */ -#define LED_ON BIT_1S /* switch LED on */ -#define LED_OFF BIT_0S /* switch LED off */ - -/* Receive and Transmit GMAC FIFO Registers (YUKON only) */ - -/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */ -/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */ -/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */ -/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */ -/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */ -/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */ -/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ -/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ -/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */ -/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */ -/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */ -/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */ -/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */ -/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */ - -/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */ - /* Bits 31..15: reserved */ -#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */ -#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ -#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */ - /* Bit 11: reserved */ -#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */ -#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ -#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */ -#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */ -#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */ -#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */ -#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */ -#define GMF_OPER_ON BIT_3 /* Operational Mode On */ -#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */ -#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */ -#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */ - -/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ - /* Bits 31..19: reserved */ -#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */ -#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */ -#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */ - /* Bits 15..7: same as for RX_GMF_CTRL_T */ -#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */ -#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */ -#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */ - /* Bits 3..0: same as for RX_GMF_CTRL_T */ - -#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON) -#define GMF_TX_CTRL_DEF GMF_OPER_ON - -#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */ - -/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ - /* Bit 7.. 3: reserved */ -#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ -#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ -#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */ - -/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ - /* Bits 31.. 8: reserved */ -#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */ -#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */ -#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */ -#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */ -#define GMC_PAUSE_ON BIT_3 /* Pause On */ -#define GMC_PAUSE_OFF BIT_2 /* Pause Off */ -#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */ -#define GMC_RST_SET BIT_0 /* Set GMAC Reset */ - -/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */ - /* Bits 31..29: reserved */ -#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */ -#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */ -#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */ -#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */ -#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */ -#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */ -#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */ -#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */ -#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */ -#define GPC_ANEG_0 BIT_19 /* ANEG[0] */ -#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */ -#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */ -#define GPC_ANEG_3 BIT_16 /* ANEG[3] */ -#define GPC_ANEG_2 BIT_15 /* ANEG[2] */ -#define GPC_ANEG_1 BIT_14 /* ANEG[1] */ -#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */ -#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */ -#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */ -#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */ -#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */ -#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */ - /* Bits 7..2: reserved */ -#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */ -#define GPC_RST_SET BIT_0 /* Set GPHY Reset */ - -#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \ - GPC_HWCFG_M_1 | GPC_HWCFG_M_0) - -#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \ - GPC_HWCFG_M_1 | GPC_HWCFG_M_0) - -#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \ - GPC_ANEG_1 | GPC_ANEG_0) - -/* forced speed and duplex mode (don't mix with other ANEG bits) */ -#define GPC_FRC10MBIT_HALF 0 -#define GPC_FRC10MBIT_FULL GPC_ANEG_0 -#define GPC_FRC100MBIT_HALF GPC_ANEG_1 -#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1) - -/* auto-negotiation with limited advertised speeds */ -/* mix only with master/slave settings (for copper) */ -#define GPC_ADV_1000_HALF GPC_ANEG_2 -#define GPC_ADV_1000_FULL GPC_ANEG_3 -#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3) - -/* master/slave settings */ -/* only for copper with 1000 Mbps */ -#define GPC_FORCE_MASTER 0 -#define GPC_FORCE_SLAVE GPC_ANEG_0 -#define GPC_PREF_MASTER GPC_ANEG_1 -#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0) - -/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */ -/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */ -#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */ -#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */ -#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */ -#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */ -#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */ -#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */ - -#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ - GM_IS_TX_FF_UR) - -/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ - /* Bits 15.. 2: reserved */ -#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */ -#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */ - - -/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ -#define WOL_CTL_LINK_CHG_OCC BIT_15S -#define WOL_CTL_MAGIC_PKT_OCC BIT_14S -#define WOL_CTL_PATTERN_OCC BIT_13S - -#define WOL_CTL_CLEAR_RESULT BIT_12S - -#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S -#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S -#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S -#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S -#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S -#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S - -#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S -#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S -#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S -#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S -#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S -#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S - -#define WOL_CTL_DEFAULT \ - (WOL_CTL_DIS_PME_ON_LINK_CHG | \ - WOL_CTL_DIS_PME_ON_PATTERN | \ - WOL_CTL_DIS_PME_ON_MAGIC_PKT | \ - WOL_CTL_DIS_LINK_CHG_UNIT | \ - WOL_CTL_DIS_PATTERN_UNIT | \ - WOL_CTL_DIS_MAGIC_PKT_UNIT) - -/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ -#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x)) - -#define SK_NUM_WOL_PATTERN 7 -#define SK_PATTERN_PER_WORD 4 -#define SK_BITMASK_PATTERN 7 -#define SK_POW_PATTERN_LENGTH 128 - -#define WOL_LENGTH_MSK 0x7f -#define WOL_LENGTH_SHIFT 8 - - -/* Receive and Transmit Descriptors ******************************************/ - -/* Transmit Descriptor struct */ -typedef struct s_HwTxd { - SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */ - SK_U32 TxNext; /* Physical Address Pointer to the next TxD */ - SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */ - SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */ - SK_U32 TxStat; /* Transmit Frame Status Word */ -#ifndef SK_USE_REV_DESC - SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */ - SK_U16 TxRes1; /* 16 bit reserved field */ - SK_U16 TxTcpWp; /* TCP Checksum Write Position */ - SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ -#else /* SK_USE_REV_DESC */ - SK_U16 TxRes1; /* 16 bit reserved field */ - SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */ - SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ - SK_U16 TxTcpWp; /* TCP Checksum Write Position */ -#endif /* SK_USE_REV_DESC */ - SK_U32 TxRes2; /* 32 bit reserved field */ -} SK_HWTXD; - -/* Receive Descriptor struct */ -typedef struct s_HwRxd { - SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */ - SK_U32 RxNext; /* Physical Address Pointer to the next RxD */ - SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */ - SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */ - SK_U32 RxStat; /* Receive Frame Status Word */ - SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */ -#ifndef SK_USE_REV_DESC - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ - SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ - SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ -#else /* SK_USE_REV_DESC */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ - SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ - SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ -#endif /* SK_USE_REV_DESC */ -} SK_HWRXD; - -/* - * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2) - * should set the define SK_USE_REV_DESC. - * Structures are 'normaly' not endianess dependent. But in - * this case the SK_U16 fields are bound to bit positions inside the - * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord. - * The bit positions inside a DWord are of course endianess dependent and - * swaps if the DWord is swapped by the hardware. - */ - - -/* Descriptor Bit Definition */ -/* TxCtrl Transmit Buffer Control Field */ -/* RxCtrl Receive Buffer Control Field */ -#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */ -#define BMU_STF BIT_30 /* Start of Frame */ -#define BMU_EOF BIT_29 /* End of Frame */ -#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */ -#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */ -/* TxCtrl specific bits */ -#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */ -#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */ -#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */ -/* RxCtrl specific bits */ -#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */ -#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */ -#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */ - /* Bit 23..16: BMU Check Opcodes */ -#define BMU_CHECK (0x55L<<16) /* Default BMU check */ -#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */ -#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */ -#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */ - -/* TxStat Transmit Frame Status Word */ -/* RxStat Receive Frame Status Word */ -/* - *Note: TxStat is reserved for ASIC loopback mode only - * - * The Bits of the Status words are defined in xmac_ii.h - * (see XMR_FS bits) - */ - -/* macros ********************************************************************/ - -/* Receive and Transmit Queues */ -#define Q_R1 0x0000 /* Receive Queue 1 */ -#define Q_R2 0x0080 /* Receive Queue 2 */ -#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */ -#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */ -#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */ -#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */ - -/* - * Macro Q_ADDR() - * - * Use this macro to access the Receive and Transmit Queue Registers. - * - * para: - * Queue Queue to access. - * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 - * Offs Queue register offset. - * Values: Q_D, Q_DA_L ... Q_T2, Q_T3 - * - * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal) - */ -#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs)) - -/* - * Macro RB_ADDR() - * - * Use this macro to access the RAM Buffer Registers. - * - * para: - * Queue Queue to access. - * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2 - * Offs Queue register offset. - * Values: RB_START, RB_END ... RB_LEV, RB_CTRL - * - * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal) - */ -#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs)) - - -/* MAC Related Registers */ -#define MAC_1 0 /* belongs to the port near the slot */ -#define MAC_2 1 /* belongs to the port far away from the slot */ - -/* - * Macro MR_ADDR() - * - * Use this macro to access a MAC Related Registers inside the ASIC. - * - * para: - * Mac MAC to access. - * Values: MAC_1, MAC_2 - * Offs MAC register offset. - * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG, - * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST - * - * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal) - */ -#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs)) - -#ifdef SK_LITTLE_ENDIAN -#define XM_WORD_LO 0 -#define XM_WORD_HI 1 -#else /* !SK_LITTLE_ENDIAN */ -#define XM_WORD_LO 1 -#define XM_WORD_HI 0 -#endif /* !SK_LITTLE_ENDIAN */ - - -/* - * macros to access the XMAC (GENESIS only) - * - * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD) - * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD) - * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT) - * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT) - * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK) - * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK) - * XM_INHASH(), to read the XM_HSM_CHK register - * XM_OUTHASH() to write the XM_HSM_CHK register - * - * para: - * Mac XMAC to access values: MAC_1 or MAC_2 - * IoC I/O context needed for SK I/O macros - * Reg XMAC Register to read or write - * (p)Val Value or pointer to the value which should be read or written - * - * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value); - */ - -#define XMA(Mac, Reg) \ - ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1)) - -#define XM_IN16(IoC, Mac, Reg, pVal) \ - SK_IN16((IoC), XMA((Mac), (Reg)), (pVal)) - -#define XM_OUT16(IoC, Mac, Reg, Val) \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (Val)) - -#define XM_IN32(IoC, Mac, Reg, pVal) { \ - SK_IN16((IoC), XMA((Mac), (Reg)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ -} - -#define XM_OUT32(IoC, Mac, Reg, Val) { \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\ -} - -/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */ - -#define XM_INADDR(IoC, Mac, Reg, pVal) { \ - SK_U16 Word; \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ - SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ - pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ - pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ - pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ -} - -#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \ - SK_U8 SK_FAR *pByte; \ - pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ - (((SK_U16)(pByte[0]) & 0x00ff) | \ - (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \ - (((SK_U16)(pByte[2]) & 0x00ff) | \ - (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \ - (((SK_U16)(pByte[4]) & 0x00ff) | \ - (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ -} - -#define XM_INHASH(IoC, Mac, Reg, pVal) { \ - SK_U16 Word; \ - SK_U8 SK_FAR *pByte; \ - pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ - SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ - pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ - pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ - pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \ - pByte[6] = (SK_U8)(Word & 0x00ff); \ - pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ -} - -#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \ - SK_U8 SK_FAR *pByte; \ - pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ - (((SK_U16)(pByte[0]) & 0x00ff)| \ - (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \ - (((SK_U16)(pByte[2]) & 0x00ff)| \ - (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \ - (((SK_U16)(pByte[4]) & 0x00ff)| \ - (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \ - (((SK_U16)(pByte[6]) & 0x00ff)| \ - (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ -} - -/* - * macros to access the GMAC (YUKON only) - * - * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT) - * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL) - * GM_IN32(), to read a 32 bit register (e.g. GM_) - * GM_OUT32(), to write a 32 bit register (e.g. GM_) - * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L) - * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L) - * GM_INHASH(), to read the GM_MC_ADDR_H1 register - * GM_OUTHASH() to write the GM_MC_ADDR_H1 register - * - * para: - * Mac GMAC to access values: MAC_1 or MAC_2 - * IoC I/O context needed for SK I/O macros - * Reg GMAC Register to read or write - * (p)Val Value or pointer to the value which should be read or written - * - * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value); - */ - -#define GMA(Mac, Reg) \ - ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg)) - -#define GM_IN16(IoC, Mac, Reg, pVal) \ - SK_IN16((IoC), GMA((Mac), (Reg)), (pVal)) - -#define GM_OUT16(IoC, Mac, Reg, Val) \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (Val)) - -#define GM_IN32(IoC, Mac, Reg, pVal) { \ - SK_IN16((IoC), GMA((Mac), (Reg)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ -} - -#define GM_OUT32(IoC, Mac, Reg, Val) { \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\ -} - -#define GM_INADDR(IoC, Mac, Reg, pVal) { \ - SK_U16 Word; \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ - SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ - pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ - pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ - pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ -} - -#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \ - SK_U8 SK_FAR *pByte; \ - pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ - (((SK_U16)(pByte[0]) & 0x00ff) | \ - (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ - (((SK_U16)(pByte[2]) & 0x00ff) | \ - (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ - (((SK_U16)(pByte[4]) & 0x00ff) | \ - (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ -} - -#define GM_INHASH(IoC, Mac, Reg, pVal) { \ - SK_U16 Word; \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ - SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ - pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ - pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ - pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \ - pByte[6] = (SK_U8)(Word & 0x00ff); \ - pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ -} - -#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \ - SK_U8 *pByte; \ - pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ - (((SK_U16)(pByte[0]) & 0x00ff)| \ - (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ - (((SK_U16)(pByte[2]) & 0x00ff)| \ - (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ - (((SK_U16)(pByte[4]) & 0x00ff)| \ - (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \ - (((SK_U16)(pByte[6]) & 0x00ff)| \ - (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ -} - -/* - * Different MAC Types - */ -#define SK_MAC_XMAC 0 /* Xaqti XMAC II */ -#define SK_MAC_GMAC 1 /* Marvell GMAC */ - -/* - * Different PHY Types - */ -#define SK_PHY_XMAC 0 /* integrated in XMAC II */ -#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */ -#define SK_PHY_LONE 2 /* Level One LXT1000 */ -#define SK_PHY_NAT 3 /* National DP83891 */ -#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */ -#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */ - -/* - * PHY addresses (bits 12..8 of PHY address reg) - */ -#define PHY_ADDR_XMAC (0<<8) -#define PHY_ADDR_BCOM (1<<8) -#define PHY_ADDR_LONE (3<<8) -#define PHY_ADDR_NAT (0<<8) - -/* GPHY address (bits 15..11 of SMI control reg) */ -#define PHY_ADDR_MARV 0 - -/* - * macros to access the PHY - * - * PHY_READ() read a 16 bit value from the PHY - * PHY_WRITE() write a 16 bit value to the PHY - * - * para: - * IoC I/O context needed for SK I/O macros - * pPort Pointer to port struct for PhyAddr - * Mac XMAC to access values: MAC_1 or MAC_2 - * PhyReg PHY Register to read or write - * (p)Val Value or pointer to the value which should be read or - * written. - * - * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value); - * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never - * comes back. This is checked in DEBUG mode. - */ -#ifndef DEBUG -#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \ - SK_U16 Mmu; \ - \ - XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ - XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ - XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ - } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ - XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - } \ -} -#else -#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \ - SK_U16 Mmu; \ - int __i = 0; \ - \ - XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ - XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ - XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ - __i++; \ - if (__i > 100000) { \ - SK_DBG_PRINTF("*****************************\n"); \ - SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \ - SK_DBG_PRINTF("*****************************\n"); \ - break; \ - } \ - } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ - XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - } \ -} -#endif /* DEBUG */ - -#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \ - SK_U16 Mmu; \ - \ - if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ - XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ - } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \ - } \ - XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ - XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \ - if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ - XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ - } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \ - } \ -} - -/* - * Macro PCI_C() - * - * Use this macro to access PCI config register from the I/O space. - * - * para: - * Addr PCI configuration register to access. - * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG, - * - * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal); - */ -#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */ - -/* - * Macro SK_HW_ADDR(Base, Addr) - * - * Calculates the effective HW address - * - * para: - * Base I/O or memory base address - * Addr Address offset - * - * usage: May be used in SK_INxx and SK_OUTxx macros - * #define SK_IN8(pAC, Addr, pVal) ...\ - * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr))) - */ -#ifdef SK_MEM_MAPPED_IO -#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr)) -#else /* SK_MEM_MAPPED_IO */ -#define SK_HW_ADDR(Base, Addr) \ - ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0))) -#endif /* SK_MEM_MAPPED_IO */ - -#define SZ_LONG (sizeof(SK_U32)) - -/* - * Macro SK_HWAC_LINK_LED() - * - * Use this macro to set the link LED mode. - * para: - * pAC Pointer to adapter context struct - * IoC I/O context needed for SK I/O macros - * Port Port number - * Mode Mode to set for this LED - */ -#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \ - SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode); - - -/* typedefs *******************************************************************/ - - -/* function prototypes ********************************************************/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_SKGEHW_H */ diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h deleted file mode 100644 index e6b0016a695c..000000000000 --- a/drivers/net/sk98lin/h/skgehwt.h +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** - * - * Name: skhwt.h - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.7 $ - * Date: $Date: 2003/09/16 12:55:08 $ - * Purpose: Defines for the hardware timer functions - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKGEHWT.H contains all defines and types for the timer functions - */ - -#ifndef _SKGEHWT_H_ -#define _SKGEHWT_H_ - -/* - * SK Hardware Timer - * - needed wherever the HWT module is used - * - use in Adapters context name pAC->Hwt - */ -typedef struct s_Hwt { - SK_U32 TStart; /* HWT start */ - SK_U32 TStop; /* HWT stop */ - int TActive; /* HWT: flag : active/inactive */ -} SK_HWT; - -extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc); -extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time); -extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc); -extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc); -extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc); -#endif /* _SKGEHWT_H_ */ diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h deleted file mode 100644 index d9b6f6d8dfe2..000000000000 --- a/drivers/net/sk98lin/h/skgei2c.h +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * - * Name: skgei2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Version: $Revision: 1.25 $ - * Date: $Date: 2003/10/20 09:06:05 $ - * Purpose: Special defines for TWSI - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling - */ - -#ifndef _INC_SKGEI2C_H_ -#define _INC_SKGEI2C_H_ - -/* - * Macros to access the B2_I2C_CTRL - */ -#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \ - SK_OUT32(IoC, B2_I2C_CTRL,\ - (flag ? 0x80000000UL : 0x0L) | \ - (((SK_U32)reg << 16) & I2C_ADDR) | \ - (((SK_U32)dev << 9) & I2C_DEV_SEL) | \ - (dev_size & I2C_DEV_SIZE) | \ - ((burst << 4) & I2C_BURST_LEN)) - -#define SK_I2C_STOP(IoC) { \ - SK_U32 I2cCtrl; \ - SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \ - SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \ -} - -#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl) - -/* - * Macros to access the TWSI SW Registers - */ -#define SK_I2C_SET_BIT(IoC, SetBits) { \ - SK_U8 OrgBits; \ - SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \ -} - -#define SK_I2C_CLR_BIT(IoC, ClrBits) { \ - SK_U8 OrgBits; \ - SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \ -} - -#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw) - -/* - * define the possible sensor states - */ -#define SK_SEN_IDLE 0 /* Idle: sensor not read */ -#define SK_SEN_VALUE 1 /* Value Read cycle */ -#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */ - -/* - * Conversion factor to convert read Voltage sensor to milli Volt - * Conversion factor to convert read Temperature sensor to 10th degree Celsius - */ -#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ -#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ -#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */ - -/* - * formula: counter = (22500*60)/(rpm * divisor * pulses/2) - * assuming: 6500rpm, 4 pulses, divisor 1 - */ -#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) - -/* - * Define sensor management data - * Maximum is reached on Genesis copper dual port and Yukon-64 - * Board specific maximum is in pAC->I2c.MaxSens - */ -#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */ -#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ - -/* - * To watch the state machine (SM) use the timer in two ways - * instead of one as hitherto - */ -#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */ -#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ - -/* - * Defines for the individual thresholds - */ - -/* Temperature sensor */ -#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ -#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ -#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ -#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ - -/* VCC which should be 5 V */ -#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ -#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ -#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ -#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ - -/* - * VIO may be 5 V or 3.3 V. Initialization takes two parts: - * 1. Initialize lowest lower limit and highest higher limit. - * 2. After the first value is read correct the upper or the lower limit to - * the appropriate C constant. - * - * Warning limits are +-5% of the exepected voltage. - * Error limits are +-10% of the expected voltage. - */ - -/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ - -#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */ -#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */ - /* 5000 mVolt */ -#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */ - -#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */ - -/* correction values for the second pass */ -#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ -#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ - /* 3300 mVolt */ -#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ - -/* - * VDD voltage - */ -#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ -#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ -#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ -#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ - -/* - * PHY PLL 3V3 voltage - */ -#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */ -#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */ -#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */ -#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */ - -/* - * VAUX (YUKON only) - */ -#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */ -#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ -#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ -#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ - -/* - * PHY 2V5 voltage - */ -#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */ -#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */ -#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */ -#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */ - -/* - * ASIC Core 1V5 voltage (YUKON only) - */ -#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ -#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */ -#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */ -#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */ - -/* - * FAN 1 speed - */ -/* assuming: 6500rpm +-15%, 4 pulses, - * warning at: 80 % - * error at: 70 % - * no upper limit - */ -#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ -#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ -#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ -#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ - -/* - * Some Voltages need dynamic thresholds - */ -#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */ -#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */ -#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */ - -extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); -#endif /* n_INC_SKGEI2C_H */ diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h deleted file mode 100644 index 143e635ec24d..000000000000 --- a/drivers/net/sk98lin/h/skgeinit.h +++ /dev/null @@ -1,797 +0,0 @@ -/****************************************************************************** - * - * Name: skgeinit.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.83 $ - * Date: $Date: 2003/09/16 14:07:37 $ - * Purpose: Structures and prototypes for the GE Init Module - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_SKGEINIT_H_ -#define __INC_SKGEINIT_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* defines ********************************************************************/ - -#define SK_TEST_VAL 0x11335577UL - -/* modifying Link LED behaviour (used with SkGeLinkLED()) */ -#define SK_LNK_OFF LED_OFF -#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) -#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON) -#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON) -#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF) - -/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */ -#define SK_LED_OFF LED_OFF -#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF) -#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF) - -/* addressing LED Registers in SkGeXmitLED() */ -#define XMIT_LED_INI 0 -#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI) -#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI) -#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI) - -/* parameter 'Mode' when calling SkGeXmitLED() */ -#define SK_LED_DIS 0 -#define SK_LED_ENA 1 -#define SK_LED_TST 2 - -/* Counter and Timer constants, for a host clock of 62.5 MHz */ -#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */ -#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */ - -#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */ - -#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */ - /* 215 ms at 78.12 MHz */ - -#define SK_FACT_62 100 /* is given in percent */ -#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ -#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */ - -/* Timeout values */ -#define SK_MAC_TO_53 72 /* MAC arbiter timeout */ -#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */ -#define SK_PKT_TO_MAX 0xffff /* Maximum value */ -#define SK_RI_TO_53 36 /* RAM interface timeout */ - -#define SK_PHY_ACC_TO 600000 /* PHY access timeout */ - -/* RAM Buffer High Pause Threshold values */ -#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */ -#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */ -#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */ - -#ifndef SK_BMU_RX_WM -#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ -#endif -#ifndef SK_BMU_TX_WM -#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ -#endif - -/* XMAC II Rx High Watermark */ -#define SK_XM_RX_HI_WM 0x05aa /* 1450 */ - -/* XMAC II Tx Threshold */ -#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */ -#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */ -#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */ -#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */ - -/* values for GIPortUsage */ -#define SK_RED_LINK 1 /* redundant link usage */ -#define SK_MUL_LINK 2 /* multiple link usage */ -#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */ - -/* Minimum RAM Buffer Rx Queue Size */ -#define SK_MIN_RXQ_SIZE 16 /* 16 kB */ - -/* Minimum RAM Buffer Tx Queue Size */ -#define SK_MIN_TXQ_SIZE 16 /* 16 kB */ - -/* Queue Size units */ -#define QZ_UNITS 0x7 -#define QZ_STEP 8 - -/* Percentage of queue size from whole memory */ -/* 80 % for receive */ -#define RAM_QUOTA_RX 80L -/* 0% for sync transfer */ -#define RAM_QUOTA_SYNC 0L -/* the rest (20%) is taken for async transfer */ - -/* Get the rounded queue size in Bytes in 8k steps */ -#define ROUND_QUEUE_SIZE(SizeInBytes) \ - ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \ - ~(QZ_STEP-1)) - -/* Get the rounded queue size in KBytes in 8k steps */ -#define ROUND_QUEUE_SIZE_KB(Kilobytes) \ - ROUND_QUEUE_SIZE((Kilobytes) * 1024L) - -/* Types of RAM Buffer Queues */ -#define SK_RX_SRAM_Q 1 /* small receive queue */ -#define SK_RX_BRAM_Q 2 /* big receive queue */ -#define SK_TX_RAM_Q 3 /* small or big transmit queue */ - -/* parameter 'Dir' when calling SkGeStopPort() */ -#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */ -#define SK_STOP_RX 2 /* Stops the receive path */ -#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */ - -/* parameter 'RstMode' when calling SkGeStopPort() */ -#define SK_SOFT_RST 1 /* perform a software reset */ -#define SK_HARD_RST 2 /* perform a hardware reset */ - -/* Init Levels */ -#define SK_INIT_DATA 0 /* Init level 0: init data structures */ -#define SK_INIT_IO 1 /* Init level 1: init with IOs */ -#define SK_INIT_RUN 2 /* Init level 2: init for run time */ - -/* Link Mode Parameter */ -#define SK_LMODE_HALF 1 /* Half Duplex Mode */ -#define SK_LMODE_FULL 2 /* Full Duplex Mode */ -#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */ -#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */ -#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */ -#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */ -#define SK_LMODE_INDETERMINATED 7 /* indeterminated */ - -/* Auto-negotiation timeout in 100ms granularity */ -#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */ - -/* Auto-negotiation error codes */ -#define SK_AND_OK 0 /* no error */ -#define SK_AND_OTHER 1 /* other error than below */ -#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */ - - -/* Link Speed Capabilities */ -#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */ -#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */ -#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */ -#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */ -#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */ - -/* Link Speed Parameter */ -#define SK_LSPEED_AUTO 1 /* Automatic resolution */ -#define SK_LSPEED_10MBPS 2 /* 10 Mbps */ -#define SK_LSPEED_100MBPS 3 /* 100 Mbps */ -#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */ -#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */ - -/* Link Speed Current State */ -#define SK_LSPEED_STAT_UNKNOWN 1 -#define SK_LSPEED_STAT_10MBPS 2 -#define SK_LSPEED_STAT_100MBPS 3 -#define SK_LSPEED_STAT_1000MBPS 4 -#define SK_LSPEED_STAT_INDETERMINATED 5 - - -/* Link Capability Parameter */ -#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */ -#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */ -#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */ -#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */ -#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */ - -/* Link Mode Current State */ -#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ -#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */ -#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */ -#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */ -#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */ -#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */ - -/* Flow Control Mode Parameter (and capabilities) */ -#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */ -#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */ -#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */ -#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or - * just the remote station may send PAUSE - */ -#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */ - -/* Flow Control Status Parameter */ -#define SK_FLOW_STAT_NONE 1 /* No Flow Control */ -#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */ -#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */ -#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */ -#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */ - -/* Master/Slave Mode Capabilities */ -#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */ -#define SK_MS_CAP_MASTER (1<<1) /* This station is master */ -#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */ -#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */ - -/* Set Master/Slave Mode Parameter (and capabilities) */ -#define SK_MS_MODE_AUTO 1 /* Automatic resolution */ -#define SK_MS_MODE_MASTER 2 /* This station is master */ -#define SK_MS_MODE_SLAVE 3 /* This station is slave */ -#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */ - -/* Master/Slave Status Parameter */ -#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */ -#define SK_MS_STAT_MASTER 2 /* This station is master */ -#define SK_MS_STAT_SLAVE 3 /* This station is slave */ -#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */ -#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */ - -/* parameter 'Mode' when calling SkXmSetRxCmd() */ -#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */ -#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */ -#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */ -#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */ -#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */ -#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */ -#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */ -#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */ -#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */ -#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */ - -/* parameter 'Para' when calling SkMacSetRxTxEn() */ -#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */ -#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */ -#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */ -#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */ -#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */ -#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */ - -/* States of PState */ -#define SK_PRT_RESET 0 /* the port is reset */ -#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */ -#define SK_PRT_INIT 2 /* the port is initialized */ -#define SK_PRT_RUN 3 /* the port has an active link */ - -/* PHY power down modes */ -#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */ -#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */ -#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */ -#define PHY_PM_ENERGY_DETECT 3 /* energy detect */ -#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */ - -/* Default receive frame limit for Workaround of XMAC Errata */ -#define SK_DEF_RX_WA_LIM SK_CONSTU64(100) - -/* values for GILedBlinkCtrl (LED Blink Control) */ -#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */ -#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */ -#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */ - -/* Link Partner Status */ -#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ -#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */ -#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */ - -/* Maximum Restarts before restart is ignored (3Com WA) */ -#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */ - -/* Max. Auto-neg. timeouts before link detection in sense mode is reset */ -#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */ - -/* structures *****************************************************************/ - -/* - * MAC specific functions - */ -typedef struct s_GeMacFunc { - int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); - int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 StatAddr, SK_U32 SK_FAR *pVal); - int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); - int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 IStatus, SK_U64 SK_FAR *pVal); -} SK_GEMACFUNC; - -/* - * Port Structure - */ -typedef struct s_GePort { -#ifndef SK_DIAG - SK_TIMER PWaTimer; /* Workaround Timer */ - SK_TIMER HalfDupChkTimer; -#endif /* SK_DIAG */ - SK_U32 PPrevShorts; /* Previous Short Counter checking */ - SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */ - SK_U64 PPrevRx; /* Previous RxOk Counter checking */ - SK_U64 PRxLim; /* Previous RxOk Counter checking */ - SK_U64 LastOctets; /* For half duplex hang check */ - int PLinkResCt; /* Link Restart Counter */ - int PAutoNegTimeOut;/* Auto-negotiation timeout current value */ - int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */ - int PRxQSize; /* Port Rx Queue Size in kB */ - int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */ - int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */ - SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */ - SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */ - SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */ - SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */ - SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */ - SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */ - SK_U32 PRxOverCnt; /* Receive Overflow Counter */ - int PRxQOff; /* Rx Queue Address Offset */ - int PXsQOff; /* Synchronous Tx Queue Address Offset */ - int PXaQOff; /* Asynchronous Tx Queue Address Offset */ - int PhyType; /* PHY used on this port */ - int PState; /* Port status (reset, stop, init, run) */ - SK_U16 PhyId1; /* PHY Id1 on this port */ - SK_U16 PhyAddr; /* MDIO/MDC PHY address */ - SK_U16 PIsave; /* Saved Interrupt status word */ - SK_U16 PSsave; /* Saved PHY status word */ - SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */ - SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */ - SK_BOOL PLinkBroken; /* Is Link broken ? */ - SK_BOOL PCheckPar; /* Do we check for parity errors ? */ - SK_BOOL HalfDupTimerActive; - SK_U8 PLinkCap; /* Link Capabilities */ - SK_U8 PLinkModeConf; /* Link Mode configured */ - SK_U8 PLinkMode; /* Link Mode currently used */ - SK_U8 PLinkModeStatus;/* Link Mode Status */ - SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */ - SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */ - SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */ - SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */ - SK_U8 PFlowCtrlMode; /* Flow Control Mode */ - SK_U8 PFlowCtrlStatus;/* Flow Control Status */ - SK_U8 PMSCap; /* Master/Slave Capabilities */ - SK_U8 PMSMode; /* Master/Slave Mode */ - SK_U8 PMSStatus; /* Master/Slave Status */ - SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */ - SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */ - SK_U8 PCableLen; /* Cable Length */ - SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */ - SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */ - SK_U8 PPhyPowerState; /* PHY current power state */ - int PMacColThres; /* MAC Collision Threshold */ - int PMacJamLen; /* MAC Jam length */ - int PMacJamIpgVal; /* MAC Jam IPG */ - int PMacJamIpgData; /* MAC IPG Jam to Data */ - int PMacIpgData; /* MAC Data IPG */ - SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */ -} SK_GEPORT; - -/* - * Gigabit Ethernet Initialization Struct - * (has to be included in the adapter context) - */ -typedef struct s_GeInit { - int GIChipId; /* Chip Identification Number */ - int GIChipRev; /* Chip Revision Number */ - SK_U8 GIPciHwRev; /* PCI HW Revision Number */ - SK_BOOL GIGenesis; /* Genesis adapter ? */ - SK_BOOL GIYukon; /* YUKON-A1/Bx chip */ - SK_BOOL GIYukonLite; /* YUKON-Lite chip */ - SK_BOOL GICopperType; /* Copper Type adapter ? */ - SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */ - SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */ - SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */ - SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */ - SK_U16 GILedBlinkCtrl; /* LED Blink Control */ - int GIMacsFound; /* Number of MACs found on this adapter */ - int GIMacType; /* MAC Type used on this adapter */ - int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */ - int GIPortUsage; /* Driver Port Usage */ - int GILevel; /* Initialization Level completed */ - int GIRamSize; /* The RAM size of the adapter in kB */ - int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */ - SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */ - SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */ - SK_U32 GIValIrqMask; /* Value for Interrupt Mask */ - SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */ - SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */ - SK_GEMACFUNC GIFunc; /* MAC depedent functions */ -} SK_GEINIT; - -/* - * Error numbers and messages for skxmac2.c and skgeinit.c - */ -#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT) -#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters" -#define SKERR_HWI_E002 (SKERR_HWI_E001+1) -#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing" -#define SKERR_HWI_E003 (SKERR_HWI_E002+1) -#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level" -#define SKERR_HWI_E004 (SKERR_HWI_E003+1) -#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured" -#define SKERR_HWI_E005 (SKERR_HWI_E004+1) -#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports" -#define SKERR_HWI_E006 (SKERR_HWI_E005+1) -#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state" -#define SKERR_HWI_E007 (SKERR_HWI_E006+1) -#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode" -#define SKERR_HWI_E008 (SKERR_HWI_E007+1) -#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode" -#define SKERR_HWI_E009 (SKERR_HWI_E008+1) -#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero" -#define SKERR_HWI_E010 (SKERR_HWI_E009+1) -#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters" -#define SKERR_HWI_E011 (SKERR_HWI_E010+1) -#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small" -#define SKERR_HWI_E012 (SKERR_HWI_E011+1) -#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified" -#define SKERR_HWI_E013 (SKERR_HWI_E012+1) -#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue" -#define SKERR_HWI_E014 (SKERR_HWI_E013+1) -#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified" -#define SKERR_HWI_E015 (SKERR_HWI_E014+1) -#define SKERR_HWI_E015MSG "Illegal Link mode parameter" -#define SKERR_HWI_E016 (SKERR_HWI_E015+1) -#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter" -#define SKERR_HWI_E017 (SKERR_HWI_E016+1) -#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal" -#define SKERR_HWI_E018 (SKERR_HWI_E017+1) -#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)" -#define SKERR_HWI_E019 (SKERR_HWI_E018+1) -#define SKERR_HWI_E019MSG "Illegal Speed parameter" -#define SKERR_HWI_E020 (SKERR_HWI_E019+1) -#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter" -#define SKERR_HWI_E021 (SKERR_HWI_E020+1) -#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter" -#define SKERR_HWI_E022 (SKERR_HWI_E021+1) -#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address" -#define SKERR_HWI_E023 (SKERR_HWI_E022+1) -#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small" -#define SKERR_HWI_E024 (SKERR_HWI_E023+1) -#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)" -#define SKERR_HWI_E025 (SKERR_HWI_E024+1) -#define SKERR_HWI_E025MSG "" - -/* function prototypes ********************************************************/ - -#ifndef SK_KR_PROTO - -/* - * public functions in skgeinit.c - */ -extern void SkGePollTxD( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL PollTxD); - -extern void SkGeYellowLED( - SK_AC *pAC, - SK_IOC IoC, - int State); - -extern int SkGeCfgSync( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_U32 IntTime, - SK_U32 LimCount, - int SyncMode); - -extern void SkGeLoadLnkSyncCnt( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_U32 CntVal); - -extern void SkGeStopPort( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Dir, - int RstMode); - -extern int SkGeInit( - SK_AC *pAC, - SK_IOC IoC, - int Level); - -extern void SkGeDeInit( - SK_AC *pAC, - SK_IOC IoC); - -extern int SkGeInitPort( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkGeXmitLED( - SK_AC *pAC, - SK_IOC IoC, - int Led, - int Mode); - -extern int SkGeInitAssignRamToQueues( - SK_AC *pAC, - int ActivePort, - SK_BOOL DualNet); - -/* - * public functions in skxmac2.c - */ -extern void SkMacRxTxDisable( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacSoftRst( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacHardRst( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkXmInitMac( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkGmInitMac( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacInitPhy( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL DoLoop); - -extern void SkMacIrqDisable( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacFlushTxFifo( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacIrq( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern int SkMacAutoNegDone( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacAutoNegLipaPhy( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_U16 IStatus); - -extern int SkMacRxTxEnable( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkMacPromiscMode( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL Enable); - -extern void SkMacHashing( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL Enable); - -extern void SkXmPhyRead( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 SK_FAR *pVal); - -extern void SkXmPhyWrite( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 Val); - -extern void SkGmPhyRead( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 SK_FAR *pVal); - -extern void SkGmPhyWrite( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 Val); - -extern void SkXmClrExactAddr( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int StartNum, - int StopNum); - -extern void SkXmAutoNegLipaXmac( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_U16 IStatus); - -extern int SkXmUpdateStats( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port); - -extern int SkGmUpdateStats( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port); - -extern int SkXmMacStatistic( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port, - SK_U16 StatAddr, - SK_U32 SK_FAR *pVal); - -extern int SkGmMacStatistic( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port, - SK_U16 StatAddr, - SK_U32 SK_FAR *pVal); - -extern int SkXmResetCounter( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port); - -extern int SkGmResetCounter( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port); - -extern int SkXmOverflowStatus( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port, - SK_U16 IStatus, - SK_U64 SK_FAR *pStatus); - -extern int SkGmOverflowStatus( - SK_AC *pAC, - SK_IOC IoC, - unsigned int Port, - SK_U16 MacStatus, - SK_U64 SK_FAR *pStatus); - -extern int SkGmCableDiagStatus( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL StartTest); - -#ifdef SK_DIAG -extern void SkGePhyRead( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 *pVal); - -extern void SkGePhyWrite( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Addr, - SK_U16 Val); - -extern void SkMacSetRxCmd( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Mode); -extern void SkMacCrcGener( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL Enable); -extern void SkMacTimeStamp( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL Enable); -extern void SkXmSendCont( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL Enable); -#endif /* SK_DIAG */ - -#else /* SK_KR_PROTO */ - -/* - * public functions in skgeinit.c - */ -extern void SkGePollTxD(); -extern void SkGeYellowLED(); -extern int SkGeCfgSync(); -extern void SkGeLoadLnkSyncCnt(); -extern void SkGeStopPort(); -extern int SkGeInit(); -extern void SkGeDeInit(); -extern int SkGeInitPort(); -extern void SkGeXmitLED(); -extern int SkGeInitAssignRamToQueues(); - -/* - * public functions in skxmac2.c - */ -extern void SkMacRxTxDisable(); -extern void SkMacSoftRst(); -extern void SkMacHardRst(); -extern void SkMacInitPhy(); -extern int SkMacRxTxEnable(); -extern void SkMacPromiscMode(); -extern void SkMacHashing(); -extern void SkMacIrqDisable(); -extern void SkMacFlushTxFifo(); -extern void SkMacIrq(); -extern int SkMacAutoNegDone(); -extern void SkMacAutoNegLipaPhy(); -extern void SkXmInitMac(); -extern void SkXmPhyRead(); -extern void SkXmPhyWrite(); -extern void SkGmInitMac(); -extern void SkGmPhyRead(); -extern void SkGmPhyWrite(); -extern void SkXmClrExactAddr(); -extern void SkXmAutoNegLipaXmac(); -extern int SkXmUpdateStats(); -extern int SkGmUpdateStats(); -extern int SkXmMacStatistic(); -extern int SkGmMacStatistic(); -extern int SkXmResetCounter(); -extern int SkGmResetCounter(); -extern int SkXmOverflowStatus(); -extern int SkGmOverflowStatus(); -extern int SkGmCableDiagStatus(); - -#ifdef SK_DIAG -extern void SkGePhyRead(); -extern void SkGePhyWrite(); -extern void SkMacSetRxCmd(); -extern void SkMacCrcGener(); -extern void SkMacTimeStamp(); -extern void SkXmSendCont(); -#endif /* SK_DIAG */ - -#endif /* SK_KR_PROTO */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_SKGEINIT_H_ */ diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h deleted file mode 100644 index ddd304f1a48b..000000000000 --- a/drivers/net/sk98lin/h/skgepnm2.h +++ /dev/null @@ -1,334 +0,0 @@ -/***************************************************************************** - * - * Name: skgepnm2.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.36 $ - * Date: $Date: 2003/05/23 12:45:13 $ - * Purpose: Defines for Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _SKGEPNM2_H_ -#define _SKGEPNM2_H_ - -/* - * General definitions - */ -#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ -#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ - -#define SK_PNMI_BUS_PCI 1 /* PCI bus*/ - -/* - * Actions - */ -#define SK_PNMI_ACT_IDLE 1 -#define SK_PNMI_ACT_RESET 2 -#define SK_PNMI_ACT_SELFTEST 3 -#define SK_PNMI_ACT_RESETCNT 4 - -/* - * VPD releated defines - */ - -#define SK_PNMI_VPD_RW 1 -#define SK_PNMI_VPD_RO 2 - -#define SK_PNMI_VPD_OK 0 -#define SK_PNMI_VPD_NOTFOUND 1 -#define SK_PNMI_VPD_CUT 2 -#define SK_PNMI_VPD_TIMEOUT 3 -#define SK_PNMI_VPD_FULL 4 -#define SK_PNMI_VPD_NOWRITE 5 -#define SK_PNMI_VPD_FATAL 6 - -#define SK_PNMI_VPD_IGNORE 0 -#define SK_PNMI_VPD_CREATE 1 -#define SK_PNMI_VPD_DELETE 2 - - -/* - * RLMT related defines - */ -#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */ - - -/* - * VCT internal status values - */ -#define SK_PNMI_VCT_PENDING 32 -#define SK_PNMI_VCT_TEST_DONE 64 -#define SK_PNMI_VCT_LINK 128 - -/* - * Internal table definitions - */ -#define SK_PNMI_GET 0 -#define SK_PNMI_PRESET 1 -#define SK_PNMI_SET 2 - -#define SK_PNMI_RO 0 -#define SK_PNMI_RW 1 -#define SK_PNMI_WO 2 - -typedef struct s_OidTabEntry { - SK_U32 Id; - SK_U32 InstanceNo; - unsigned int StructSize; - unsigned int Offset; - int Access; - int (* Func)(SK_AC *pAc, SK_IOC pIo, int action, - SK_U32 Id, char* pBuf, unsigned int* pLen, - SK_U32 Instance, unsigned int TableIndex, - SK_U32 NetNumber); - SK_U16 Param; -} SK_PNMI_TAB_ENTRY; - - -/* - * Trap lengths - */ -#define SK_PNMI_TRAP_SIMPLE_LEN 17 -#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46 -#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23 -#define SK_PNMI_TRAP_RLMT_PORT_LEN 23 - -/* - * Number of MAC types supported - */ -#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1) - -/* - * MAC statistic data list (overall set for MAC types used) - */ -enum SK_MACSTATS { - SK_PNMI_HTX = 0, - SK_PNMI_HTX_OCTET, - SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET, - SK_PNMI_HTX_OCTETLOW, - SK_PNMI_HTX_BROADCAST, - SK_PNMI_HTX_MULTICAST, - SK_PNMI_HTX_UNICAST, - SK_PNMI_HTX_BURST, - SK_PNMI_HTX_PMACC, - SK_PNMI_HTX_MACC, - SK_PNMI_HTX_COL, - SK_PNMI_HTX_SINGLE_COL, - SK_PNMI_HTX_MULTI_COL, - SK_PNMI_HTX_EXCESS_COL, - SK_PNMI_HTX_LATE_COL, - SK_PNMI_HTX_DEFFERAL, - SK_PNMI_HTX_EXCESS_DEF, - SK_PNMI_HTX_UNDERRUN, - SK_PNMI_HTX_CARRIER, - SK_PNMI_HTX_UTILUNDER, - SK_PNMI_HTX_UTILOVER, - SK_PNMI_HTX_64, - SK_PNMI_HTX_127, - SK_PNMI_HTX_255, - SK_PNMI_HTX_511, - SK_PNMI_HTX_1023, - SK_PNMI_HTX_MAX, - SK_PNMI_HTX_LONGFRAMES, - SK_PNMI_HTX_SYNC, - SK_PNMI_HTX_SYNC_OCTET, - SK_PNMI_HTX_RESERVED, - - SK_PNMI_HRX, - SK_PNMI_HRX_OCTET, - SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET, - SK_PNMI_HRX_OCTETLOW, - SK_PNMI_HRX_BADOCTET, - SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET, - SK_PNMI_HRX_BADOCTETLOW, - SK_PNMI_HRX_BROADCAST, - SK_PNMI_HRX_MULTICAST, - SK_PNMI_HRX_UNICAST, - SK_PNMI_HRX_PMACC, - SK_PNMI_HRX_MACC, - SK_PNMI_HRX_PMACC_ERR, - SK_PNMI_HRX_MACC_UNKWN, - SK_PNMI_HRX_BURST, - SK_PNMI_HRX_MISSED, - SK_PNMI_HRX_FRAMING, - SK_PNMI_HRX_UNDERSIZE, - SK_PNMI_HRX_OVERFLOW, - SK_PNMI_HRX_JABBER, - SK_PNMI_HRX_CARRIER, - SK_PNMI_HRX_IRLENGTH, - SK_PNMI_HRX_SYMBOL, - SK_PNMI_HRX_SHORTS, - SK_PNMI_HRX_RUNT, - SK_PNMI_HRX_TOO_LONG, - SK_PNMI_HRX_FCS, - SK_PNMI_HRX_CEXT, - SK_PNMI_HRX_UTILUNDER, - SK_PNMI_HRX_UTILOVER, - SK_PNMI_HRX_64, - SK_PNMI_HRX_127, - SK_PNMI_HRX_255, - SK_PNMI_HRX_511, - SK_PNMI_HRX_1023, - SK_PNMI_HRX_MAX, - SK_PNMI_HRX_LONGFRAMES, - - SK_PNMI_HRX_RESERVED, - - SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */ -}; - -/* - * MAC specific data - */ -typedef struct s_PnmiStatAddr { - SK_U16 Reg; /* MAC register containing the value */ - SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/ -} SK_PNMI_STATADDR; - - -/* - * SK_PNMI_STRUCT_DATA copy offset evaluation macros - */ -#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) -#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) -#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e)) -#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e)) -#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e)) -#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e)) -#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e)) -#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e)) -#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e)) -#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e)) - -#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \ - Val32 = (s); \ - pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ - &(((SK_PNMI_STRUCT_DATA *)0)-> \ - ReturnStatus.ErrorStatus)); \ - SK_PNMI_STORE_U32(pVal, Val32); \ - Val32 = (o); \ - pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ - &(((SK_PNMI_STRUCT_DATA *)0)-> \ - ReturnStatus.ErrorOffset)); \ - SK_PNMI_STORE_U32(pVal, Val32);} - -/* - * Time macros - */ -#ifndef SK_PNMI_HUNDREDS_SEC -#if SK_TICKS_PER_SEC == 100 -#define SK_PNMI_HUNDREDS_SEC(t) (t) -#else -#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC)) -#endif /* !SK_TICKS_PER_SEC */ -#endif /* !SK_PNMI_HUNDREDS_SEC */ - -/* - * Macros to work around alignment problems - */ -#ifndef SK_PNMI_STORE_U16 -#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1);} -#endif - -#ifndef SK_PNMI_STORE_U32 -#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1); \ - *((char *)(p) + 2) = \ - *(((char *)&(v)) + 2); \ - *((char *)(p) + 3) = \ - *(((char *)&(v)) + 3);} -#endif - -#ifndef SK_PNMI_STORE_U64 -#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1); \ - *((char *)(p) + 2) = \ - *(((char *)&(v)) + 2); \ - *((char *)(p) + 3) = \ - *(((char *)&(v)) + 3); \ - *((char *)(p) + 4) = \ - *(((char *)&(v)) + 4); \ - *((char *)(p) + 5) = \ - *(((char *)&(v)) + 5); \ - *((char *)(p) + 6) = \ - *(((char *)&(v)) + 6); \ - *((char *)(p) + 7) = \ - *(((char *)&(v)) + 7);} -#endif - -#ifndef SK_PNMI_READ_U16 -#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1);} -#endif - -#ifndef SK_PNMI_READ_U32 -#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1); \ - *(((char *)&(v)) + 2) = \ - *((char *)(p) + 2); \ - *(((char *)&(v)) + 3) = \ - *((char *)(p) + 3);} -#endif - -#ifndef SK_PNMI_READ_U64 -#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1); \ - *(((char *)&(v)) + 2) = \ - *((char *)(p) + 2); \ - *(((char *)&(v)) + 3) = \ - *((char *)(p) + 3); \ - *(((char *)&(v)) + 4) = \ - *((char *)(p) + 4); \ - *(((char *)&(v)) + 5) = \ - *((char *)(p) + 5); \ - *(((char *)&(v)) + 6) = \ - *((char *)(p) + 6); \ - *(((char *)&(v)) + 7) = \ - *((char *)(p) + 7);} -#endif - -/* - * Macros for Debug - */ -#ifdef DEBUG - -#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \ - pAC->Pnmi.RlmtUpdatedFlag > 0 || \ - pAC->Pnmi.SirqUpdatedFlag > 0) { \ - SK_DBG_MSG(pAC, \ - SK_DBGMOD_PNMI, \ - SK_DBGCAT_CTRL, \ - ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \ - vSt, \ - pAC->Pnmi.MacUpdatedFlag, \ - pAC->Pnmi.RlmtUpdatedFlag, \ - pAC->Pnmi.SirqUpdatedFlag))}} - -#else /* !DEBUG */ - -#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */ - -#endif /* !DEBUG */ - -#endif /* _SKGEPNM2_H_ */ diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h deleted file mode 100644 index 1ed214ccb253..000000000000 --- a/drivers/net/sk98lin/h/skgepnmi.h +++ /dev/null @@ -1,962 +0,0 @@ -/***************************************************************************** - * - * Name: skgepnmi.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.62 $ - * Date: $Date: 2003/08/15 12:31:52 $ - * Purpose: Defines for Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _SKGEPNMI_H_ -#define _SKGEPNMI_H_ - -/* - * Include dependencies - */ -#include "h/sktypes.h" -#include "h/skerror.h" -#include "h/sktimer.h" -#include "h/ski2c.h" -#include "h/skaddr.h" -#include "h/skrlmt.h" -#include "h/skvpd.h" - -/* - * Management Database Version - */ -#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */ - - -/* - * Event definitions - */ -#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */ -#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */ -#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */ -#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */ -#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */ -#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */ -#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */ -#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */ -#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */ - -#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */ -#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */ -#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */ -#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */ -#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */ -#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets - 1 = single net; 2 = dual net */ -#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */ - - -/* - * Return values - */ -#define SK_PNMI_ERR_OK 0 -#define SK_PNMI_ERR_GENERAL 1 -#define SK_PNMI_ERR_TOO_SHORT 2 -#define SK_PNMI_ERR_BAD_VALUE 3 -#define SK_PNMI_ERR_READ_ONLY 4 -#define SK_PNMI_ERR_UNKNOWN_OID 5 -#define SK_PNMI_ERR_UNKNOWN_INST 6 -#define SK_PNMI_ERR_UNKNOWN_NET 7 -#define SK_PNMI_ERR_NOT_SUPPORTED 10 - - -/* - * Return values of driver reset function SK_DRIVER_RESET() and - * driver event function SK_DRIVER_EVENT() - */ -#define SK_PNMI_ERR_OK 0 -#define SK_PNMI_ERR_FAIL 1 - - -/* - * Return values of driver test function SK_DRIVER_SELFTEST() - */ -#define SK_PNMI_TST_UNKNOWN (1 << 0) -#define SK_PNMI_TST_TRANCEIVER (1 << 1) -#define SK_PNMI_TST_ASIC (1 << 2) -#define SK_PNMI_TST_SENSOR (1 << 3) -#define SK_PNMI_TST_POWERMGMT (1 << 4) -#define SK_PNMI_TST_PCI (1 << 5) -#define SK_PNMI_TST_MAC (1 << 6) - - -/* - * RLMT specific definitions - */ -#define SK_PNMI_RLMT_STATUS_STANDBY 1 -#define SK_PNMI_RLMT_STATUS_ACTIVE 2 -#define SK_PNMI_RLMT_STATUS_ERROR 3 - -#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1 -#define SK_PNMI_RLMT_LSTAT_AUTONEG 2 -#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3 -#define SK_PNMI_RLMT_LSTAT_LOG_UP 4 -#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5 - -#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK) -#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK) -#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG) -/* #define SK_PNMI_RLMT_MODE_CHK_EX */ - -/* - * OID definition - */ -#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */ - -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 - -/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */ -#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */ -#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */ -#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */ -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */ -#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */ -#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D -#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -/* #define OID_802_3_MULTICAST_LIST 0x01010103 */ -/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */ -/* #define OID_802_3_MAC_OPTIONS 0x01010105 */ - -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -/* - * PnP and PM OIDs - */ -#ifdef SK_POWER_MGMT -#define OID_PNP_CAPABILITIES 0xFD010100 -#define OID_PNP_SET_POWER 0xFD010101 -#define OID_PNP_QUERY_POWER 0xFD010102 -#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 -#endif /* SK_POWER_MGMT */ - -#endif /* _NDIS_ */ - -#define OID_SKGE_MDB_VERSION 0xFF010100 -#define OID_SKGE_SUPPORTED_LIST 0xFF010101 -#define OID_SKGE_VPD_FREE_BYTES 0xFF010102 -#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103 -#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104 -#define OID_SKGE_VPD_KEY 0xFF010105 -#define OID_SKGE_VPD_VALUE 0xFF010106 -#define OID_SKGE_VPD_ACCESS 0xFF010107 -#define OID_SKGE_VPD_ACTION 0xFF010108 - -#define OID_SKGE_PORT_NUMBER 0xFF010110 -#define OID_SKGE_DEVICE_TYPE 0xFF010111 -#define OID_SKGE_DRIVER_DESCR 0xFF010112 -#define OID_SKGE_DRIVER_VERSION 0xFF010113 -#define OID_SKGE_HW_DESCR 0xFF010114 -#define OID_SKGE_HW_VERSION 0xFF010115 -#define OID_SKGE_CHIPSET 0xFF010116 -#define OID_SKGE_ACTION 0xFF010117 -#define OID_SKGE_RESULT 0xFF010118 -#define OID_SKGE_BUS_TYPE 0xFF010119 -#define OID_SKGE_BUS_SPEED 0xFF01011A -#define OID_SKGE_BUS_WIDTH 0xFF01011B -/* 0xFF01011C unused */ -#define OID_SKGE_DIAG_ACTION 0xFF01011D -#define OID_SKGE_DIAG_RESULT 0xFF01011E -#define OID_SKGE_MTU 0xFF01011F -#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120 -#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121 -#define OID_SKGE_PMD 0xFF010122 -#define OID_SKGE_CONNECTOR 0xFF010123 -#define OID_SKGE_LINK_CAP 0xFF010124 -#define OID_SKGE_LINK_MODE 0xFF010125 -#define OID_SKGE_LINK_MODE_STATUS 0xFF010126 -#define OID_SKGE_LINK_STATUS 0xFF010127 -#define OID_SKGE_FLOWCTRL_CAP 0xFF010128 -#define OID_SKGE_FLOWCTRL_MODE 0xFF010129 -#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A -#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B -#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C -#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D -#define OID_SKGE_MULTICAST_LIST 0xFF01012E -#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F - -#define OID_SKGE_TRAP 0xFF010130 -#define OID_SKGE_TRAP_NUMBER 0xFF010131 - -#define OID_SKGE_RLMT_MODE 0xFF010140 -#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141 -#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142 -#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143 -#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160 - -#define OID_SKGE_SPEED_CAP 0xFF010170 -#define OID_SKGE_SPEED_MODE 0xFF010171 -#define OID_SKGE_SPEED_STATUS 0xFF010172 - -#define OID_SKGE_BOARDLEVEL 0xFF010180 - -#define OID_SKGE_SENSOR_NUMBER 0xFF020100 -#define OID_SKGE_SENSOR_INDEX 0xFF020101 -#define OID_SKGE_SENSOR_DESCR 0xFF020102 -#define OID_SKGE_SENSOR_TYPE 0xFF020103 -#define OID_SKGE_SENSOR_VALUE 0xFF020104 -#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105 -#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106 -#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107 -#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108 -#define OID_SKGE_SENSOR_STATUS 0xFF020109 -#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A -#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B -#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C -#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D - -#define OID_SKGE_CHKSM_NUMBER 0xFF020110 -#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111 -#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112 -#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113 -#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114 -#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115 - -#define OID_SKGE_STAT_TX 0xFF020120 -#define OID_SKGE_STAT_TX_OCTETS 0xFF020121 -#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122 -#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123 -#define OID_SKGE_STAT_TX_UNICAST 0xFF020124 -#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125 -#define OID_SKGE_STAT_TX_BURST 0xFF020126 -#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127 -#define OID_SKGE_STAT_TX_FLOWC 0xFF020128 -#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129 -#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A -#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B -#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C -#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D -#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E -#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F -#define OID_SKGE_STAT_TX_CARRIER 0xFF020130 -/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */ -#define OID_SKGE_STAT_TX_64 0xFF020132 -#define OID_SKGE_STAT_TX_127 0xFF020133 -#define OID_SKGE_STAT_TX_255 0xFF020134 -#define OID_SKGE_STAT_TX_511 0xFF020135 -#define OID_SKGE_STAT_TX_1023 0xFF020136 -#define OID_SKGE_STAT_TX_MAX 0xFF020137 -#define OID_SKGE_STAT_TX_SYNC 0xFF020138 -#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139 -#define OID_SKGE_STAT_RX 0xFF02013A -#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B -#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C -#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D -#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E -#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F -#define OID_SKGE_STAT_RX_FLOWC 0xFF020140 -#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141 -#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142 -#define OID_SKGE_STAT_RX_BURST 0xFF020143 -#define OID_SKGE_STAT_RX_MISSED 0xFF020144 -#define OID_SKGE_STAT_RX_FRAMING 0xFF020145 -#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146 -#define OID_SKGE_STAT_RX_JABBER 0xFF020147 -#define OID_SKGE_STAT_RX_CARRIER 0xFF020148 -#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149 -#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A -#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B -#define OID_SKGE_STAT_RX_RUNT 0xFF02014C -#define OID_SKGE_STAT_RX_CEXT 0xFF02014D -#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E -#define OID_SKGE_STAT_RX_FCS 0xFF02014F -/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */ -#define OID_SKGE_STAT_RX_64 0xFF020151 -#define OID_SKGE_STAT_RX_127 0xFF020152 -#define OID_SKGE_STAT_RX_255 0xFF020153 -#define OID_SKGE_STAT_RX_511 0xFF020154 -#define OID_SKGE_STAT_RX_1023 0xFF020155 -#define OID_SKGE_STAT_RX_MAX 0xFF020156 -#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157 - -#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160 -#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161 -#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162 -#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163 - -#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164 -#define OID_SKGE_RLMT_STATUS 0xFF020165 -#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166 -#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167 -#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168 -#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169 - -#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150 -#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151 -#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152 -#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153 -#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154 -#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155 - -#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170 -#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171 -#define OID_SKGE_TX_RETRY 0xFF020172 -#define OID_SKGE_RX_INTR_CTS 0xFF020173 -#define OID_SKGE_TX_INTR_CTS 0xFF020174 -#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175 -#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176 -#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177 -#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178 -#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179 -#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A -#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B -#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C -#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D -#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E -#define OID_SKGE_SYSUPTIME 0xFF02017F - -#define OID_SKGE_ALL_DATA 0xFF020190 - -/* Defines for VCT. */ -#define OID_SKGE_VCT_GET 0xFF020200 -#define OID_SKGE_VCT_SET 0xFF020201 -#define OID_SKGE_VCT_STATUS 0xFF020202 - -#ifdef SK_DIAG_SUPPORT -/* Defines for driver DIAG mode. */ -#define OID_SKGE_DIAG_MODE 0xFF020204 -#endif /* SK_DIAG_SUPPORT */ - -/* New OIDs */ -#define OID_SKGE_DRIVER_RELDATE 0xFF020210 -#define OID_SKGE_DRIVER_FILENAME 0xFF020211 -#define OID_SKGE_CHIPID 0xFF020212 -#define OID_SKGE_RAMSIZE 0xFF020213 -#define OID_SKGE_VAUXAVAIL 0xFF020214 -#define OID_SKGE_PHY_TYPE 0xFF020215 -#define OID_SKGE_PHY_LP_MODE 0xFF020216 - -/* VCT struct to store a backup copy of VCT data after a port reset. */ -typedef struct s_PnmiVct { - SK_U8 VctStatus; - SK_U8 PCableLen; - SK_U32 PMdiPairLen[4]; - SK_U8 PMdiPairSts[4]; -} SK_PNMI_VCT; - - -/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */ -#define SK_PNMI_VCT_NONE 0 -#define SK_PNMI_VCT_OLD_VCT_DATA 1 -#define SK_PNMI_VCT_NEW_VCT_DATA 2 -#define SK_PNMI_VCT_OLD_DSP_DATA 4 -#define SK_PNMI_VCT_NEW_DSP_DATA 8 -#define SK_PNMI_VCT_RUNNING 16 - - -/* VCT cable test status. */ -#define SK_PNMI_VCT_NORMAL_CABLE 0 -#define SK_PNMI_VCT_SHORT_CABLE 1 -#define SK_PNMI_VCT_OPEN_CABLE 2 -#define SK_PNMI_VCT_TEST_FAIL 3 -#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4 - -#define OID_SKGE_TRAP_SEN_WAR_LOW 500 -#define OID_SKGE_TRAP_SEN_WAR_UPP 501 -#define OID_SKGE_TRAP_SEN_ERR_LOW 502 -#define OID_SKGE_TRAP_SEN_ERR_UPP 503 -#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520 -#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521 -#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522 -#define OID_SKGE_TRAP_RLMT_PORT_UP 523 -#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 - -#ifdef SK_DIAG_SUPPORT -/* Defines for driver DIAG mode. */ -#define SK_DIAG_ATTACHED 2 -#define SK_DIAG_RUNNING 1 -#define SK_DIAG_IDLE 0 -#endif /* SK_DIAG_SUPPORT */ - -/* - * Generic PNMI IOCTL subcommand definitions. - */ -#define SK_GET_SINGLE_VAR 1 -#define SK_SET_SINGLE_VAR 2 -#define SK_PRESET_SINGLE_VAR 3 -#define SK_GET_FULL_MIB 4 -#define SK_SET_FULL_MIB 5 -#define SK_PRESET_FULL_MIB 6 - - -/* - * Define error numbers and messages for syslog - */ -#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1) -#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID" -#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2) -#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys" -#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3) -#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID" -#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4) -#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action" -#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5) -#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver" -#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6) -#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command" -#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7) -#define SK_PNMI_ERR007MSG "General: Driver description not initialized" -#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8) -#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID" -#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9) -#define SK_PNMI_ERR009MSG "Addr: Unknown OID" -#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10) -#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID" -#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11) -#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long" -#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12) -#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID" -#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13) -#define SK_PNMI_ERR013MSG "" -#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14) -#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys" -#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15) -#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small" -#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16) -#define SK_PNMI_ERR016MSG "Vpd: Key string too long" -#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17) -#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer" -#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18) -#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid" -#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19) -#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long" -#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21) -#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long" -#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22) -#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before" -#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23) -#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action" -#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24) -#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action" -#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25) -#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry" -#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26) -#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD" -#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27) -#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry" -#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28) -#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry" -#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29) -#define SK_PNMI_ERR029MSG "General: Driver description string too long" -#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30) -#define SK_PNMI_ERR030MSG "General: Driver version not initialized" -#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31) -#define SK_PNMI_ERR031MSG "General: Driver version string too long" -#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32) -#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr" -#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33) -#define SK_PNMI_ERR033MSG "General: HW description string too long" -#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34) -#define SK_PNMI_ERR034MSG "General: Unknown OID" -#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35) -#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID" -#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36) -#define SK_PNMI_ERR036MSG "" -#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37) -#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0" -#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38) -#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0" -#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39) -#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID" -#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40) -#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID" -#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41) -#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID" -#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42) -#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0" -#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43) -#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0" -#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44) -#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0" -#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45) -#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0" -#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46) -#define SK_PNMI_ERR046MSG "Monitor: Unknown OID" -#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47) -#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0" -#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48) -#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0" -#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49) -#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!" -#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50) -#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!" -#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51) -#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" -#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) -#define SK_PNMI_ERR052MSG "" -#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53) -#define SK_PNMI_ERR053MSG "General: Driver release date not initialized" -#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54) -#define SK_PNMI_ERR054MSG "General: Driver release date string too long" -#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55) -#define SK_PNMI_ERR055MSG "General: Driver file name not initialized" -#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56) -#define SK_PNMI_ERR056MSG "General: Driver file name string too long" - -/* - * Management counter macros called by the driver - */ -#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \ - (char *)(v)) - -#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \ - { \ - (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \ - if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \ - (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \ - } \ - } -#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++) -#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++) -#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++) -#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++) -#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++) -#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \ - ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v)); -#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \ - { \ - ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \ - (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \ - } -#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++); - -#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatSyncCts)++; \ - (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \ - } \ - } - -#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \ - } \ - } - -#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \ - } \ - } - -#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \ - } \ - } - -/* - * Conversion Macros - */ -#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1) -#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1) -#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1) -#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1) -#define SK_PNMI_PORT_PHYS2INST(pAC,p) \ - (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2)) -#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2) - -/* - * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct - */ -#define SK_PNMI_VPD_KEY_SIZE 5 -#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE) -#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4) -#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */ - -#define SK_PNMI_MULTICAST_LISTLEN 64 -#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS) -#define SK_PNMI_CHECKSUM_ENTRIES 3 -#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1) -#define SK_PNMI_MONITOR_ENTRIES 20 -#define SK_PNMI_TRAP_ENTRIES 10 -#define SK_PNMI_TRAPLEN 128 -#define SK_PNMI_STRINGLEN1 80 -#define SK_PNMI_STRINGLEN2 25 -#define SK_PNMI_TRAP_QUEUE_LEN 512 - -typedef struct s_PnmiVpd { - char VpdKey[SK_PNMI_VPD_KEY_SIZE]; - char VpdValue[SK_PNMI_VPD_DATALEN]; - SK_U8 VpdAccess; - SK_U8 VpdAction; -} SK_PNMI_VPD; - -typedef struct s_PnmiSensor { - SK_U8 SensorIndex; - char SensorDescr[SK_PNMI_STRINGLEN2]; - SK_U8 SensorType; - SK_U32 SensorValue; - SK_U32 SensorWarningThresholdLow; - SK_U32 SensorWarningThresholdHigh; - SK_U32 SensorErrorThresholdLow; - SK_U32 SensorErrorThresholdHigh; - SK_U8 SensorStatus; - SK_U64 SensorWarningCts; - SK_U64 SensorErrorCts; - SK_U64 SensorWarningTimestamp; - SK_U64 SensorErrorTimestamp; -} SK_PNMI_SENSOR; - -typedef struct s_PnmiChecksum { - SK_U64 ChecksumRxOkCts; - SK_U64 ChecksumRxUnableCts; - SK_U64 ChecksumRxErrCts; - SK_U64 ChecksumTxOkCts; - SK_U64 ChecksumTxUnableCts; -} SK_PNMI_CHECKSUM; - -typedef struct s_PnmiStat { - SK_U64 StatTxOkCts; - SK_U64 StatTxOctetsOkCts; - SK_U64 StatTxBroadcastOkCts; - SK_U64 StatTxMulticastOkCts; - SK_U64 StatTxUnicastOkCts; - SK_U64 StatTxLongFramesCts; - SK_U64 StatTxBurstCts; - SK_U64 StatTxPauseMacCtrlCts; - SK_U64 StatTxMacCtrlCts; - SK_U64 StatTxSingleCollisionCts; - SK_U64 StatTxMultipleCollisionCts; - SK_U64 StatTxExcessiveCollisionCts; - SK_U64 StatTxLateCollisionCts; - SK_U64 StatTxDeferralCts; - SK_U64 StatTxExcessiveDeferralCts; - SK_U64 StatTxFifoUnderrunCts; - SK_U64 StatTxCarrierCts; - SK_U64 Dummy1; /* StatTxUtilization */ - SK_U64 StatTx64Cts; - SK_U64 StatTx127Cts; - SK_U64 StatTx255Cts; - SK_U64 StatTx511Cts; - SK_U64 StatTx1023Cts; - SK_U64 StatTxMaxCts; - SK_U64 StatTxSyncCts; - SK_U64 StatTxSyncOctetsCts; - SK_U64 StatRxOkCts; - SK_U64 StatRxOctetsOkCts; - SK_U64 StatRxBroadcastOkCts; - SK_U64 StatRxMulticastOkCts; - SK_U64 StatRxUnicastOkCts; - SK_U64 StatRxLongFramesCts; - SK_U64 StatRxPauseMacCtrlCts; - SK_U64 StatRxMacCtrlCts; - SK_U64 StatRxPauseMacCtrlErrorCts; - SK_U64 StatRxMacCtrlUnknownCts; - SK_U64 StatRxBurstCts; - SK_U64 StatRxMissedCts; - SK_U64 StatRxFramingCts; - SK_U64 StatRxFifoOverflowCts; - SK_U64 StatRxJabberCts; - SK_U64 StatRxCarrierCts; - SK_U64 StatRxIRLengthCts; - SK_U64 StatRxSymbolCts; - SK_U64 StatRxShortsCts; - SK_U64 StatRxRuntCts; - SK_U64 StatRxCextCts; - SK_U64 StatRxTooLongCts; - SK_U64 StatRxFcsCts; - SK_U64 Dummy2; /* StatRxUtilization */ - SK_U64 StatRx64Cts; - SK_U64 StatRx127Cts; - SK_U64 StatRx255Cts; - SK_U64 StatRx511Cts; - SK_U64 StatRx1023Cts; - SK_U64 StatRxMaxCts; -} SK_PNMI_STAT; - -typedef struct s_PnmiConf { - char ConfMacCurrentAddr[6]; - char ConfMacFactoryAddr[6]; - SK_U8 ConfPMD; - SK_U8 ConfConnector; - SK_U32 ConfPhyType; - SK_U32 ConfPhyMode; - SK_U8 ConfLinkCapability; - SK_U8 ConfLinkMode; - SK_U8 ConfLinkModeStatus; - SK_U8 ConfLinkStatus; - SK_U8 ConfFlowCtrlCapability; - SK_U8 ConfFlowCtrlMode; - SK_U8 ConfFlowCtrlStatus; - SK_U8 ConfPhyOperationCapability; - SK_U8 ConfPhyOperationMode; - SK_U8 ConfPhyOperationStatus; - SK_U8 ConfSpeedCapability; - SK_U8 ConfSpeedMode; - SK_U8 ConfSpeedStatus; -} SK_PNMI_CONF; - -typedef struct s_PnmiRlmt { - SK_U32 RlmtIndex; - SK_U32 RlmtStatus; - SK_U64 RlmtTxHelloCts; - SK_U64 RlmtRxHelloCts; - SK_U64 RlmtTxSpHelloReqCts; - SK_U64 RlmtRxSpHelloCts; -} SK_PNMI_RLMT; - -typedef struct s_PnmiRlmtMonitor { - SK_U32 RlmtMonitorIndex; - char RlmtMonitorAddr[6]; - SK_U64 RlmtMonitorErrorCts; - SK_U64 RlmtMonitorTimestamp; - SK_U8 RlmtMonitorAdmin; -} SK_PNMI_RLMT_MONITOR; - -typedef struct s_PnmiRequestStatus { - SK_U32 ErrorStatus; - SK_U32 ErrorOffset; -} SK_PNMI_REQUEST_STATUS; - -typedef struct s_PnmiStrucData { - SK_U32 MgmtDBVersion; - SK_PNMI_REQUEST_STATUS ReturnStatus; - SK_U32 VpdFreeBytes; - char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE]; - SK_U32 VpdEntriesNumber; - SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES]; - SK_U32 PortNumber; - SK_U32 DeviceType; - char DriverDescr[SK_PNMI_STRINGLEN1]; - char DriverVersion[SK_PNMI_STRINGLEN2]; - char DriverReleaseDate[SK_PNMI_STRINGLEN1]; - char DriverFileName[SK_PNMI_STRINGLEN1]; - char HwDescr[SK_PNMI_STRINGLEN1]; - char HwVersion[SK_PNMI_STRINGLEN2]; - SK_U16 Chipset; - SK_U32 ChipId; - SK_U8 VauxAvail; - SK_U32 RamSize; - SK_U32 MtuSize; - SK_U32 Action; - SK_U32 TestResult; - SK_U8 BusType; - SK_U8 BusSpeed; - SK_U8 BusWidth; - SK_U8 SensorNumber; - SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES]; - SK_U8 ChecksumNumber; - SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES]; - SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES]; - SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES]; - SK_U8 RlmtMode; - SK_U32 RlmtPortNumber; - SK_U8 RlmtPortActive; - SK_U8 RlmtPortPreferred; - SK_U64 RlmtChangeCts; - SK_U64 RlmtChangeTime; - SK_U64 RlmtChangeEstimate; - SK_U64 RlmtChangeThreshold; - SK_PNMI_RLMT Rlmt[SK_MAX_MACS]; - SK_U32 RlmtMonitorNumber; - SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES]; - SK_U32 TrapNumber; - SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN]; - SK_U64 TxSwQueueLen; - SK_U64 TxSwQueueMax; - SK_U64 TxRetryCts; - SK_U64 RxIntrCts; - SK_U64 TxIntrCts; - SK_U64 RxNoBufCts; - SK_U64 TxNoBufCts; - SK_U64 TxUsedDescrNo; - SK_U64 RxDeliveredCts; - SK_U64 RxOctetsDeliveredCts; - SK_U64 RxHwErrorsCts; - SK_U64 TxHwErrorsCts; - SK_U64 InErrorsCts; - SK_U64 OutErrorsCts; - SK_U64 ErrRecoveryCts; - SK_U64 SysUpTime; -} SK_PNMI_STRUCT_DATA; - -#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA)) -#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\ - &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes)) - /* - * ReturnStatus field - * must be located - * before VpdFreeBytes - */ - -/* - * Various definitions - */ -#define SK_PNMI_MAX_PROTOS 3 - -#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum - * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK - * for check while init phase 1 - */ - -/* - * Estimate data structure - */ -typedef struct s_PnmiEstimate { - unsigned int EstValueIndex; - SK_U64 EstValue[7]; - SK_U64 Estimate; - SK_TIMER EstTimer; -} SK_PNMI_ESTIMATE; - - -/* - * VCT timer data structure - */ -typedef struct s_VctTimer { - SK_TIMER VctTimer; -} SK_PNMI_VCT_TIMER; - - -/* - * PNMI specific adapter context structure - */ -typedef struct s_PnmiPort { - SK_U64 StatSyncCts; - SK_U64 StatSyncOctetsCts; - SK_U64 StatRxLongFrameCts; - SK_U64 StatRxFrameTooLongCts; - SK_U64 StatRxPMaccErr; - SK_U64 TxSwQueueLen; - SK_U64 TxSwQueueMax; - SK_U64 TxRetryCts; - SK_U64 RxIntrCts; - SK_U64 TxIntrCts; - SK_U64 RxNoBufCts; - SK_U64 TxNoBufCts; - SK_U64 TxUsedDescrNo; - SK_U64 RxDeliveredCts; - SK_U64 RxOctetsDeliveredCts; - SK_U64 RxHwErrorsCts; - SK_U64 TxHwErrorsCts; - SK_U64 InErrorsCts; - SK_U64 OutErrorsCts; - SK_U64 ErrRecoveryCts; - SK_U64 RxShortZeroMark; - SK_U64 CounterOffset[SK_PNMI_CNT_NO]; - SK_U32 CounterHigh[SK_PNMI_CNT_NO]; - SK_BOOL ActiveFlag; - SK_U8 Align[3]; -} SK_PNMI_PORT; - - -typedef struct s_PnmiData { - SK_PNMI_PORT Port [SK_MAX_MACS]; - SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */ - SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO]; - SK_U32 TestResult; - char HwVersion[10]; - SK_U16 Align01; - - char *pDriverDescription; - char *pDriverVersion; - char *pDriverReleaseDate; - char *pDriverFileName; - - int MacUpdatedFlag; - int RlmtUpdatedFlag; - int SirqUpdatedFlag; - - SK_U64 RlmtChangeCts; - SK_U64 RlmtChangeTime; - SK_PNMI_ESTIMATE RlmtChangeEstimate; - SK_U64 RlmtChangeThreshold; - - SK_U64 StartUpTime; - SK_U32 DeviceType; - char PciBusSpeed; - char PciBusWidth; - char Chipset; - char PMD; - char Connector; - SK_BOOL DualNetActiveFlag; - SK_U16 Align02; - - char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN]; - unsigned int TrapBufFree; - unsigned int TrapQueueBeg; - unsigned int TrapQueueEnd; - unsigned int TrapBufPad; - unsigned int TrapUnique; - SK_U8 VctStatus[SK_MAX_MACS]; - SK_PNMI_VCT VctBackup[SK_MAX_MACS]; - SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS]; -#ifdef SK_DIAG_SUPPORT - SK_U32 DiagAttached; -#endif /* SK_DIAG_SUPPORT */ -} SK_PNMI; - - -/* - * Function prototypes - */ -extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); -extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, - SK_EVPARA Param); -extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, - unsigned int * pLen, SK_U32 NetIndex); - -#endif diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h deleted file mode 100644 index 3eec6274e413..000000000000 --- a/drivers/net/sk98lin/h/skgesirq.h +++ /dev/null @@ -1,110 +0,0 @@ -/****************************************************************************** - * - * Name: skgesirq.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.30 $ - * Date: $Date: 2003/07/04 12:34:13 $ - * Purpose: SK specific Gigabit Ethernet special IRQ functions - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _INC_SKGESIRQ_H_ -#define _INC_SKGESIRQ_H_ - -/* Define return codes of SkGePortCheckUp and CheckShort */ -#define SK_HW_PS_NONE 0 /* No action needed */ -#define SK_HW_PS_RESTART 1 /* Restart needed */ -#define SK_HW_PS_LINK 2 /* Link Up actions needed */ - -/* - * Define the Event the special IRQ/INI module can handle - */ -#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */ -#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */ -#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */ -#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */ -#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */ -#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */ -#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */ -#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */ -#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */ -#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */ - -#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */ -#define SK_WA_INA_TIME (100000UL) /* 100 msec */ - -#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */ - -/* - * Define the error numbers and messages - */ -#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0) -#define SKERR_SIRQ_E001MSG "Unknown event" -#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1) -#define SKERR_SIRQ_E002MSG "Packet timeout RX1" -#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1) -#define SKERR_SIRQ_E003MSG "Packet timeout RX2" -#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1) -#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized" -#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1) -#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized" -#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1) -#define SKERR_SIRQ_E006MSG "CHECK failure R1" -#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1) -#define SKERR_SIRQ_E007MSG "CHECK failure R2" -#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1) -#define SKERR_SIRQ_E008MSG "CHECK failure XS1" -#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1) -#define SKERR_SIRQ_E009MSG "CHECK failure XA1" -#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1) -#define SKERR_SIRQ_E010MSG "CHECK failure XS2" -#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1) -#define SKERR_SIRQ_E011MSG "CHECK failure XA2" -#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1) -#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error" -#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1) -#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error" -#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1) -#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)" -#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1) -#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)" -#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1) -#define SKERR_SIRQ_E016MSG "Parity error MAC 1" -#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1) -#define SKERR_SIRQ_E017MSG "Parity error MAC 2" -#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1) -#define SKERR_SIRQ_E018MSG "Parity error RX 1" -#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1) -#define SKERR_SIRQ_E019MSG "Parity error RX 2" -#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1) -#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun" -#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1) -#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt" -#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1) -#define SKERR_SIRQ_E022MSG "Cable pair swap error" -#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1) -#define SKERR_SIRQ_E023MSG "Auto-negotiation error" -#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1) -#define SKERR_SIRQ_E024MSG "FIFO overflow error" -#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1) -#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected" - -extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); -extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); - -#endif /* _INC_SKGESIRQ_H_ */ diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h deleted file mode 100644 index 6a63f4a15de6..000000000000 --- a/drivers/net/sk98lin/h/ski2c.h +++ /dev/null @@ -1,174 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Version: $Revision: 1.35 $ - * Date: $Date: 2003/10/20 09:06:30 $ - * Purpose: Defines to access Voltage and Temperature Sensor - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKI2C.H contains all I2C specific defines - */ - -#ifndef _SKI2C_H_ -#define _SKI2C_H_ - -typedef struct s_Sensor SK_SENSOR; - -#include "h/skgei2c.h" - -/* - * Define the I2C events. - */ -#define SK_I2CEV_IRQ 1 /* IRQ happened Event */ -#define SK_I2CEV_TIM 2 /* Timeout event */ -#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */ - -/* - * Define READ and WRITE Constants. - */ -#define I2C_READ 0 -#define I2C_WRITE 1 -#define I2C_BURST 1 -#define I2C_SINGLE 0 - -#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) -#define SKERR_I2C_E001MSG "Sensor index unknown" -#define SKERR_I2C_E002 (SKERR_I2C_E001+1) -#define SKERR_I2C_E002MSG "TWSI: transfer does not complete" -#define SKERR_I2C_E003 (SKERR_I2C_E002+1) -#define SKERR_I2C_E003MSG "LM80: NAK on device send" -#define SKERR_I2C_E004 (SKERR_I2C_E003+1) -#define SKERR_I2C_E004MSG "LM80: NAK on register send" -#define SKERR_I2C_E005 (SKERR_I2C_E004+1) -#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send" -#define SKERR_I2C_E006 (SKERR_I2C_E005+1) -#define SKERR_I2C_E006MSG "Unknown event" -#define SKERR_I2C_E007 (SKERR_I2C_E006+1) -#define SKERR_I2C_E007MSG "LM80 read out of state" -#define SKERR_I2C_E008 (SKERR_I2C_E007+1) -#define SKERR_I2C_E008MSG "Unexpected sensor read completed" -#define SKERR_I2C_E009 (SKERR_I2C_E008+1) -#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range" -#define SKERR_I2C_E010 (SKERR_I2C_E009+1) -#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range" -#define SKERR_I2C_E011 (SKERR_I2C_E010+1) -#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range" -#define SKERR_I2C_E012 (SKERR_I2C_E011+1) -#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range" -#define SKERR_I2C_E013 (SKERR_I2C_E012+1) -#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor" -#define SKERR_I2C_E014 (SKERR_I2C_E013+1) -#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range" -#define SKERR_I2C_E015 (SKERR_I2C_E014+1) -#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range" -#define SKERR_I2C_E016 (SKERR_I2C_E015+1) -#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete" - -/* - * Define Timeout values - */ -#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */ -#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */ -#define SK_I2C_TIM_WATCH 1000000L /* 1 second */ - -/* - * Define trap and error log hold times - */ -#ifndef SK_SEN_ERR_TR_HOLD -#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_ERR_LOG_HOLD -#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_WARN_TR_HOLD -#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_WARN_LOG_HOLD -#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC) -#endif - -/* - * Defines for SenType - */ -#define SK_SEN_UNKNOWN 0 -#define SK_SEN_TEMP 1 -#define SK_SEN_VOLT 2 -#define SK_SEN_FAN 3 - -/* - * Define for the SenErrorFlag - */ -#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */ -#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */ -#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */ -#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */ -#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */ - -/* - * Define the Sensor struct - */ -struct s_Sensor { - char *SenDesc; /* Description */ - int SenType; /* Voltage or Temperature */ - SK_I32 SenValue; /* Current value of the sensor */ - SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */ - SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */ - SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */ - SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ - int SenErrFlag; /* Sensor indicated an error */ - SK_BOOL SenInit; /* Is sensor initialized ? */ - SK_U64 SenErrCts; /* Error trap counter */ - SK_U64 SenWarnCts; /* Warning trap counter */ - SK_U64 SenBegErrTS; /* Begin error timestamp */ - SK_U64 SenBegWarnTS; /* Begin warning timestamp */ - SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */ - SK_U64 SenLastErrLogTS; /* Last error log timestamp */ - SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */ - SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */ - int SenState; /* Sensor State (see HW specific include) */ - int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen); - /* Sensors read function */ - SK_U16 SenReg; /* Register Address for this sensor */ - SK_U8 SenDev; /* Device Selection for this sensor */ -}; - -typedef struct s_I2c { - SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */ - int CurrSens; /* Which sensor is currently queried */ - int MaxSens; /* Max. number of sensors */ - int TimerMode; /* Use the timer also to watch the state machine */ - int InitLevel; /* Initialized Level */ -#ifndef SK_DIAG - int DummyReads; /* Number of non-checked dummy reads */ - SK_TIMER SenTimer; /* Sensors timer */ -#endif /* !SK_DIAG */ -} SK_I2C; - -extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); -#ifdef SK_DIAG -extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, - int Burst); -#else /* !SK_DIAG */ -extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); -extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); -#endif /* !SK_DIAG */ -#endif /* n_SKI2C_H */ - diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h deleted file mode 100644 index 2ec40d4fdf60..000000000000 --- a/drivers/net/sk98lin/h/skqueue.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Name: skqueue.h - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.16 $ - * Date: $Date: 2003/09/16 12:50:32 $ - * Purpose: Defines for the Event queue - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKQUEUE.H contains all defines and types for the event queue - */ - -#ifndef _SKQUEUE_H_ -#define _SKQUEUE_H_ - - -/* - * define the event classes to be served - */ -#define SKGE_DRV 1 /* Driver Event Class */ -#define SKGE_RLMT 2 /* RLMT Event Class */ -#define SKGE_I2C 3 /* I2C Event Class */ -#define SKGE_PNMI 4 /* PNMI Event Class */ -#define SKGE_CSUM 5 /* Checksum Event Class */ -#define SKGE_HWAC 6 /* Hardware Access Event Class */ - -#define SKGE_SWT 9 /* Software Timer Event Class */ -#define SKGE_LACP 10 /* LACP Aggregation Event Class */ -#define SKGE_RSF 11 /* RSF Aggregation Event Class */ -#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */ -#define SKGE_FD 13 /* FD Distributor Event Class */ - -/* - * define event queue as circular buffer - */ -#define SK_MAX_EVENT 64 - -/* - * Parameter union for the Para stuff - */ -typedef union u_EvPara { - void *pParaPtr; /* Parameter Pointer */ - SK_U64 Para64; /* Parameter 64bit version */ - SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */ -} SK_EVPARA; - -/* - * Event Queue - * skqueue.c - * events are class/value pairs - * class is addressee, e.g. RLMT, PNMI etc. - * value is command, e.g. line state change, ring op change etc. - */ -typedef struct s_EventElem { - SK_U32 Class; /* Event class */ - SK_U32 Event; /* Event value */ - SK_EVPARA Para; /* Event parameter */ -} SK_EVENTELEM; - -typedef struct s_Queue { - SK_EVENTELEM EvQueue[SK_MAX_EVENT]; - SK_EVENTELEM *EvPut; - SK_EVENTELEM *EvGet; -} SK_QUEUE; - -extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level); -extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event, - SK_EVPARA Para); -extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc); - - -/* Define Error Numbers and messages */ -#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0) -#define SKERR_Q_E001MSG "Event queue overflow" -#define SKERR_Q_E002 (SKERR_Q_E001+1) -#define SKERR_Q_E002MSG "Undefined event class" -#endif /* _SKQUEUE_H_ */ - diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h deleted file mode 100644 index ca75dfdcf2d6..000000000000 --- a/drivers/net/sk98lin/h/skrlmt.h +++ /dev/null @@ -1,438 +0,0 @@ -/****************************************************************************** - * - * Name: skrlmt.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.37 $ - * Date: $Date: 2003/04/15 09:43:43 $ - * Purpose: Header file for Redundant Link ManagemenT. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This is the header file for Redundant Link ManagemenT. - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * ... - * "sktypes.h" - * "skqueue.h" - * "skaddr.h" - * "skrlmt.h" - * ... - * "skdrv2nd.h" - * - ******************************************************************************/ - -#ifndef __INC_SKRLMT_H -#define __INC_SKRLMT_H - -#ifdef __cplusplus -extern "C" { -#endif /* cplusplus */ - -/* defines ********************************************************************/ - -#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */ -#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */ - -/* ----- Default queue sizes - must be multiples of 8 KB ----- */ - -/* Less than 8 KB free in RX queue => pause frames. */ -#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */ -#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */ -#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */ - -#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */ - -/* ----- PORT states ----- */ - -#define SK_RLMT_PS_INIT 0 /* Port state: Init. */ -#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */ -#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */ -#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */ -#define SK_RLMT_PS_UP 4 /* Port state: Up. */ - -/* ----- RLMT states ----- */ - -#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */ -#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */ -#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */ - -/* ----- PORT events ----- */ - -#define SK_RLMT_LINK_UP 1001 /* Link came up. */ -#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */ -#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */ - -/* ----- RLMT events ----- */ - -#define SK_RLMT_START 2001 /* Start RLMT. */ -#define SK_RLMT_STOP 2002 /* Stop RLMT. */ -#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */ -#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */ -#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */ -#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */ -#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */ -#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */ - -/* ----- RLMT mode bits ----- */ - -/* - * CAUTION: These defines are private to RLMT. - * Please use the RLMT mode defines below. - */ - -#define SK_RLMT_CHECK_LINK 1 /* Check Link. */ -#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */ -#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */ - -#ifndef RLMT_CHECK_REMOTE -#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK -#else /* RLMT_CHECK_REMOTE */ -#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */ -#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3 -#define SK_RLMT_CHECK_OTHERS \ - (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK) -#endif /* RLMT_CHECK_REMOTE */ - -#ifndef SK_RLMT_ENABLE_TRANSPARENT -#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */ -#else /* SK_RLMT_ENABLE_TRANSPARENT */ -#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */ -#endif /* SK_RLMT_ENABLE_TRANSPARENT */ - -/* ----- RLMT modes ----- */ - -/* Check Link State. */ -#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK) - -/* Check Local Ports: check other links on the same adapter. */ -#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK) - -/* Check Local Ports and Segmentation Status. */ -#define SK_RLMT_MODE_CLPSS \ - (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG) - -#ifdef RLMT_CHECK_REMOTE -/* Check Local and Remote Ports: check links (local or remote). */ - Name of define TBD! -#define SK_RLMT_MODE_CRP \ - (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK) - -/* Check Local and Remote Ports and Segmentation Status. */ - Name of define TBD! -#define SK_RLMT_MODE_CRPSS \ - (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \ - SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG) -#endif /* RLMT_CHECK_REMOTE */ - -/* ----- RLMT lookahead result bits ----- */ - -#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */ -#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */ - -/* Macros */ - -#if 0 -SK_AC *pAC /* adapter context */ -SK_U32 PortNum /* receiving port */ -unsigned PktLen /* received packet's length */ -SK_BOOL IsBc /* Flag: packet is broadcast */ -unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */ -unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */ -#endif /* 0 */ - -#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \ - SK_AC *_pAC; \ - SK_U32 _PortNum; \ - _pAC = (pAC); \ - _PortNum = (SK_U32)(PortNum); \ - /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \ - _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \ - if (_pAC->Rlmt.RlmtOff) { \ - *(pNumBytes) = 0; \ - } \ - else {\ - if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \ - *(pNumBytes) = 0; \ - } \ - else if (IsBc) { \ - if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \ - *(pNumBytes) = 6; \ - *(pOffset) = 6; \ - } \ - else { \ - *(pNumBytes) = 0; \ - } \ - } \ - else { \ - if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \ - /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ - *(pNumBytes) = 0; \ - } \ - else { \ - *(pNumBytes) = 6; \ - *(pOffset) = 0; \ - } \ - } \ - } \ -} - -#if 0 -SK_AC *pAC /* adapter context */ -SK_U32 PortNum /* receiving port */ -SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */ -SK_BOOL IsBc /* Flag: packet is broadcast */ -SK_BOOL IsMc /* Flag: packet is multicast */ -unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */ -SK_RLMT_LOOKAHEAD() expects *pNumBytes from -packet offset *pOffset (s.a.) at *pLaPacket. - -If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is -BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler -can trash unneeded parts of the if construction. -#endif /* 0 */ - -#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \ - SK_AC *_pAC; \ - SK_U32 _PortNum; \ - SK_U8 *_pLaPacket; \ - _pAC = (pAC); \ - _PortNum = (SK_U32)(PortNum); \ - _pLaPacket = (SK_U8 *)(pLaPacket); \ - if (IsBc) {\ - if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \ - _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \ - _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \ - _pAC->Rlmt.CheckSwitch = SK_TRUE; \ - } \ - /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ - *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \ - } \ - else if (IsMc) { \ - if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \ - _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \ - if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \ - *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \ - } \ - else { \ - *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \ - } \ - } \ - else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \ - *(pForRlmt) = SK_RLMT_RX_RLMT; \ - } \ - else { \ - /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ - *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \ - } \ - } \ - else { \ - if (SK_ADDR_EQUAL( \ - _pLaPacket, \ - _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \ - *(pForRlmt) = SK_RLMT_RX_RLMT; \ - } \ - else { \ - /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \ - *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \ - } \ - } \ -} - -#ifdef SK_RLMT_FAST_LOOKAHEAD -Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead. -#endif /* SK_RLMT_FAST_LOOKAHEAD */ -#ifdef SK_RLMT_SLOW_LOOKAHEAD -Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead. -#endif /* SK_RLMT_SLOW_LOOKAHEAD */ - -/* typedefs *******************************************************************/ - -#ifdef SK_RLMT_MBUF_PRIVATE -typedef struct s_RlmtMbuf { - some content -} SK_RLMT_MBUF; -#endif /* SK_RLMT_MBUF_PRIVATE */ - - -#ifdef SK_LA_INFO -typedef struct s_Rlmt_PacketInfo { - unsigned PacketLength; /* Length of packet. */ - unsigned PacketType; /* Directed/Multicast/Broadcast. */ -} SK_RLMT_PINFO; -#endif /* SK_LA_INFO */ - - -typedef struct s_RootId { - SK_U8 Id[8]; /* Root Bridge Id. */ -} SK_RLMT_ROOT_ID; - - -typedef struct s_port { - SK_MAC_ADDR CheckAddr; - SK_BOOL SuspectTx; -} SK_PORT_CHECK; - - -typedef struct s_RlmtNet SK_RLMT_NET; - - -typedef struct s_RlmtPort { - -/* ----- Public part (read-only) ----- */ - - SK_U8 PortState; /* Current state of this port. */ - - /* For PNMI */ - SK_BOOL LinkDown; - SK_BOOL PortDown; - SK_U8 Align01; - - SK_U32 PortNumber; /* Number of port on adapter. */ - SK_RLMT_NET * Net; /* Net port belongs to. */ - - SK_U64 TxHelloCts; - SK_U64 RxHelloCts; - SK_U64 TxSpHelloReqCts; - SK_U64 RxSpHelloCts; - -/* ----- Private part ----- */ - -/* SK_U64 PacketsRx; */ /* Total packets received. */ - SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */ -/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */ - SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */ - SK_U64 BcTimeStamp; /* Time of last BC receive. */ - SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */ - - SK_TIMER UpTimer; /* Timer struct Link/Port up. */ - SK_TIMER DownRxTimer; /* Timer struct down rx. */ - SK_TIMER DownTxTimer; /* Timer struct down tx. */ - - SK_U32 CheckingState; /* Checking State. */ - - SK_ADDR_PORT * AddrPort; - - SK_U8 Random[4]; /* Random value. */ - unsigned PortsChecked; /* #ports checked. */ - unsigned PortsSuspect; /* #ports checked that are s. */ - SK_PORT_CHECK PortCheck[1]; -/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */ - - SK_BOOL PortStarted; /* Port is started. */ - SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */ - SK_BOOL RootIdSet; - SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */ -} SK_RLMT_PORT; - - -struct s_RlmtNet { - -/* ----- Public part (read-only) ----- */ - - SK_U32 NetNumber; /* Number of net. */ - - SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */ - SK_U32 NumPorts; /* Number of ports. */ - SK_U32 PrefPort; /* Preferred port. */ - - /* For PNMI */ - - SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */ - SK_U32 RlmtMode; /* Check ... */ - SK_U32 ActivePort; /* Active port. */ - SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */ - - SK_U8 RlmtState; /* Current RLMT state. */ - -/* ----- Private part ----- */ - SK_BOOL RootIdSet; - SK_U16 Align01; - - int LinksUp; /* #Links up. */ - int PortsUp; /* #Ports up. */ - SK_U32 TimeoutValue; /* RLMT timeout value. */ - - SK_U32 CheckingState; /* Checking State. */ - SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */ - - SK_TIMER LocTimer; /* Timer struct. */ - SK_TIMER SegTimer; /* Timer struct. */ -}; - - -typedef struct s_Rlmt { - -/* ----- Public part (read-only) ----- */ - - SK_U32 NumNets; /* Number of nets. */ - SK_U32 NetsStarted; /* Number of nets started. */ - SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */ - SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */ - -/* ----- Private part ----- */ - SK_BOOL CheckSwitch; - SK_BOOL RlmtOff; /* set to zero if the Mac addresses - are equal or the second one - is zero */ - SK_U16 Align01; - -} SK_RLMT; - - -extern SK_MAC_ADDR BridgeMcAddr; -extern SK_MAC_ADDR SkRlmtMcAddr; - -/* function prototypes ********************************************************/ - - -#ifndef SK_KR_PROTO - -/* Functions provided by SkRlmt */ - -/* ANSI/C++ compliant function prototypes */ - -extern void SkRlmtInit( - SK_AC *pAC, - SK_IOC IoC, - int Level); - -extern int SkRlmtEvent( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 Event, - SK_EVPARA Para); - -#else /* defined(SK_KR_PROTO) */ - -/* Non-ANSI/C++ compliant function prototypes */ - -#error KR-style function prototypes are not yet provided. - -#endif /* defined(SK_KR_PROTO)) */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_SKRLMT_H */ diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h deleted file mode 100644 index 04e6d7c1ec33..000000000000 --- a/drivers/net/sk98lin/h/sktimer.h +++ /dev/null @@ -1,63 +0,0 @@ -/****************************************************************************** - * - * Name: sktimer.h - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.11 $ - * Date: $Date: 2003/09/16 12:58:18 $ - * Purpose: Defines for the timer functions - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKTIMER.H contains all defines and types for the timer functions - */ - -#ifndef _SKTIMER_H_ -#define _SKTIMER_H_ - -#include "h/skqueue.h" - -/* - * SK timer - * - needed wherever a timer is used. Put this in your data structure - * wherever you want. - */ -typedef struct s_Timer SK_TIMER; - -struct s_Timer { - SK_TIMER *TmNext; /* linked list */ - SK_U32 TmClass; /* Timer Event class */ - SK_U32 TmEvent; /* Timer Event value */ - SK_EVPARA TmPara; /* Timer Event parameter */ - SK_U32 TmDelta; /* delta time */ - int TmActive; /* flag: active/inactive */ -}; - -/* - * Timer control struct. - * - use in Adapters context name pAC->Tim - */ -typedef struct s_TimCtrl { - SK_TIMER *StQueue; /* Head of Timer queue */ -} SK_TIMCTRL; - -extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level); -extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer); -extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer, - SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para); -extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc); -#endif /* _SKTIMER_H_ */ diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h deleted file mode 100644 index 40edc96e1055..000000000000 --- a/drivers/net/sk98lin/h/sktypes.h +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** - * - * Name: sktypes.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.2 $ - * Date: $Date: 2003/10/07 08:16:51 $ - * Purpose: Define data types for Linux - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * In this file, all data types that are needed by the common modules - * are mapped to Linux data types. - * - * - * Include File Hierarchy: - * - * - ******************************************************************************/ - -#ifndef __INC_SKTYPES_H -#define __INC_SKTYPES_H - - -/* defines *******************************************************************/ - -/* - * Data types with a specific size. 'I' = signed, 'U' = unsigned. - */ -#define SK_I8 s8 -#define SK_U8 u8 -#define SK_I16 s16 -#define SK_U16 u16 -#define SK_I32 s32 -#define SK_U32 u32 -#define SK_I64 s64 -#define SK_U64 u64 - -#define SK_UPTR ulong /* casting pointer <-> integral */ - -/* -* Boolean type. -*/ -#define SK_BOOL SK_U8 -#define SK_FALSE 0 -#define SK_TRUE (!SK_FALSE) - -/* typedefs *******************************************************************/ - -/* function prototypes ********************************************************/ - -#endif /* __INC_SKTYPES_H */ diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h deleted file mode 100644 index a1a7294828e5..000000000000 --- a/drivers/net/sk98lin/h/skversion.h +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - * - * Name: version.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.5 $ - * Date: $Date: 2003/10/07 08:16:51 $ - * Purpose: SK specific Error log support - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifdef lint -static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; -static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.23 PL: 01"; -#endif /* !defined(lint) */ - -#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \ - "(C)Copyright 1999-2004 Marvell(R)." - -#define VER_STRING "6.23" -#define DRIVER_FILE_NAME "sk98lin" -#define DRIVER_REL_DATE "Feb-13-2004" - - diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h deleted file mode 100644 index fdd9e48e8040..000000000000 --- a/drivers/net/sk98lin/h/skvpd.h +++ /dev/null @@ -1,248 +0,0 @@ -/****************************************************************************** - * - * Name: skvpd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.15 $ - * Date: $Date: 2003/01/13 10:39:38 $ - * Purpose: Defines and Macros for VPD handling - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2003 SysKonnect GmbH. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * skvpd.h contains Diagnostic specific defines for VPD handling - */ - -#ifndef __INC_SKVPD_H_ -#define __INC_SKVPD_H_ - -/* - * Define Resource Type Identifiers and VPD keywords - */ -#define RES_ID 0x82 /* Resource Type ID String (Product Name) */ -#define RES_VPD_R 0x90 /* start of VPD read only area */ -#define RES_VPD_W 0x91 /* start of VPD read/write area */ -#define RES_END 0x78 /* Resource Type End Tag */ - -#ifndef VPD_NAME -#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */ -#endif /* VPD_NAME */ -#define VPD_PN "PN" /* Adapter Part Number */ -#define VPD_EC "EC" /* Adapter Engineering Level */ -#define VPD_MN "MN" /* Manufacture ID */ -#define VPD_SN "SN" /* Serial Number */ -#define VPD_CP "CP" /* Extended Capability */ -#define VPD_RV "RV" /* Checksum and Reserved */ -#define VPD_YA "YA" /* Asset Tag Identifier */ -#define VPD_VL "VL" /* First Error Log Message (SK specific) */ -#define VPD_VF "VF" /* Second Error Log Message (SK specific) */ -#define VPD_RW "RW" /* Remaining Read / Write Area */ - -/* 'type' values for vpd_setup_para() */ -#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */ -#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */ - -/* 'op' values for vpd_setup_para() */ -#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */ -#define OWR_KEY 2 /* overwrite key if already exists */ - -/* - * Define READ and WRITE Constants. - */ - -#define VPD_DEV_ID_GENESIS 0x4300 - -#define VPD_SIZE_YUKON 256 -#define VPD_SIZE_GENESIS 512 -#define VPD_SIZE 512 -#define VPD_READ 0x0000 -#define VPD_WRITE 0x8000 - -#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE) - -#define VPD_GET_RES_LEN(p) ((unsigned int) \ - (* (SK_U8 *)&(p)[1]) |\ - ((* (SK_U8 *)&(p)[2]) << 8)) -#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2])) -#define VPD_GET_VAL(p) ((char *)&(p)[3]) - -#define VPD_MAX_LEN 50 - -/* VPD status */ - /* bit 7..1 reserved */ -#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */ - /* and vpd_free_rw valid */ - -/* - * VPD structs - */ -typedef struct s_vpd_status { - unsigned short Align01; /* Alignment */ - unsigned short vpd_status; /* VPD status, description see above */ - int vpd_free_ro; /* unused bytes in read only area */ - int vpd_free_rw; /* bytes available in read/write area */ -} SK_VPD_STATUS; - -typedef struct s_vpd { - SK_VPD_STATUS v; /* VPD status structure */ - char vpd_buf[VPD_SIZE]; /* VPD buffer */ - int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */ - int vpd_size; /* saved VPD-size */ -} SK_VPD; - -typedef struct s_vpd_para { - unsigned int p_len; /* parameter length */ - char *p_val; /* points to the value */ -} SK_VPD_PARA; - -/* - * structure of Large Resource Type Identifiers - */ - -/* was removed because of alignment problems */ - -/* - * structure of VPD keywords - */ -typedef struct s_vpd_key { - char p_key[2]; /* 2 bytes ID string */ - unsigned char p_len; /* 1 byte length */ - char p_val; /* start of the value string */ -} SK_VPD_KEY; - - -/* - * System specific VPD macros - */ -#ifndef SKDIAG -#ifndef VPD_DO_IO -#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val) -#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val) -#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal) -#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal) -#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal) -#else /* VPD_DO_IO */ -#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val) -#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val) -#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal) -#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal) -#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal) -#endif /* VPD_DO_IO */ -#else /* SKDIAG */ -#define VPD_OUT8(pAC,Ioc,Addr,Val) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciWriteCfgByte(pAC,Addr,Val); \ - else \ - SK_OUT8(pAC,PCI_C(Addr),Val); \ - } -#define VPD_OUT16(pAC,Ioc,Addr,Val) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciWriteCfgWord(pAC,Addr,Val); \ - else \ - SK_OUT16(pAC,PCI_C(Addr),Val); \ - } -#define VPD_IN8(pAC,Ioc,Addr,pVal) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgByte(pAC,Addr,pVal); \ - else \ - SK_IN8(pAC,PCI_C(Addr),pVal); \ - } -#define VPD_IN16(pAC,Ioc,Addr,pVal) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgWord(pAC,Addr,pVal); \ - else \ - SK_IN16(pAC,PCI_C(Addr),pVal); \ - } -#define VPD_IN32(pAC,Ioc,Addr,pVal) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ - SkPciReadCfgDWord(pAC,Addr,pVal); \ - else \ - SK_IN32(pAC,PCI_C(Addr),pVal); \ - } -#endif /* nSKDIAG */ - -/* function prototypes ********************************************************/ - -#ifndef SK_KR_PROTO -#ifdef SKDIAG -extern SK_U32 VpdReadDWord( - SK_AC *pAC, - SK_IOC IoC, - int addr); -#endif /* SKDIAG */ - -extern SK_VPD_STATUS *VpdStat( - SK_AC *pAC, - SK_IOC IoC); - -extern int VpdKeys( - SK_AC *pAC, - SK_IOC IoC, - char *buf, - int *len, - int *elements); - -extern int VpdRead( - SK_AC *pAC, - SK_IOC IoC, - const char *key, - char *buf, - int *len); - -extern SK_BOOL VpdMayWrite( - char *key); - -extern int VpdWrite( - SK_AC *pAC, - SK_IOC IoC, - const char *key, - const char *buf); - -extern int VpdDelete( - SK_AC *pAC, - SK_IOC IoC, - char *key); - -extern int VpdUpdate( - SK_AC *pAC, - SK_IOC IoC); - -#ifdef SKDIAG -extern int VpdReadBlock( - SK_AC *pAC, - SK_IOC IoC, - char *buf, - int addr, - int len); - -extern int VpdWriteBlock( - SK_AC *pAC, - SK_IOC IoC, - char *buf, - int addr, - int len); -#endif /* SKDIAG */ -#else /* SK_KR_PROTO */ -extern SK_U32 VpdReadDWord(); -extern SK_VPD_STATUS *VpdStat(); -extern int VpdKeys(); -extern int VpdRead(); -extern SK_BOOL VpdMayWrite(); -extern int VpdWrite(); -extern int VpdDelete(); -extern int VpdUpdate(); -#endif /* SK_KR_PROTO */ - -#endif /* __INC_SKVPD_H_ */ diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h deleted file mode 100644 index 7f8e6d0084c7..000000000000 --- a/drivers/net/sk98lin/h/xmac_ii.h +++ /dev/null @@ -1,1579 +0,0 @@ -/****************************************************************************** - * - * Name: xmac_ii.h - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.52 $ - * Date: $Date: 2003/10/02 16:35:50 $ - * Purpose: Defines and Macros for Gigabit Ethernet Controller - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef __INC_XMAC_H -#define __INC_XMAC_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* defines ********************************************************************/ - -/* - * XMAC II registers - * - * The XMAC registers are 16 or 32 bits wide. - * The XMACs host processor interface is set to 16 bit mode, - * therefore ALL registers will be addressed with 16 bit accesses. - * - * The following macros are provided to access the XMAC registers - * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(), - * XM_INHASH(), and XM_OUTHASH(). - * The macros are defined in SkGeHw.h. - * - * Note: NA reg = Network Address e.g DA, SA etc. - * - */ -#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */ - /* 0x0004: reserved */ -#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */ -#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/ -#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */ -#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */ - /* 0x0018 - 0x001e: reserved */ -#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */ -#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */ -#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */ -#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */ -#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */ -#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */ -#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */ - /* 0x003c: reserved */ -#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */ -#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */ -#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */ -#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */ - /* 0x0050 - 0x005e: reserved */ -#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */ -#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */ -#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */ -#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */ -#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */ - /* 0x006e: reserved */ -#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */ -#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */ -#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/ -#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */ - - /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */ - /* use the XM_EXM() macro to address */ -#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */ - - /* - * XM_EXM(Reg) - * - * returns the XMAC address offset of specified Exact Match Addr Reg - * - * para: Reg EXM register to addr (0 .. 15) - * - * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]); - */ -#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3)) - -#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */ -#define XM_SA 0x0108 /* NA reg r/w Station Address Register */ -#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */ -#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */ -#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */ -#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */ -#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */ -#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */ -#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */ - /* 0x012e: reserved */ -#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */ -#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */ - /* 0x0138 - 0x01fe: reserved */ -#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */ -#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */ -#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */ -#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */ -#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */ - /* 0x0204 - 0x027e: reserved */ -#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */ -#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/ -#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */ -#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */ -#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */ -#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */ -#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */ -#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */ -#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */ -#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */ -#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */ -#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */ -#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */ -#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */ -#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */ -#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */ -#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */ -#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */ -#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */ - /* 0x02cc - 0x02ce: reserved */ -#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */ -#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */ -#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */ -#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */ -#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/ -#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/ - /* 0x02e8 - 0x02fe: reserved */ -#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */ -#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */ -#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/ -#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */ -#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */ -#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */ -#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */ -#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */ -#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */ -#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/ -#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */ -#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */ -#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */ -#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */ -#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */ -#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */ -#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */ -#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */ -#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */ -#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */ -#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */ -#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */ - /* 0x0358 - 0x035a: reserved */ -#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/ -#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */ - /* 0x0364 - 0x0366: reserved */ -#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */ -#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */ -#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */ -#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */ -#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/ -#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/ - /* 0x02e8 - 0x02fe: reserved */ - - -/*----------------------------------------------------------------------------*/ -/* - * XMAC Bit Definitions - * - * If the bit access behaviour differs from the register access behaviour - * (r/w, r/o) this is documented after the bit number. - * The following bit access behaviours are used: - * (sc) self clearing - * (ro) read only - */ - -/* XM_MMU_CMD 16 bit r/w MMU Command Register */ - /* Bit 15..13: reserved */ -#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */ -#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */ -#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */ -#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */ - /* Bit 8: reserved */ -#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */ -#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */ -#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */ -#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */ -#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */ -#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */ -#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */ -#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */ - - -/* XM_TX_CMD 16 bit r/w Transmit Command Register */ - /* Bit 15..7: reserved */ -#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/ -#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */ -#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */ -#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */ -#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */ -#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */ -#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */ - - -/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */ - /* Bit 15..5: reserved */ -#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */ - - -/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */ - /* Bit 15..7: reserved */ -#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */ - - -/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */ - /* Bit 15..8: reserved */ -#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */ - - -/* XM_RX_CMD 16 bit r/w Receive Command Register */ - /* Bit 15..9: reserved */ -#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */ - /* inrange error packets */ -#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */ - /* jumbo packets */ -#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */ -#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */ -#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */ -#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */ -#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */ -#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */ -#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */ - - -/* XM_PHY_ADDR 16 bit r/w PHY Address Register */ - /* Bit 15..5: reserved */ -#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ - - -/* XM_GP_PORT 32 bit r/w General Purpose Port Register */ - /* Bit 31..7: reserved */ -#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */ -#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */ - /* Bit 4: reserved */ -#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */ -#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */ - /* Bit 1: reserved */ -#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */ - - -/* XM_IMSK 16 bit r/w Interrupt Mask Register */ -/* XM_ISRC 16 bit r/o Interrupt Status Register */ - /* Bit 15: reserved */ -#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */ -#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */ -#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */ -#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */ -#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */ -#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */ -#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */ -#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */ -#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */ -#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */ -#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */ -#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */ -#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */ -#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */ -#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */ - -#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\ - XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR)) - - -/* XM_HW_CFG 16 bit r/w Hardware Config Register */ - /* Bit 15.. 4: reserved */ -#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */ -#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/ - /* Bit 1: reserved */ -#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */ - - -/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */ -/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */ - /* Bit 15..10 reserved */ -#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */ - -/* XM_TX_THR 16 bit r/w Tx Request Threshold */ -/* XM_HT_THR 16 bit r/w Host Request Threshold */ -/* XM_RX_THR 16 bit r/w Rx Request Threshold */ - /* Bit 15..11 reserved */ -#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */ - - -/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */ -#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */ -#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */ -#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */ -#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */ -#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */ -#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/ -#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */ -#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */ -#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */ -#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */ -#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */ -#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */ -#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */ -#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */ -#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */ - -/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */ -/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */ - /* Bit 15..11: reserved */ -#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */ - - -/* XM_DEV_ID 32 bit r/o Device ID Register */ -#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */ -#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */ - - -/* XM_MODE 32 bit r/w Mode Register */ - /* Bit 31..27: reserved */ -#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */ -#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */ - /* extern generated */ -#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */ -#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */ - /* intern generated */ -#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */ -#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */ -#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */ -#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */ -#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */ - /* intern generated */ -#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */ - /* intern generated */ -#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */ -#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */ -#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */ -#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */ -#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */ -#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */ -#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */ -#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */ -#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */ -#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */ -#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */ -#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */ -#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */ -#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */ -#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */ -#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */ -#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */ - -#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) -#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ - XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) - -/* XM_STAT_CMD 16 bit r/w Statistics Command Register */ - /* Bit 16..6: reserved */ -#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */ -#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */ -#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */ -#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */ -#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */ -#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */ - - -/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */ -/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */ -#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/ -#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/ -#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/ -#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/ -#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */ -#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */ -#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */ -#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */ -#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */ - /* Bit 22: reserved */ -#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */ -#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/ -#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */ -#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/ -#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */ - /* Bit 16: reserved */ -#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */ -#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */ -#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */ -#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */ -#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */ -#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */ -#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/ -#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */ -#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */ -#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/ -#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/ -#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */ -#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */ -#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/ -#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/ -#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */ - -#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV) - -/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */ -/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */ - /* Bit 31..26: reserved */ -#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/ -#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/ -#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/ -#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/ -#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */ -#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */ -#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */ -#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */ -#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/ -#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */ -#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */ -#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */ -#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */ -#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/ -#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */ -#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */ -#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/ -#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/ -#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */ -#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */ -#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */ -#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */ -#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */ -#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/ -#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/ -#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */ - -#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV) - -/* - * Receive Frame Status Encoding - */ -#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */ -#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/ -#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/ -#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */ -#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */ -#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */ - /* Bit 12: reserved */ -#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */ -#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */ -#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */ -#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */ -#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */ -#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */ -#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */ -#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */ -#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */ -#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */ -#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */ -#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */ - -/* - * XMR_FS_ERR will be set if - * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT, - * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR - * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue - * XMR_FS_ERR unless the corresponding bit in the Receive Command - * Register is set. - */ -#define XMR_FS_ANY_ERR XMR_FS_ERR - -/*----------------------------------------------------------------------------*/ -/* - * XMAC-PHY Registers, indirect addressed over the XMAC - */ -#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */ -#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ -#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ -#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */ -#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ -#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ - /* 0x09 - 0x0e: reserved */ -#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */ -#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */ - -/*----------------------------------------------------------------------------*/ -/* - * Broadcom-PHY Registers, indirect addressed over XMAC - */ -#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */ -#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ -#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ -#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ -#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ -#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ - /* Broadcom-specific registers */ -#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ -#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b - 0x0e: reserved */ -#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ -#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */ -#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */ -#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */ -#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */ -#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */ - /* 0x15 - 0x17: reserved */ -#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */ -#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */ -#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */ -#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */ - /* 0x1c: reserved */ - /* 0x1d - 0x1f: test registers */ - -/*----------------------------------------------------------------------------*/ -/* - * Marvel-PHY Registers, indirect addressed over GMAC - */ -#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */ -#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ -#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ -#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ -#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ -#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ - /* Marvel-specific registers */ -#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ -#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b - 0x0e: reserved */ -#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ -#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */ -#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */ -#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */ -#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */ -#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */ -#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */ -#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */ - /* 0x17: reserved */ -#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */ -#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */ -#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */ -#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */ -#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */ - /* 0x1d - 0x1f: reserved */ - -/*----------------------------------------------------------------------------*/ -/* - * Level One-PHY Registers, indirect addressed over XMAC - */ -#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */ -#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ -#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ -#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */ -#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ -#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ - /* Level One-specific registers */ -#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ -#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b -0x0e: reserved */ -#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ -#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/ -#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */ -#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */ -#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */ -#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */ -#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */ -#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */ - /* 0x17 -0x1c: reserved */ - -/*----------------------------------------------------------------------------*/ -/* - * National-PHY Registers, indirect addressed over XMAC - */ -#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */ -#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */ -#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ -#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ -#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */ -#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ -#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */ -#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */ - /* National-specific registers */ -#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ -#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b -0x0e: reserved */ -#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */ -#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */ -#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */ -#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */ -#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */ -#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */ - /* 0x15 -0x18: reserved */ -#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */ - - -/*----------------------------------------------------------------------------*/ - -/* - * PHY bit definitions - * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are - * XMAC/Broadcom/LevelOne/National/Marvell-specific. - * All other are general. - */ - -/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/ -/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/ -/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/ -/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ -#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */ -#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */ -#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */ -#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */ -#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */ -#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */ -#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */ -#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */ -#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */ -#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */ - /* Bit 5..0: reserved */ - -#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */ -#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */ -#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */ - - -/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/ -/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/ -/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/ -/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/ - /* Bit 15..9: reserved */ - /* (BC/L1) 100/10 Mbps cap bits ignored*/ -#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */ - /* Bit 7: reserved */ -#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */ -#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */ -#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */ -#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */ -#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */ -#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */ -#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */ - - -/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */ -#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */ -#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */ -#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */ - -/* different Broadcom PHY Ids */ -#define PHY_BCOM_ID1_A1 0x6041 -#define PHY_BCOM_ID1_B2 0x6043 -#define PHY_BCOM_ID1_C0 0x6044 -#define PHY_BCOM_ID1_C5 0x6047 - - -/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ -/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */ -#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */ -#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */ - /* Bit 11.. 9: reserved */ -#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */ -#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */ -#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */ - /* Bit 4.. 0: reserved */ - -/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ -/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ - /* Bit 14: reserved */ -#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */ - /* Bit 12: reserved */ -#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */ -#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ - -/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ -/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ - /* Bit 14: reserved */ -#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */ - /* Bit 12: reserved */ -#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */ -#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ - -/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ -/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ - /* Bit 14: reserved */ -#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */ - /* Bit 12: reserved */ -#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */ -#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */ - /* Bit 9..5: 100/10 BT cap bits ingnored */ -#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/ - -/* field type definition for PHY_x_AN_SEL */ -#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */ - -/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ - /* Bit 15..4: reserved */ -#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */ -#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */ -#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */ - /* Bit 0: reserved */ - -/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ -/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ -/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/ - /* Bit 15..5: reserved */ -#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */ -/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */ -/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */ -/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */ -#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */ - -/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/ -/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/ -/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/ -/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/ -#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */ -#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */ -#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */ -#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */ -#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */ -#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */ - -/* - * XMAC-Specific - */ -/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/ -#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */ -#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */ - /* Bit 13..0: reserved */ - -/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/ - /* Bit 15..9: reserved */ -#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */ -#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */ -#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */ -#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */ -#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */ - /* Bit 2..0: reserved */ -/* - * Remote Fault Bits (PHY_X_AN_RFB) encoding - */ -#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */ -#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */ -#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */ -#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */ - -/* - * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding - */ -#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */ -#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */ -#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */ -#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */ - - -/* - * Broadcom-Specific - */ -/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ - /* Bit 7..0: reserved */ - -/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */ -#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ - /* Bit 9..8: reserved */ -#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ - -/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/ -#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ -#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ -#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ -#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */ - /* Bit 11..0: reserved */ - -/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/ -#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */ -#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */ -#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */ -#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */ -#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */ -#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */ -#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */ -#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */ -#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */ -#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */ -#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */ -#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */ -#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */ -#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */ -#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */ -#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */ - -/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/ - /* Bit 15..14: reserved */ -#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */ -#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */ -#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */ -#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */ -#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */ -#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */ -#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */ -#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */ -#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */ -#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */ -#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */ -#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */ -#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */ -#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */ - -/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ - /* Bit 15..8: reserved */ -#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */ - -/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/ -#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */ -#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */ - -/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/ -#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */ -#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */ -#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */ - /* Bit 11: reserved */ -#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */ - /* Bit 9.. 8: reserved */ -#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */ - /* Bit 6: reserved */ -#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */ - /* Bit 4: reserved */ -#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */ - /* Bit 2.. 0: reserved */ - -/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/ -#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */ -#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */ -#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */ -#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */ -#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */ -#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */ -#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */ -#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */ -#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */ -#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */ -#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */ -#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */ -#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */ -#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */ - -#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT) - -/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/ -/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ - /* Bit 15: reserved */ -#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */ -#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */ -#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */ -#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */ -#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */ -#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */ -#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */ -#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */ -#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */ -#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */ -#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */ -#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */ -#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */ -#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */ -#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */ - -#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) - -/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ -#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ -#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ -#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ -#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ - -/* - * Resolved Duplex mode and Capabilities (Aux Status Summary Reg) - */ -#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */ -#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */ -/* others: 100/10: invalid for us */ - -/* - * Level One-Specific - */ -/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ - /* Bit 7..0: reserved */ - -/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */ -#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ - /* Bit 9..8: reserved */ -#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ - -/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/ -#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ -#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ -#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ -#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */ - /* Bit 11..0: reserved */ - -/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ -#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */ - /* Bit 14: reserved */ -#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */ -#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */ -#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */ -#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */ -#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */ -#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */ -#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */ -#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */ -#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */ -#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */ -#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */ -#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */ -#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */ -#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */ - -/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/ -#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */ -#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */ -#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */ -#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */ -#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */ -#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */ -#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */ -#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */ -#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */ -#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */ -#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */ -#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */ -#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */ - -/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ -/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/ - /* Bit 15..14: reserved */ -#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */ - /* Bit 12: not described */ -#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */ -#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */ -#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */ -#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */ -#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */ -#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */ -#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */ -#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */ -#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */ -#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */ -#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */ -#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */ - -/* int. mask */ -#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN) - -/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ -#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */ -#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */ -#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */ -#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */ -#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */ -#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */ -#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */ -#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */ -#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */ - -/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ -#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */ - /* Bit 14: reserved */ -#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */ -#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */ - /* Bit 11: reserved */ -#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/ - /* Bit 9..0: not described */ - -/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ -#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */ -#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */ - - -/* - * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding - */ -#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */ -#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */ -#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ -#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ - - -/* - * National-Specific - */ -/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */ -#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */ -#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */ -#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ -#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */ - /* Bit 6..0: reserved */ - -/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */ -#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */ -#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */ -#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/ -#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */ -#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */ -#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */ - /* Bit 8: reserved */ -#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */ - -/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/ -#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */ -#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */ -#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */ -#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */ - /* Bit 11..0: reserved */ - -/* todo: those are still missing */ -/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/ -/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/ -/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/ -/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/ -/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/ -/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/ - -/* - * Marvell-Specific - */ -/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ -/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/ -#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */ -#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */ -#define PHY_M_AN_RF BIT_13 /* Remote Fault */ - /* Bit 12: reserved */ -#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */ -#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */ -#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */ -#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */ -#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */ -#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */ - -/* special defines for FIBER (88E1011S only) */ -#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */ -#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */ -#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */ -#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */ - -/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */ -#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */ -#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */ -#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */ -#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */ - -/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */ -#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */ -#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */ -#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ - /* Bit 7..0: reserved */ - -/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/ -#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ -#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ -#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */ -#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */ -#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */ -#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */ -#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */ -#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */ -#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */ -#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */ -#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */ -#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */ - -#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */ -#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */ - -#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x) -#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */ -#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */ -#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */ - -/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/ -#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ -#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */ -#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */ -#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */ -#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */ -#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */ -#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */ -#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */ -#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */ -#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */ -#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */ -#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */ -#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */ -#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */ -#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */ -#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */ - -#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN) - -/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ -/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/ -#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */ -#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */ -#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */ -#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */ -#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */ -#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */ -#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */ -#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */ -#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */ -#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */ -#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */ -#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */ - /* Bit 3..2: reserved */ -#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */ -#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */ - -#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \ - PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR) - -/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/ -#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */ -#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */ -#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */ -#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */ - -#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */ -#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */ -#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */ - -#define MAC_TX_CLK_0_MHZ 2 -#define MAC_TX_CLK_2_5_MHZ 6 -#define MAC_TX_CLK_25_MHZ 7 - -/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/ -#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */ -#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */ -#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */ -#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */ - /* Bit 7.. 5: reserved */ -#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */ -#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */ -#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */ -#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */ - -#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */ - -#define PULS_NO_STR 0 /* no pulse stretching */ -#define PULS_21MS 1 /* 21 ms to 42 ms */ -#define PULS_42MS 2 /* 42 ms to 84 ms */ -#define PULS_84MS 3 /* 84 ms to 170 ms */ -#define PULS_170MS 4 /* 170 ms to 340 ms */ -#define PULS_340MS 5 /* 340 ms to 670 ms */ -#define PULS_670MS 6 /* 670 ms to 1.3 s */ -#define PULS_1300MS 7 /* 1.3 s to 2.7 s */ - -#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */ - -#define BLINK_42MS 0 /* 42 ms */ -#define BLINK_84MS 1 /* 84 ms */ -#define BLINK_170MS 2 /* 170 ms */ -#define BLINK_340MS 3 /* 340 ms */ -#define BLINK_670MS 4 /* 670 ms */ - /* values 5 - 7: reserved */ - -/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ -#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */ -#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */ -#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */ -#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */ -#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */ -#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */ - -#define MO_LED_NORM 0 -#define MO_LED_BLINK 1 -#define MO_LED_OFF 2 -#define MO_LED_ON 3 - -/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ - /* Bit 15.. 7: reserved */ -#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */ -#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */ -#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */ -#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */ -#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */ - -/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ -#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */ -#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */ -#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */ -#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */ -#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */ -#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */ - /* Bit 9..4: reserved */ -#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */ -#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */ - - -/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/ -#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */ -#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */ - /* Bit 12.. 8: reserved */ -#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */ - -/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */ -#define CABD_STAT_NORMAL 0 -#define CABD_STAT_SHORT 1 -#define CABD_STAT_OPEN 2 -#define CABD_STAT_FAIL 3 - - -/* - * GMAC registers - * - * The GMAC registers are 16 or 32 bits wide. - * The GMACs host processor interface is 16 bits wide, - * therefore ALL registers will be addressed with 16 bit accesses. - * - * The following macros are provided to access the GMAC registers - * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(), - * GM_INHASH(), and GM_OUTHASH(). - * The macros are defined in SkGeHw.h. - * - * Note: NA reg = Network Address e.g DA, SA etc. - * - */ - -/* Port Registers */ -#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */ -#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */ -#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */ -#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */ -#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */ -#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */ -#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */ - -/* Source Address Registers */ -#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */ -#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */ -#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */ -#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */ -#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */ -#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */ - -/* Multicast Address Hash Registers */ -#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */ -#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */ -#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */ -#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */ - -/* Interrupt Source Registers */ -#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */ -#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */ -#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */ - -/* Interrupt Mask Registers */ -#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */ -#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */ -#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */ - -/* Serial Management Interface (SMI) Registers */ -#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */ -#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */ -#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */ - -/* MIB Counters */ -#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ -#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ - -/* - * MIB Counters base address definitions (low word) - - * use offset 4 for access to high word (32 bit r/o) - */ -#define GM_RXF_UC_OK \ - (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */ -#define GM_RXF_BC_OK \ - (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */ -#define GM_RXF_MPAUSE \ - (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */ -#define GM_RXF_MC_OK \ - (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */ -#define GM_RXF_FCS_ERR \ - (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */ - /* GM_MIB_CNT_BASE + 40: reserved */ -#define GM_RXO_OK_LO \ - (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */ -#define GM_RXO_OK_HI \ - (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */ -#define GM_RXO_ERR_LO \ - (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */ -#define GM_RXO_ERR_HI \ - (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */ -#define GM_RXF_SHT \ - (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */ -#define GM_RXE_FRAG \ - (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */ -#define GM_RXF_64B \ - (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */ -#define GM_RXF_127B \ - (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */ -#define GM_RXF_255B \ - (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */ -#define GM_RXF_511B \ - (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */ -#define GM_RXF_1023B \ - (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */ -#define GM_RXF_1518B \ - (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */ -#define GM_RXF_MAX_SZ \ - (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */ -#define GM_RXF_LNG_ERR \ - (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */ -#define GM_RXF_JAB_PKT \ - (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */ - /* GM_MIB_CNT_BASE + 168: reserved */ -#define GM_RXE_FIFO_OV \ - (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */ - /* GM_MIB_CNT_BASE + 184: reserved */ -#define GM_TXF_UC_OK \ - (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */ -#define GM_TXF_BC_OK \ - (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */ -#define GM_TXF_MPAUSE \ - (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */ -#define GM_TXF_MC_OK \ - (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */ -#define GM_TXO_OK_LO \ - (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */ -#define GM_TXO_OK_HI \ - (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */ -#define GM_TXF_64B \ - (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */ -#define GM_TXF_127B \ - (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */ -#define GM_TXF_255B \ - (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */ -#define GM_TXF_511B \ - (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */ -#define GM_TXF_1023B \ - (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */ -#define GM_TXF_1518B \ - (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */ -#define GM_TXF_MAX_SZ \ - (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */ - /* GM_MIB_CNT_BASE + 296: reserved */ -#define GM_TXF_COL \ - (GM_MIB_CNT_BASE + 304) /* Tx Collision */ -#define GM_TXF_LAT_COL \ - (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */ -#define GM_TXF_ABO_COL \ - (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */ -#define GM_TXF_MUL_COL \ - (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */ -#define GM_TXF_SNG_COL \ - (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */ -#define GM_TXE_FIFO_UR \ - (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */ - -/*----------------------------------------------------------------------------*/ -/* - * GMAC Bit Definitions - * - * If the bit access behaviour differs from the register access behaviour - * (r/w, r/o) this is documented after the bit number. - * The following bit access behaviours are used: - * (sc) self clearing - * (r/o) read only - */ - -/* GM_GP_STAT 16 bit r/o General Purpose Status Register */ -#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */ -#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */ -#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */ -#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */ -#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */ -#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */ -#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */ -#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */ - /* Bit 7..6: reserved */ -#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */ -#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ -#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */ -#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */ -#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */ - /* Bit 0: reserved */ - -/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ - /* Bit 15: reserved */ -#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */ -#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */ -#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */ -#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */ -#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */ -#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */ -#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */ -#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */ -#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */ -#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */ -#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */ -#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */ -#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */ -#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */ -#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */ - -#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) -#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\ - GM_GPCR_AU_SPD_DIS) - -/* GM_TX_CTRL 16 bit r/w Transmit Control Register */ -#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */ -#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */ -#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */ -#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold */ - -#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK) - -#define TX_COL_DEF 0x04 - -/* GM_RX_CTRL 16 bit r/w Receive Control Register */ -#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */ -#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */ -#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */ -#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */ - -/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ -#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */ -#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */ -#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */ - /* Bit 3..0: reserved */ - -#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK) -#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK) -#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK) - -#define TX_JAM_LEN_DEF 0x03 -#define TX_JAM_IPG_DEF 0x0b -#define TX_IPG_JAM_DEF 0x1c - -/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */ -#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */ -#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */ -#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */ -#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */ - /* Bit 7..5: reserved */ -#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ - -#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK) -#define DATA_BLIND_DEF 0x04 - -#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK) -#define IPG_DATA_DEF 0x1e - -/* GM_SMI_CTRL 16 bit r/w SMI Control Register */ -#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */ -#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */ -#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/ -#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */ -#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */ - /* Bit 2..0: reserved */ - -#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK) -#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK) - - /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ - /* Bit 15..6: reserved */ -#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */ -#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */ - /* Bit 3..0: reserved */ - -/* Receive Frame Status Encoding */ -#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */ - /* Bit 15..14: reserved */ -#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */ -#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */ -#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */ -#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */ -#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */ -#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */ -#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */ -#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */ -#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */ -#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */ -#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */ - /* Bit 2: reserved */ -#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */ -#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */ - -/* - * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) - */ -#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \ - GMR_FS_LONG_ERR | \ - GMR_FS_MII_ERR | \ - GMR_FS_BAD_FC | \ - GMR_FS_GOOD_FC | \ - GMR_FS_JABBER) - -/* Rx GMAC FIFO Flush Mask (default) */ -#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \ - GMR_FS_RX_FF_OV | \ - GMR_FS_MII_ERR | \ - GMR_FS_BAD_FC | \ - GMR_FS_GOOD_FC | \ - GMR_FS_UN_SIZE | \ - GMR_FS_JABBER) - -/* typedefs *******************************************************************/ - - -/* function prototypes ********************************************************/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __INC_XMAC_H */ diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c deleted file mode 100644 index 6e6c56aa6d6f..000000000000 --- a/drivers/net/sk98lin/skaddr.c +++ /dev/null @@ -1,1788 +0,0 @@ -/****************************************************************************** - * - * Name: skaddr.c - * Project: Gigabit Ethernet Adapters, ADDR-Module - * Version: $Revision: 1.52 $ - * Date: $Date: 2003/06/02 13:46:15 $ - * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This module is intended to manage multicast addresses, address override, - * and promiscuous mode on GEnesis and Yukon adapters. - * - * Address Layout: - * port address: physical MAC address - * 1st exact match: logical MAC address (GEnesis only) - * 2nd exact match: RLMT multicast (GEnesis only) - * exact match 3-13: OS-specific multicasts (GEnesis only) - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * "skdrv2nd.h" - * - ******************************************************************************/ - -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell."; -#endif /* DEBUG ||!LINT || !SK_SLIM */ - -#define __SKADDR_C - -#ifdef __cplusplus -extern "C" { -#endif /* cplusplus */ - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" - -/* defines ********************************************************************/ - - -#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */ -#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */ -#define HASH_BITS 6 /* #bits in hash */ -#define SK_MC_BIT 0x01 - -/* Error numbers and messages. */ - -#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0) -#define SKERR_ADDR_E001MSG "Bad Flags." -#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1) -#define SKERR_ADDR_E002MSG "New Error." - -/* typedefs *******************************************************************/ - -/* None. */ - -/* global variables ***********************************************************/ - -/* 64-bit hash values with all bits set. */ - -static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; - -/* local variables ************************************************************/ - -#ifdef DEBUG -static int Next0[SK_MAX_MACS] = {0}; -#endif /* DEBUG */ - -static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); -static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); - -/* functions ******************************************************************/ - -/****************************************************************************** - * - * SkAddrInit - initialize data, set state to init - * - * Description: - * - * SK_INIT_DATA - * ============ - * - * This routine clears the multicast tables and resets promiscuous mode. - * Some entries are reserved for the "logical MAC address", the - * SK-RLMT multicast address, and the BPDU multicast address. - * - * - * SK_INIT_IO - * ========== - * - * All permanent MAC addresses are read from EPROM. - * If the current MAC addresses are not already set in software, - * they are set to the values of the permanent addresses. - * The current addresses are written to the corresponding MAC. - * - * - * SK_INIT_RUN - * =========== - * - * Nothing. - * - * Context: - * init, pageable - * - * Returns: - * SK_ADDR_SUCCESS - */ -int SkAddrInit( -SK_AC *pAC, /* the adapter context */ -SK_IOC IoC, /* I/O context */ -int Level) /* initialization level */ -{ - int j; - SK_U32 i; - SK_U8 *InAddr; - SK_U16 *OutAddr; - SK_ADDR_PORT *pAPort; - - switch (Level) { - case SK_INIT_DATA: - SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, - (SK_U16) sizeof(SK_ADDR)); - - for (i = 0; i < SK_MAX_MACS; i++) { - pAPort = &pAC->Addr.Port[i]; - pAPort->PromMode = SK_PROM_MODE_NONE; - - pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; - pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; - pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; - pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; - } -#ifdef xDEBUG - for (i = 0; i < SK_MAX_MACS; i++) { - if (pAC->Addr.Port[i].NextExactMatchRlmt < - SK_ADDR_FIRST_MATCH_RLMT) { - Next0[i] |= 4; - } - } -#endif /* DEBUG */ - /* pAC->Addr.InitDone = SK_INIT_DATA; */ - break; - - case SK_INIT_IO: -#ifndef SK_NO_RLMT - for (i = 0; i < SK_MAX_NETS; i++) { - pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; - } -#endif /* !SK_NO_RLMT */ -#ifdef xDEBUG - for (i = 0; i < SK_MAX_MACS; i++) { - if (pAC->Addr.Port[i].NextExactMatchRlmt < - SK_ADDR_FIRST_MATCH_RLMT) { - Next0[i] |= 8; - } - } -#endif /* DEBUG */ - - /* Read permanent logical MAC address from Control Register File. */ - for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; - SK_IN8(IoC, B2_MAC_1 + j, InAddr); - } - - if (!pAC->Addr.Net[0].CurrentMacAddressSet) { - /* Set the current logical MAC address to the permanent one. */ - pAC->Addr.Net[0].CurrentMacAddress = - pAC->Addr.Net[0].PermanentMacAddress; - pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE; - } - - /* Set the current logical MAC address. */ - pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = - pAC->Addr.Net[0].CurrentMacAddress; -#if SK_MAX_NETS > 1 - /* Set logical MAC address for net 2 to (log | 3). */ - if (!pAC->Addr.Net[1].CurrentMacAddressSet) { - pAC->Addr.Net[1].PermanentMacAddress = - pAC->Addr.Net[0].PermanentMacAddress; - pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3; - /* Set the current logical MAC address to the permanent one. */ - pAC->Addr.Net[1].CurrentMacAddress = - pAC->Addr.Net[1].PermanentMacAddress; - pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE; - } -#endif /* SK_MAX_NETS > 1 */ - -#ifdef DEBUG - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, - ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", - i, - pAC->Addr.Net[i].PermanentMacAddress.a[0], - pAC->Addr.Net[i].PermanentMacAddress.a[1], - pAC->Addr.Net[i].PermanentMacAddress.a[2], - pAC->Addr.Net[i].PermanentMacAddress.a[3], - pAC->Addr.Net[i].PermanentMacAddress.a[4], - pAC->Addr.Net[i].PermanentMacAddress.a[5])) - - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, - ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", - i, - pAC->Addr.Net[i].CurrentMacAddress.a[0], - pAC->Addr.Net[i].CurrentMacAddress.a[1], - pAC->Addr.Net[i].CurrentMacAddress.a[2], - pAC->Addr.Net[i].CurrentMacAddress.a[3], - pAC->Addr.Net[i].CurrentMacAddress.a[4], - pAC->Addr.Net[i].CurrentMacAddress.a[5])) - } -#endif /* DEBUG */ - - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - pAPort = &pAC->Addr.Port[i]; - - /* Read permanent port addresses from Control Register File. */ - for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j]; - SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr); - } - - if (!pAPort->CurrentMacAddressSet) { - /* - * Set the current and previous physical MAC address - * of this port to its permanent MAC address. - */ - pAPort->CurrentMacAddress = pAPort->PermanentMacAddress; - pAPort->PreviousMacAddress = pAPort->PermanentMacAddress; - pAPort->CurrentMacAddressSet = SK_TRUE; - } - - /* Set port's current physical MAC address. */ - OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - XM_OUTADDR(IoC, i, XM_SA, OutAddr); - } -#endif /* GENESIS */ -#ifdef YUKON - if (!pAC->GIni.GIGenesis) { - GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr); - } -#endif /* YUKON */ -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, - ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAPort->PermanentMacAddress.a[0], - pAPort->PermanentMacAddress.a[1], - pAPort->PermanentMacAddress.a[2], - pAPort->PermanentMacAddress.a[3], - pAPort->PermanentMacAddress.a[4], - pAPort->PermanentMacAddress.a[5])) - - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, - ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAPort->CurrentMacAddress.a[0], - pAPort->CurrentMacAddress.a[1], - pAPort->CurrentMacAddress.a[2], - pAPort->CurrentMacAddress.a[3], - pAPort->CurrentMacAddress.a[4], - pAPort->CurrentMacAddress.a[5])) -#endif /* DEBUG */ - } - /* pAC->Addr.InitDone = SK_INIT_IO; */ - break; - - case SK_INIT_RUN: -#ifdef xDEBUG - for (i = 0; i < SK_MAX_MACS; i++) { - if (pAC->Addr.Port[i].NextExactMatchRlmt < - SK_ADDR_FIRST_MATCH_RLMT) { - Next0[i] |= 16; - } - } -#endif /* DEBUG */ - - /* pAC->Addr.InitDone = SK_INIT_RUN; */ - break; - - default: /* error */ - break; - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrInit */ - -#ifndef SK_SLIM - -/****************************************************************************** - * - * SkAddrMcClear - clear the multicast table - * - * Description: - * This routine clears the multicast table. - * - * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated - * immediately. - * - * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according - * to the adapter in use. The real work is done there. - * - * Context: - * runtime, pageable - * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY - * may be called after SK_INIT_IO without limitation - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -int SkAddrMcClear( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Index of affected port */ -int Flags) /* permanent/non-perm, sw-only */ -{ - int ReturnCode; - - if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - - if (pAC->GIni.GIGenesis) { - ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); - } - else { - ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); - } - - return (ReturnCode); - -} /* SkAddrMcClear */ - -#endif /* !SK_SLIM */ - -#ifndef SK_SLIM - -/****************************************************************************** - * - * SkAddrXmacMcClear - clear the multicast table - * - * Description: - * This routine clears the multicast table - * (either entry 2 or entries 3-16 and InexactFilter) of the given port. - * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated - * immediately. - * - * Context: - * runtime, pageable - * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY - * may be called after SK_INIT_IO without limitation - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrXmacMcClear( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Index of affected port */ -int Flags) /* permanent/non-perm, sw-only */ -{ - int i; - - if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ - - /* Clear RLMT multicast addresses. */ - pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; - } - else { /* not permanent => DRV */ - - /* Clear InexactFilter */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; - } - - /* Clear DRV multicast addresses. */ - - pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; - } - - if (!(Flags & SK_MC_SW_ONLY)) { - (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber); - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrXmacMcClear */ - -#endif /* !SK_SLIM */ - -#ifndef SK_SLIM - -/****************************************************************************** - * - * SkAddrGmacMcClear - clear the multicast table - * - * Description: - * This routine clears the multicast hashing table (InexactFilter) - * (either the RLMT or the driver bits) of the given port. - * - * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated - * immediately. - * - * Context: - * runtime, pageable - * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY - * may be called after SK_INIT_IO without limitation - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrGmacMcClear( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Index of affected port */ -int Flags) /* permanent/non-perm, sw-only */ -{ - int i; - -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) -#endif /* DEBUG */ - - /* Clear InexactFilter */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; - } - - if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ - - /* Copy DRV bits to InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; - - /* Clear InexactRlmtFilter. */ - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; - - } - } - else { /* not permanent => DRV */ - - /* Copy RLMT bits to InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; - - /* Clear InexactDrvFilter. */ - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; - } - } - -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) -#endif /* DEBUG */ - - if (!(Flags & SK_MC_SW_ONLY)) { - (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrGmacMcClear */ - -#ifndef SK_ADDR_CHEAT - -/****************************************************************************** - * - * SkXmacMcHash - hash multicast address - * - * Description: - * This routine computes the hash value for a multicast address. - * A CRC32 algorithm is used. - * - * Notes: - * The code was adapted from the XaQti data sheet. - * - * Context: - * runtime, pageable - * - * Returns: - * Hash value of multicast address. - */ -static SK_U32 SkXmacMcHash( -unsigned char *pMc) /* Multicast address */ -{ - SK_U32 Idx; - SK_U32 Bit; - SK_U32 Data; - SK_U32 Crc; - - Crc = 0xFFFFFFFFUL; - for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) { - Data = *pMc++; - for (Bit = 0; Bit < 8; Bit++, Data >>= 1) { - Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0); - } - } - - return (Crc & ((1 << HASH_BITS) - 1)); - -} /* SkXmacMcHash */ - - -/****************************************************************************** - * - * SkGmacMcHash - hash multicast address - * - * Description: - * This routine computes the hash value for a multicast address. - * A CRC16 algorithm is used. - * - * Notes: - * - * - * Context: - * runtime, pageable - * - * Returns: - * Hash value of multicast address. - */ -static SK_U32 SkGmacMcHash( -unsigned char *pMc) /* Multicast address */ -{ - SK_U32 Data; - SK_U32 TmpData; - SK_U32 Crc; - int Byte; - int Bit; - - Crc = 0xFFFFFFFFUL; - for (Byte = 0; Byte < 6; Byte++) { - /* Get next byte. */ - Data = (SK_U32) pMc[Byte]; - - /* Change bit order in byte. */ - TmpData = Data; - for (Bit = 0; Bit < 8; Bit++) { - if (TmpData & 1L) { - Data |= 1L << (7 - Bit); - } - else { - Data &= ~(1L << (7 - Bit)); - } - TmpData >>= 1; - } - - Crc ^= (Data << 24); - for (Bit = 0; Bit < 8; Bit++) { - if (Crc & 0x80000000) { - Crc = (Crc << 1) ^ GMAC_POLY; - } - else { - Crc <<= 1; - } - } - } - - return (Crc & ((1 << HASH_BITS) - 1)); - -} /* SkGmacMcHash */ - -#endif /* !SK_ADDR_CHEAT */ - -/****************************************************************************** - * - * SkAddrMcAdd - add a multicast address to a port - * - * Description: - * This routine enables reception for a given address on the given port. - * - * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the - * adapter in use. The real work is done there. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_DATA - * - * Returns: - * SK_MC_FILTERING_EXACT - * SK_MC_FILTERING_INEXACT - * SK_MC_ILLEGAL_ADDRESS - * SK_MC_ILLEGAL_PORT - * SK_MC_RLMT_OVERFLOW - */ -int SkAddrMcAdd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Port Number */ -SK_MAC_ADDR *pMc, /* multicast address to be added */ -int Flags) /* permanent/non-permanent */ -{ - int ReturnCode; - - if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - - if (pAC->GIni.GIGenesis) { - ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); - } - else { - ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); - } - - return (ReturnCode); - -} /* SkAddrMcAdd */ - - -/****************************************************************************** - * - * SkAddrXmacMcAdd - add a multicast address to a port - * - * Description: - * This routine enables reception for a given address on the given port. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * The multicast bit is only checked if there are no free exact match - * entries. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_DATA - * - * Returns: - * SK_MC_FILTERING_EXACT - * SK_MC_FILTERING_INEXACT - * SK_MC_ILLEGAL_ADDRESS - * SK_MC_RLMT_OVERFLOW - */ -static int SkAddrXmacMcAdd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Port Number */ -SK_MAC_ADDR *pMc, /* multicast address to be added */ -int Flags) /* permanent/non-permanent */ -{ - int i; - SK_U8 Inexact; -#ifndef SK_ADDR_CHEAT - SK_U32 HashBit; -#endif /* !defined(SK_ADDR_CHEAT) */ - - if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ -#ifdef xDEBUG - if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt < - SK_ADDR_FIRST_MATCH_RLMT) { - Next0[PortNumber] |= 1; - return (SK_MC_RLMT_OVERFLOW); - } -#endif /* DEBUG */ - - if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt > - SK_ADDR_LAST_MATCH_RLMT) { - return (SK_MC_RLMT_OVERFLOW); - } - - /* Set a RLMT multicast address. */ - - pAC->Addr.Port[PortNumber].Exact[ - pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc; - - return (SK_MC_FILTERING_EXACT); - } - -#ifdef xDEBUG - if (pAC->Addr.Port[PortNumber].NextExactMatchDrv < - SK_ADDR_FIRST_MATCH_DRV) { - Next0[PortNumber] |= 2; - return (SK_MC_RLMT_OVERFLOW); - } -#endif /* DEBUG */ - - if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { - - /* Set exact match entry. */ - pAC->Addr.Port[PortNumber].Exact[ - pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc; - - /* Clear InexactFilter */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; - } - } - else { - if (!(pMc->a[0] & SK_MC_BIT)) { - /* Hashing only possible with multicast addresses */ - return (SK_MC_ILLEGAL_ADDRESS); - } -#ifndef SK_ADDR_CHEAT - /* Compute hash value of address. */ - HashBit = 63 - SkXmacMcHash(&pMc->a[0]); - - /* Add bit to InexactFilter. */ - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |= - 1 << (HashBit % 8); -#else /* SK_ADDR_CHEAT */ - /* Set all bits in InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; - } -#endif /* SK_ADDR_CHEAT */ - } - - for (Inexact = 0, i = 0; i < 8; i++) { - Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; - } - - if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) { - return (SK_MC_FILTERING_EXACT); - } - else { - return (SK_MC_FILTERING_INEXACT); - } - -} /* SkAddrXmacMcAdd */ - - -/****************************************************************************** - * - * SkAddrGmacMcAdd - add a multicast address to a port - * - * Description: - * This routine enables reception for a given address on the given port. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_DATA - * - * Returns: - * SK_MC_FILTERING_INEXACT - * SK_MC_ILLEGAL_ADDRESS - */ -static int SkAddrGmacMcAdd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Port Number */ -SK_MAC_ADDR *pMc, /* multicast address to be added */ -int Flags) /* permanent/non-permanent */ -{ - int i; -#ifndef SK_ADDR_CHEAT - SK_U32 HashBit; -#endif /* !defined(SK_ADDR_CHEAT) */ - - if (!(pMc->a[0] & SK_MC_BIT)) { - /* Hashing only possible with multicast addresses */ - return (SK_MC_ILLEGAL_ADDRESS); - } - -#ifndef SK_ADDR_CHEAT - - /* Compute hash value of address. */ - HashBit = SkGmacMcHash(&pMc->a[0]); - - if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ - - /* Add bit to InexactRlmtFilter. */ - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |= - 1 << (HashBit % 8); - - /* Copy bit to InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; - } -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])) -#endif /* DEBUG */ - } - else { /* not permanent => DRV */ - - /* Add bit to InexactDrvFilter. */ - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |= - 1 << (HashBit % 8); - - /* Copy bit to InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; - } -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])) -#endif /* DEBUG */ - } - -#else /* SK_ADDR_CHEAT */ - - /* Set all bits in InexactFilter. */ - for (i = 0; i < 8; i++) { - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; - } -#endif /* SK_ADDR_CHEAT */ - - return (SK_MC_FILTERING_INEXACT); - -} /* SkAddrGmacMcAdd */ - -#endif /* !SK_SLIM */ - -/****************************************************************************** - * - * SkAddrMcUpdate - update the HW MC address table and set the MAC address - * - * Description: - * This routine enables reception of the addresses contained in a local - * table for a given port. - * It also programs the port's current physical MAC address. - * - * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according - * to the adapter in use. The real work is done there. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_MC_FILTERING_EXACT - * SK_MC_FILTERING_INEXACT - * SK_ADDR_ILLEGAL_PORT - */ -int SkAddrMcUpdate( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber) /* Port Number */ -{ - int ReturnCode = 0; -#if (!defined(SK_SLIM) || defined(DEBUG)) - if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } -#endif /* !SK_SLIM || DEBUG */ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber); - } -#endif /* GENESIS */ -#ifdef YUKON - if (!pAC->GIni.GIGenesis) { - ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber); - } -#endif /* YUKON */ - return (ReturnCode); - -} /* SkAddrMcUpdate */ - - -#ifdef GENESIS - -/****************************************************************************** - * - * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address - * - * Description: - * This routine enables reception of the addresses contained in a local - * table for a given port. - * It also programs the port's current physical MAC address. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_MC_FILTERING_EXACT - * SK_MC_FILTERING_INEXACT - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrXmacMcUpdate( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber) /* Port Number */ -{ - SK_U32 i; - SK_U8 Inexact; - SK_U16 *OutAddr; - SK_ADDR_PORT *pAPort; - - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) - - pAPort = &pAC->Addr.Port[PortNumber]; - -#ifdef DEBUG - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) -#endif /* DEBUG */ - - /* Start with 0 to also program the logical MAC address. */ - for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { - /* Set exact match address i on XMAC */ - OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; - XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); - } - - /* Clear other permanent exact match addresses on XMAC */ - if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) { - - SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt, - SK_ADDR_LAST_MATCH_RLMT); - } - - for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) { - OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; - XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); - } - - /* Clear other non-permanent exact match addresses on XMAC */ - if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { - - SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv, - SK_ADDR_LAST_MATCH_DRV); - } - - for (Inexact = 0, i = 0; i < 8; i++) { - Inexact |= pAPort->InexactFilter.Bytes[i]; - } - - if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { - - /* Set all bits in 64-bit hash register. */ - XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else if (Inexact != 0) { - - /* Set 64-bit hash register to InexactFilter. */ - XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else { - /* Disable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); - } - - if (pAPort->PromMode != SK_PROM_MODE_NONE) { - (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); - } - - /* Set port's current physical MAC address. */ - OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; - - XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); - -#ifdef xDEBUG - for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { - SK_U8 InAddr8[6]; - SK_U16 *InAddr; - - /* Get exact match address i from port PortNumber. */ - InAddr = (SK_U16 *) &InAddr8[0]; - - XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr); - - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrXmacMcUpdate: MC address %d on Port %u: ", - "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n", - i, - PortNumber, - InAddr8[0], - InAddr8[1], - InAddr8[2], - InAddr8[3], - InAddr8[4], - InAddr8[5], - pAPort->Exact[i].a[0], - pAPort->Exact[i].a[1], - pAPort->Exact[i].a[2], - pAPort->Exact[i].a[3], - pAPort->Exact[i].a[4], - pAPort->Exact[i].a[5])) - } -#endif /* DEBUG */ - - /* Determine return value. */ - if (Inexact == 0 && pAPort->PromMode == 0) { - return (SK_MC_FILTERING_EXACT); - } - else { - return (SK_MC_FILTERING_INEXACT); - } - -} /* SkAddrXmacMcUpdate */ - -#endif /* GENESIS */ - -#ifdef YUKON - -/****************************************************************************** - * - * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address - * - * Description: - * This routine enables reception of the addresses contained in a local - * table for a given port. - * It also programs the port's current physical MAC address. - * - * Notes: - * The return code is only valid for SK_PROM_MODE_NONE. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_MC_FILTERING_EXACT - * SK_MC_FILTERING_INEXACT - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrGmacMcUpdate( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber) /* Port Number */ -{ -#ifndef SK_SLIM - SK_U32 i; - SK_U8 Inexact; -#endif /* not SK_SLIM */ - SK_U16 *OutAddr; - SK_ADDR_PORT *pAPort; - - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) - - pAPort = &pAC->Addr.Port[PortNumber]; - -#ifdef DEBUG - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) -#endif /* DEBUG */ - -#ifndef SK_SLIM - for (Inexact = 0, i = 0; i < 8; i++) { - Inexact |= pAPort->InexactFilter.Bytes[i]; - } - - /* Set 64-bit hash register to InexactFilter. */ - GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, - &pAPort->InexactFilter.Bytes[0]); - - if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { - - /* Set all bits in 64-bit hash register. */ - GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else { - /* Enable Hashing. */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - - if (pAPort->PromMode != SK_PROM_MODE_NONE) { - (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); - } -#else /* SK_SLIM */ - - /* Set all bits in 64-bit hash register. */ - GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - - (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); - -#endif /* SK_SLIM */ - - /* Set port's current physical MAC address. */ - OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; - GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); - - /* Set port's current logical MAC address. */ - OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0]; - GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr); - -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAPort->Exact[0].a[0], - pAPort->Exact[0].a[1], - pAPort->Exact[0].a[2], - pAPort->Exact[0].a[3], - pAPort->Exact[0].a[4], - pAPort->Exact[0].a[5])) - - SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAPort->CurrentMacAddress.a[0], - pAPort->CurrentMacAddress.a[1], - pAPort->CurrentMacAddress.a[2], - pAPort->CurrentMacAddress.a[3], - pAPort->CurrentMacAddress.a[4], - pAPort->CurrentMacAddress.a[5])) -#endif /* DEBUG */ - -#ifndef SK_SLIM - /* Determine return value. */ - if (Inexact == 0 && pAPort->PromMode == 0) { - return (SK_MC_FILTERING_EXACT); - } - else { - return (SK_MC_FILTERING_INEXACT); - } -#else /* SK_SLIM */ - return (SK_MC_FILTERING_INEXACT); -#endif /* SK_SLIM */ - -} /* SkAddrGmacMcUpdate */ - -#endif /* YUKON */ - -#ifndef SK_NO_MAO - -/****************************************************************************** - * - * SkAddrOverride - override a port's MAC address - * - * Description: - * This routine overrides the MAC address of one port. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_ADDR_SUCCESS if successful. - * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address. - * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address. - * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before. - */ -int SkAddrOverride( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* Port Number */ -SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */ -int Flags) /* logical/physical MAC address */ -{ -#ifndef SK_NO_RLMT - SK_EVPARA Para; -#endif /* !SK_NO_RLMT */ - SK_U32 NetNumber; - SK_U32 i; - SK_U16 SK_FAR *OutAddr; - -#ifndef SK_NO_RLMT - NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber; -#else - NetNumber = 0; -#endif /* SK_NO_RLMT */ -#if (!defined(SK_SLIM) || defined(DEBUG)) - if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } -#endif /* !SK_SLIM || DEBUG */ - if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) { - return (SK_ADDR_MULTICAST_ADDRESS); - } - - if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) { - return (SK_ADDR_TOO_EARLY); - } - - if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */ - /* Parameter *pNewAddr is ignored. */ - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - if (!pAC->Addr.Port[i].CurrentMacAddressSet) { - return (SK_ADDR_TOO_EARLY); - } - } -#ifndef SK_NO_RLMT - /* Set PortNumber to number of net's active port. */ - PortNumber = pAC->Rlmt.Net[NetNumber]. - Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; -#endif /* !SK_NO_RLMT */ - pAC->Addr.Port[PortNumber].Exact[0] = - pAC->Addr.Net[NetNumber].CurrentMacAddress; - - /* Write address to first exact match entry of active port. */ - (void) SkAddrMcUpdate(pAC, IoC, PortNumber); - } - else if (Flags & SK_ADDR_CLEAR_LOGICAL) { - /* Deactivate logical MAC address. */ - /* Parameter *pNewAddr is ignored. */ - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - if (!pAC->Addr.Port[i].CurrentMacAddressSet) { - return (SK_ADDR_TOO_EARLY); - } - } -#ifndef SK_NO_RLMT - /* Set PortNumber to number of net's active port. */ - PortNumber = pAC->Rlmt.Net[NetNumber]. - Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; -#endif /* !SK_NO_RLMT */ - for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) { - pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0; - } - - /* Write address to first exact match entry of active port. */ - (void) SkAddrMcUpdate(pAC, IoC, PortNumber); - } - else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { - return (SK_ADDR_DUPLICATE_ADDRESS); - } - - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - if (!pAC->Addr.Port[i].CurrentMacAddressSet) { - return (SK_ADDR_TOO_EARLY); - } - - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Port[i].CurrentMacAddress.a)) { - if (i == PortNumber) { - return (SK_ADDR_SUCCESS); - } - else { - return (SK_ADDR_DUPLICATE_ADDRESS); - } - } - } - - pAC->Addr.Port[PortNumber].PreviousMacAddress = - pAC->Addr.Port[PortNumber].CurrentMacAddress; - pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; - - /* Change port's physical MAC address. */ - OutAddr = (SK_U16 SK_FAR *) pNewAddr; -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); - } -#endif /* GENESIS */ -#ifdef YUKON - if (!pAC->GIni.GIGenesis) { - GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); - } -#endif /* YUKON */ - -#ifndef SK_NO_RLMT - /* Report address change to RLMT. */ - Para.Para32[0] = PortNumber; - Para.Para32[0] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); -#endif /* !SK_NO_RLMT */ - } - else { /* Logical MAC address. */ - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { - return (SK_ADDR_SUCCESS); - } - - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { - if (!pAC->Addr.Port[i].CurrentMacAddressSet) { - return (SK_ADDR_TOO_EARLY); - } - - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Port[i].CurrentMacAddress.a)) { - return (SK_ADDR_DUPLICATE_ADDRESS); - } - } - - /* - * In case that the physical and the logical MAC addresses are equal - * we must also change the physical MAC address here. - * In this case we have an adapter which initially was programmed with - * two identical MAC addresses. - */ - if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, - pAC->Addr.Port[PortNumber].Exact[0].a)) { - - pAC->Addr.Port[PortNumber].PreviousMacAddress = - pAC->Addr.Port[PortNumber].CurrentMacAddress; - pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; - -#ifndef SK_NO_RLMT - /* Report address change to RLMT. */ - Para.Para32[0] = PortNumber; - Para.Para32[0] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); -#endif /* !SK_NO_RLMT */ - } - -#ifndef SK_NO_RLMT - /* Set PortNumber to number of net's active port. */ - PortNumber = pAC->Rlmt.Net[NetNumber]. - Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; -#endif /* !SK_NO_RLMT */ - pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr; - pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr; -#ifdef DEBUG - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) - - SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) -#endif /* DEBUG */ - - /* Write address to first exact match entry of active port. */ - (void) SkAddrMcUpdate(pAC, IoC, PortNumber); - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrOverride */ - - -#endif /* SK_NO_MAO */ - -/****************************************************************************** - * - * SkAddrPromiscuousChange - set promiscuous mode for given port - * - * Description: - * This routine manages promiscuous mode: - * - none - * - all LLC frames - * - all MC frames - * - * It calls either SkAddrXmacPromiscuousChange or - * SkAddrGmacPromiscuousChange, according to the adapter in use. - * The real work is done there. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -int SkAddrPromiscuousChange( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* port whose promiscuous mode changes */ -int NewPromMode) /* new promiscuous mode */ -{ - int ReturnCode = 0; -#if (!defined(SK_SLIM) || defined(DEBUG)) - if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } -#endif /* !SK_SLIM || DEBUG */ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - ReturnCode = - SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); - } -#endif /* GENESIS */ -#ifdef YUKON - if (!pAC->GIni.GIGenesis) { - ReturnCode = - SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); - } -#endif /* YUKON */ - - return (ReturnCode); - -} /* SkAddrPromiscuousChange */ - -#ifdef GENESIS - -/****************************************************************************** - * - * SkAddrXmacPromiscuousChange - set promiscuous mode for given port - * - * Description: - * This routine manages promiscuous mode: - * - none - * - all LLC frames - * - all MC frames - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrXmacPromiscuousChange( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* port whose promiscuous mode changes */ -int NewPromMode) /* new promiscuous mode */ -{ - int i; - SK_BOOL InexactModeBit; - SK_U8 Inexact; - SK_U8 HwInexact; - SK_FILTER64 HwInexactFilter; - SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */ - int CurPromMode = SK_PROM_MODE_NONE; - - /* Read CurPromMode from Hardware. */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - - if ((LoMode & XM_MD_ENA_PROM) != 0) { - /* Promiscuous mode! */ - CurPromMode |= SK_PROM_MODE_LLC; - } - - for (Inexact = 0xFF, i = 0; i < 8; i++) { - Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; - } - if (Inexact == 0xFF) { - CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); - } - else { - /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ - XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - - InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; - - /* Read 64-bit hash register from XMAC */ - XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]); - - for (HwInexact = 0xFF, i = 0; i < 8; i++) { - HwInexact &= HwInexactFilter.Bytes[i]; - } - - if (InexactModeBit && (HwInexact == 0xFF)) { - CurPromMode |= SK_PROM_MODE_ALL_MC; - } - } - - pAC->Addr.Port[PortNumber].PromMode = NewPromMode; - - if (NewPromMode == CurPromMode) { - return (SK_ADDR_SUCCESS); - } - - if ((NewPromMode & SK_PROM_MODE_ALL_MC) && - !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */ - - /* Set all bits in 64-bit hash register. */ - XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else if ((CurPromMode & SK_PROM_MODE_ALL_MC) && - !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */ - for (Inexact = 0, i = 0; i < 8; i++) { - Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; - } - if (Inexact == 0) { - /* Disable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); - } - else { - /* Set 64-bit hash register to InexactFilter. */ - XM_OUTHASH(IoC, PortNumber, XM_HSM, - &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - } - - if ((NewPromMode & SK_PROM_MODE_LLC) && - !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ - /* Set the MAC in Promiscuous Mode */ - SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else if ((CurPromMode & SK_PROM_MODE_LLC) && - !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ - /* Clear Promiscuous Mode */ - SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrXmacPromiscuousChange */ - -#endif /* GENESIS */ - -#ifdef YUKON - -/****************************************************************************** - * - * SkAddrGmacPromiscuousChange - set promiscuous mode for given port - * - * Description: - * This routine manages promiscuous mode: - * - none - * - all LLC frames - * - all MC frames - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -static int SkAddrGmacPromiscuousChange( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 PortNumber, /* port whose promiscuous mode changes */ -int NewPromMode) /* new promiscuous mode */ -{ - SK_U16 ReceiveControl; /* GMAC Receive Control Register */ - int CurPromMode = SK_PROM_MODE_NONE; - - /* Read CurPromMode from Hardware. */ - GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl); - - if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) { - /* Promiscuous mode! */ - CurPromMode |= SK_PROM_MODE_LLC; - } - - if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) { - /* All Multicast mode! */ - CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); - } - - pAC->Addr.Port[PortNumber].PromMode = NewPromMode; - - if (NewPromMode == CurPromMode) { - return (SK_ADDR_SUCCESS); - } - - if ((NewPromMode & SK_PROM_MODE_ALL_MC) && - !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */ - - /* Set all bits in 64-bit hash register. */ - GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); - - /* Enable Hashing */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - - if ((CurPromMode & SK_PROM_MODE_ALL_MC) && - !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ - - /* Set 64-bit hash register to InexactFilter. */ - GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, - &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); - - /* Enable Hashing. */ - SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - } - - if ((NewPromMode & SK_PROM_MODE_LLC) && - !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ - - /* Set the MAC to Promiscuous Mode. */ - SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); - } - else if ((CurPromMode & SK_PROM_MODE_LLC) && - !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ - - /* Clear Promiscuous Mode. */ - SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); - } - - return (SK_ADDR_SUCCESS); - -} /* SkAddrGmacPromiscuousChange */ - -#endif /* YUKON */ - -#ifndef SK_SLIM - -/****************************************************************************** - * - * SkAddrSwap - swap address info - * - * Description: - * This routine swaps address info of two ports. - * - * Context: - * runtime, pageable - * may be called after SK_INIT_IO - * - * Returns: - * SK_ADDR_SUCCESS - * SK_ADDR_ILLEGAL_PORT - */ -int SkAddrSwap( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -SK_U32 FromPortNumber, /* Port1 Index */ -SK_U32 ToPortNumber) /* Port2 Index */ -{ - int i; - SK_U8 Byte; - SK_MAC_ADDR MacAddr; - SK_U32 DWord; - - if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - - if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { - return (SK_ADDR_ILLEGAL_PORT); - } - - if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) { - return (SK_ADDR_ILLEGAL_PORT); - } - - /* - * Swap: - * - Exact Match Entries (GEnesis and Yukon) - * Yukon uses first entry for the logical MAC - * address (stored in the second GMAC register). - * - FirstExactMatchRlmt (GEnesis only) - * - NextExactMatchRlmt (GEnesis only) - * - FirstExactMatchDrv (GEnesis only) - * - NextExactMatchDrv (GEnesis only) - * - 64-bit filter (InexactFilter) - * - Promiscuous Mode - * of ports. - */ - - for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) { - MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i]; - pAC->Addr.Port[FromPortNumber].Exact[i] = - pAC->Addr.Port[ToPortNumber].Exact[i]; - pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr; - } - - for (i = 0; i < 8; i++) { - Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i]; - pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] = - pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i]; - pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte; - } - - i = pAC->Addr.Port[FromPortNumber].PromMode; - pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; - pAC->Addr.Port[ToPortNumber].PromMode = i; - - if (pAC->GIni.GIGenesis) { - DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; - pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = - pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; - pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; - pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = - pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; - pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; - pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = - pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; - pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; - - DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; - pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = - pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; - pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; - } - - /* CAUTION: Solution works if only ports of one adapter are in use. */ - for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. - Net->NetNumber].NumPorts; i++) { - if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. - Port[i]->PortNumber == ToPortNumber) { - pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. - ActivePort = i; - /* 20001207 RA: Was "ToPortNumber;". */ - } - } - - (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); - (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); - - return (SK_ADDR_SUCCESS); - -} /* SkAddrSwap */ - -#endif /* !SK_SLIM */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c deleted file mode 100644 index 37ce03fb8de3..000000000000 --- a/drivers/net/sk98lin/skdim.c +++ /dev/null @@ -1,742 +0,0 @@ -/****************************************************************************** - * - * Name: skdim.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.5 $ - * Date: $Date: 2003/11/28 12:55:40 $ - * Purpose: All functions to maintain interrupt moderation - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This module is intended to manage the dynamic interrupt moderation on both - * GEnesis and Yukon adapters. - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * "skdrv2nd.h" - * - ******************************************************************************/ - -#ifndef lint -static const char SysKonnectFileId[] = - "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect."; -#endif - -#define __SKADDR_C - -#ifdef __cplusplus -#error C++ is not yet supported. -extern "C" { -#endif - -/******************************************************************************* -** -** Includes -** -*******************************************************************************/ - -#ifndef __INC_SKDRV1ST_H -#include "h/skdrv1st.h" -#endif - -#ifndef __INC_SKDRV2ND_H -#include "h/skdrv2nd.h" -#endif - -#include - -/******************************************************************************* -** -** Defines -** -*******************************************************************************/ - -/******************************************************************************* -** -** Typedefs -** -*******************************************************************************/ - -/******************************************************************************* -** -** Local function prototypes -** -*******************************************************************************/ - -static unsigned int GetCurrentSystemLoad(SK_AC *pAC); -static SK_U64 GetIsrCalls(SK_AC *pAC); -static SK_BOOL IsIntModEnabled(SK_AC *pAC); -static void SetCurrIntCtr(SK_AC *pAC); -static void EnableIntMod(SK_AC *pAC); -static void DisableIntMod(SK_AC *pAC); -static void ResizeDimTimerDuration(SK_AC *pAC); -static void DisplaySelectedModerationType(SK_AC *pAC); -static void DisplaySelectedModerationMask(SK_AC *pAC); -static void DisplayDescrRatio(SK_AC *pAC); - -/******************************************************************************* -** -** Global variables -** -*******************************************************************************/ - -/******************************************************************************* -** -** Local variables -** -*******************************************************************************/ - -/******************************************************************************* -** -** Global functions -** -*******************************************************************************/ - -/******************************************************************************* -** Function : SkDimModerate -** Description : Called in every ISR to check if moderation is to be applied -** or not for the current number of interrupts -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimModerate(SK_AC *pAC) { - unsigned int CurrSysLoad = 0; /* expressed in percent */ - unsigned int LoadIncrease = 0; /* expressed in percent */ - SK_U64 ThresholdInts = 0; - SK_U64 IsrCallsPerSec = 0; - -#define M_DIMINFO pAC->DynIrqModInfo - - if (!IsIntModEnabled(pAC)) { - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - CurrSysLoad = GetCurrentSystemLoad(pAC); - if (CurrSysLoad > 75) { - /* - ** More than 75% total system load! Enable the moderation - ** to shield the system against too many interrupts. - */ - EnableIntMod(pAC); - } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) { - LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad); - if (LoadIncrease > ((M_DIMINFO.PrevSysLoad * - C_INT_MOD_ENABLE_PERCENTAGE) / 100)) { - if (CurrSysLoad > 10) { - /* - ** More than 50% increase with respect to the - ** previous load of the system. Most likely this - ** is due to our ISR-proc... - */ - EnableIntMod(pAC); - } - } - } else { - /* - ** Neither too much system load at all nor too much increase - ** with respect to the previous system load. Hence, we can leave - ** the ISR-handling like it is without enabling moderation. - */ - } - M_DIMINFO.PrevSysLoad = CurrSysLoad; - } - } else { - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec * - C_INT_MOD_DISABLE_PERCENTAGE) / 100); - IsrCallsPerSec = GetIsrCalls(pAC); - if (IsrCallsPerSec <= ThresholdInts) { - /* - ** The number of interrupts within the last second is - ** lower than the disable_percentage of the desried - ** maxrate. Therefore we can disable the moderation. - */ - DisableIntMod(pAC); - M_DIMINFO.MaxModIntsPerSec = - (M_DIMINFO.MaxModIntsPerSecUpperLimit + - M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2; - } else { - /* - ** The number of interrupts per sec is the same as expected. - ** Evalulate the descriptor-ratio. If it has changed, a resize - ** in the moderation timer might be useful - */ - if (M_DIMINFO.AutoSizing) { - ResizeDimTimerDuration(pAC); - } - } - } - } - - /* - ** Some information to the log... - */ - if (M_DIMINFO.DisplayStats) { - DisplaySelectedModerationType(pAC); - DisplaySelectedModerationMask(pAC); - DisplayDescrRatio(pAC); - } - - M_DIMINFO.NbrProcessedDescr = 0; - SetCurrIntCtr(pAC); -} - -/******************************************************************************* -** Function : SkDimStartModerationTimer -** Description : Starts the audit-timer for the dynamic interrupt moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimStartModerationTimer(SK_AC *pAC) { - SK_EVPARA EventParam; /* Event struct for timer event */ - - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = SK_DRV_MODERATION_TIMER; - SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer, - SK_DRV_MODERATION_TIMER_LENGTH, - SKGE_DRV, SK_DRV_TIMER, EventParam); -} - -/******************************************************************************* -** Function : SkDimEnableModerationIfNeeded -** Description : Either enables or disables moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : This function is called when a particular adapter is opened -** There is no Disable function, because when all interrupts -** might be disable, the moderation timer has no meaning at all -******************************************************************************/ - -void -SkDimEnableModerationIfNeeded(SK_AC *pAC) { - - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) { - EnableIntMod(pAC); /* notification print in this function */ - } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - SkDimStartModerationTimer(pAC); - if (M_DIMINFO.DisplayStats) { - printk("Dynamic moderation has been enabled\n"); - } - } else { - if (M_DIMINFO.DisplayStats) { - printk("No moderation has been enabled\n"); - } - } -} - -/******************************************************************************* -** Function : SkDimDisplayModerationSettings -** Description : Displays the current settings regarding interrupt moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimDisplayModerationSettings(SK_AC *pAC) { - DisplaySelectedModerationType(pAC); - DisplaySelectedModerationMask(pAC); -} - -/******************************************************************************* -** -** Local functions -** -*******************************************************************************/ - -/******************************************************************************* -** Function : GetCurrentSystemLoad -** Description : Retrieves the current system load of the system. This load -** is evaluated for all processors within the system. -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : unsigned int: load expressed in percentage -** Notes : The possible range being returned is from 0 up to 100. -** Whereas 0 means 'no load at all' and 100 'system fully loaded' -** It is impossible to determine what actually causes the system -** to be in 100%, but maybe that is due to too much interrupts. -*******************************************************************************/ - -static unsigned int -GetCurrentSystemLoad(SK_AC *pAC) { - unsigned long jif = jiffies; - unsigned int UserTime = 0; - unsigned int SystemTime = 0; - unsigned int NiceTime = 0; - unsigned int IdleTime = 0; - unsigned int TotalTime = 0; - unsigned int UsedTime = 0; - unsigned int SystemLoad = 0; - - /* unsigned int NbrCpu = 0; */ - - /* - ** The following lines have been commented out, because - ** from kernel 2.5.44 onwards, the kernel-owned structure - ** - ** struct kernel_stat kstat - ** - ** is not marked as an exported symbol in the file - ** - ** kernel/ksyms.c - ** - ** As a consequence, using this driver as KLM is not possible - ** and any access of the structure kernel_stat via the - ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided. - ** - ** The kstat-information might be added again in future - ** versions of the 2.5.xx kernel, but for the time being, - ** number of interrupts will serve as indication how much - ** load we currently have... - ** - ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) { - ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user; - ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice; - ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system; - ** } - */ - SK_U64 ThresholdInts = 0; - SK_U64 IsrCallsPerSec = 0; - - ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec * - C_INT_MOD_ENABLE_PERCENTAGE) + 100); - IsrCallsPerSec = GetIsrCalls(pAC); - if (IsrCallsPerSec >= ThresholdInts) { - /* - ** We do not know how much the real CPU-load is! - ** Return 80% as a default in order to activate DIM - */ - SystemLoad = 80; - return (SystemLoad); - } - - UsedTime = UserTime + NiceTime + SystemTime; - - IdleTime = jif * num_online_cpus() - UsedTime; - TotalTime = UsedTime + IdleTime; - - SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) / - (TotalTime - M_DIMINFO.PrevTotalTime); - - if (M_DIMINFO.DisplayStats) { - printk("Current system load is: %u\n", SystemLoad); - } - - M_DIMINFO.PrevTotalTime = TotalTime; - M_DIMINFO.PrevUsedTime = UsedTime; - - return (SystemLoad); -} - -/******************************************************************************* -** Function : GetIsrCalls -** Description : Depending on the selected moderation mask, this function will -** return the number of interrupts handled in the previous time- -** frame. This evaluated number is based on the current number -** of interrupts stored in PNMI-context and the previous stored -** interrupts. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : int: the number of interrupts being executed in the last -** timeframe -** Notes : It makes only sense to call this function, when dynamic -** interrupt moderation is applied -*******************************************************************************/ - -static SK_U64 -GetIsrCalls(SK_AC *pAC) { - SK_U64 RxPort0IntDiff = 0; - SK_U64 RxPort1IntDiff = 0; - SK_U64 TxPort0IntDiff = 0; - SK_U64 TxPort1IntDiff = 0; - - if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) { - if (pAC->GIni.GIMacsFound == 2) { - TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - - pAC->DynIrqModInfo.PrevPort1TxIntrCts; - } - TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - - pAC->DynIrqModInfo.PrevPort0TxIntrCts; - } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) { - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - } else { - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - - pAC->DynIrqModInfo.PrevPort1TxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - - pAC->DynIrqModInfo.PrevPort0TxIntrCts; - } - - return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff); -} - -/******************************************************************************* -** Function : GetRxCalls -** Description : This function will return the number of times a receive inter- -** rupt was processed. This is needed to evaluate any resizing -** factor. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : SK_U64: the number of RX-ints being processed -** Notes : It makes only sense to call this function, when dynamic -** interrupt moderation is applied -*******************************************************************************/ - -static SK_U64 -GetRxCalls(SK_AC *pAC) { - SK_U64 RxPort0IntDiff = 0; - SK_U64 RxPort1IntDiff = 0; - - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - - return (RxPort0IntDiff + RxPort1IntDiff); -} - -/******************************************************************************* -** Function : SetCurrIntCtr -** Description : Will store the current number orf occured interrupts in the -** adapter context. This is needed to evaluated the number of -** interrupts within a current timeframe. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -static void -SetCurrIntCtr(SK_AC *pAC) { - if (pAC->GIni.GIMacsFound == 2) { - pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts; - pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts; - } - pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts; - pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts; -} - -/******************************************************************************* -** Function : IsIntModEnabled() -** Description : Retrieves the current value of the interrupts moderation -** command register. Its content determines whether any -** moderation is running or not. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : SK_TRUE : if mod timer running -** SK_FALSE : if no moderation is being performed -** Notes : - -*******************************************************************************/ - -static SK_BOOL -IsIntModEnabled(SK_AC *pAC) { - unsigned long CtrCmd; - - SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd); - if ((CtrCmd & TIM_START) == TIM_START) { - return SK_TRUE; - } else { - return SK_FALSE; - } -} - -/******************************************************************************* -** Function : EnableIntMod() -** Description : Enables the interrupt moderation using the values stored in -** in the pAC->DynIntMod data structure -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : - -** Notes : - -*******************************************************************************/ - -static void -EnableIntMod(SK_AC *pAC) { - unsigned long ModBase; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec; - } else { - ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec; - } - - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); - SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration); - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); - if (M_DIMINFO.DisplayStats) { - printk("Enabled interrupt moderation (%i ints/sec)\n", - M_DIMINFO.MaxModIntsPerSec); - } -} - -/******************************************************************************* -** Function : DisableIntMod() -** Description : Disables the interrupt moderation independent of what inter- -** rupts are running or not -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : - -** Notes : - -*******************************************************************************/ - -static void -DisableIntMod(SK_AC *pAC) { - - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP); - if (M_DIMINFO.DisplayStats) { - printk("Disabled interrupt moderation\n"); - } -} - -/******************************************************************************* -** Function : ResizeDimTimerDuration(); -** Description : Checks the current used descriptor ratio and resizes the -** duration timer (longer/smaller) if possible. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : - -** Notes : There are both maximum and minimum timer duration value. -** This function assumes that interrupt moderation is already -** enabled! -*******************************************************************************/ - -static void -ResizeDimTimerDuration(SK_AC *pAC) { - SK_BOOL IncreaseTimerDuration; - int TotalMaxNbrDescr; - int UsedDescrRatio; - int RatioDiffAbs; - int RatioDiffRel; - int NewMaxModIntsPerSec; - int ModAdjValue; - long ModBase; - - /* - ** Check first if we are allowed to perform any modification - */ - if (IsIntModEnabled(pAC)) { - if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) { - return; - } else { - if (M_DIMINFO.ModJustEnabled) { - M_DIMINFO.ModJustEnabled = SK_FALSE; - return; - } - } - } - - /* - ** If we got until here, we have to evaluate the amount of the - ** descriptor ratio change... - */ - TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC); - UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr; - - if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) { - RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */ - } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) { - RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */ - } else { - RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */ - } - - /* - ** Now we can determine the change in percent - */ - if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } - - if (IncreaseTimerDuration) { - NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec + - (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100; - } else { - NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec - - (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100; - } - - /* - ** Check if we exceed boundaries... - */ - if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) || - (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) { - if (M_DIMINFO.DisplayStats) { - printk("Cannot change ModTim from %i to %i ints/sec\n", - M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec); - } - return; - } else { - if (M_DIMINFO.DisplayStats) { - printk("Resized ModTim from %i to %i ints/sec\n", - M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec); - } - } - - M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec; - } else { - ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec; - } - - /* - ** We do not need to touch any other registers - */ - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); -} - -/******************************************************************************* -** Function : DisplaySelectedModerationType() -** Description : Displays what type of moderation we have -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplaySelectedModerationType(SK_AC *pAC) { - - if (pAC->DynIrqModInfo.DisplayStats) { - if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) { - printk("Static int moderation runs with %i INTS/sec\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - if (IsIntModEnabled(pAC)) { - printk("Dynamic int moderation runs with %i INTS/sec\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - } else { - printk("Dynamic int moderation currently not applied\n"); - } - } else { - printk("No interrupt moderation selected!\n"); - } - } -} - -/******************************************************************************* -** Function : DisplaySelectedModerationMask() -** Description : Displays what interrupts are moderated -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplaySelectedModerationMask(SK_AC *pAC) { - - if (pAC->DynIrqModInfo.DisplayStats) { - if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) { - switch (pAC->DynIrqModInfo.MaskIrqModeration) { - case IRQ_MASK_TX_ONLY: - printk("Only Tx-interrupts are moderated\n"); - break; - case IRQ_MASK_RX_ONLY: - printk("Only Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_ONLY: - printk("Only special-interrupts are moderated\n"); - break; - case IRQ_MASK_TX_RX: - printk("Tx- and Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_RX: - printk("Special- and Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_TX: - printk("Special- and Tx-interrupts are moderated\n"); - break; - case IRQ_MASK_RX_TX_SP: - printk("All Rx-, Tx and special-interrupts are moderated\n"); - break; - default: - printk("Don't know what is moderated\n"); - break; - } - } else { - printk("No specific interrupts masked for moderation\n"); - } - } -} - -/******************************************************************************* -** Function : DisplayDescrRatio -** Description : Like the name states... -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplayDescrRatio(SK_AC *pAC) { - int TotalMaxNbrDescr = 0; - - if (pAC->DynIrqModInfo.DisplayStats) { - TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC); - printk("Ratio descriptors: %i/%i\n", - M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr); - } -} - -/******************************************************************************* -** -** End of file -** -*******************************************************************************/ diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c deleted file mode 100644 index 36460694eb82..000000000000 --- a/drivers/net/sk98lin/skethtool.c +++ /dev/null @@ -1,628 +0,0 @@ -/****************************************************************************** - * - * Name: skethtool.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.7 $ - * Date: $Date: 2004/09/29 13:32:07 $ - * Purpose: All functions regarding ethtool handling - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2004 Marvell. - * - * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet - * Server Adapters. - * - * Author: Ralph Roesler (rroesler@syskonnect.de) - * Mirko Lindner (mlindner@syskonnect.de) - * - * Address all question to: linux@syskonnect.de - * - * The technical manual for the adapters is available from SysKonnect's - * web pages: www.syskonnect.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - *****************************************************************************/ - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" -#include "h/skversion.h" - -#include -#include -#include - -/****************************************************************************** - * - * Defines - * - *****************************************************************************/ - -#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ - SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ - SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \ - SUPPORTED_TP) - -#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ - ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \ - ADVERTISED_TP) - -#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \ - SUPPORTED_FIBRE | \ - SUPPORTED_Autoneg) - -#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \ - ADVERTISED_FIBRE | \ - ADVERTISED_Autoneg) - - -/****************************************************************************** - * - * Local Functions - * - *****************************************************************************/ - -/***************************************************************************** - * - * getSettings - retrieves the current settings of the selected adapter - * - * Description: - * The current configuration of the selected adapter is returned. - * This configuration involves a)speed, b)duplex and c)autoneg plus - * a number of other variables. - * - * Returns: always 0 - * - */ -static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd) -{ - const DEV_NET *pNet = netdev_priv(dev); - int port = pNet->PortNr; - const SK_AC *pAC = pNet->pAC; - const SK_GEPORT *pPort = &pAC->GIni.GP[port]; - - static int DuplexAutoNegConfMap[9][3]= { - { -1 , -1 , -1 }, - { 0 , -1 , -1 }, - { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE }, - { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE }, - { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE }, - { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE }, - { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE }, - { SK_LMODE_AUTOSENSE , -1 , -1 }, - { SK_LMODE_INDETERMINATED, -1 , -1 } - }; - static int SpeedConfMap[6][2] = { - { 0 , -1 }, - { SK_LSPEED_AUTO , -1 }, - { SK_LSPEED_10MBPS , SPEED_10 }, - { SK_LSPEED_100MBPS , SPEED_100 }, - { SK_LSPEED_1000MBPS , SPEED_1000 }, - { SK_LSPEED_INDETERMINATED, -1 } - }; - static int AdvSpeedMap[6][2] = { - { 0 , -1 }, - { SK_LSPEED_AUTO , -1 }, - { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full }, - { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full }, - { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full}, - { SK_LSPEED_INDETERMINATED, -1 } - }; - - ecmd->phy_address = port; - ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1]; - ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1]; - ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2]; - ecmd->transceiver = XCVR_INTERNAL; - - if (pAC->GIni.GICopperType) { - ecmd->port = PORT_TP; - ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg); - if (pAC->GIni.GIGenesis) { - ecmd->supported &= ~(SUPPORTED_10baseT_Half); - ecmd->supported &= ~(SUPPORTED_10baseT_Full); - ecmd->supported &= ~(SUPPORTED_100baseT_Half); - ecmd->supported &= ~(SUPPORTED_100baseT_Full); - } else { - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { - ecmd->supported &= ~(SUPPORTED_1000baseT_Half); - } -#ifdef CHIP_ID_YUKON_FE - if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { - ecmd->supported &= ~(SUPPORTED_1000baseT_Half); - ecmd->supported &= ~(SUPPORTED_1000baseT_Full); - } -#endif - } - if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) { - ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1]; - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { - ecmd->advertising &= ~(SUPPORTED_1000baseT_Half); - } - } else { - ecmd->advertising = ecmd->supported; - } - - if (ecmd->autoneg == AUTONEG_ENABLE) - ecmd->advertising |= ADVERTISED_Autoneg; - } else { - ecmd->port = PORT_FIBRE; - ecmd->supported = SUPP_FIBRE_ALL; - ecmd->advertising = ADV_FIBRE_ALL; - } - return 0; -} - -/* - * MIB infrastructure uses instance value starting at 1 - * based on board and port. - */ -static inline u32 pnmiInstance(const DEV_NET *pNet) -{ - return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr; -} - -/***************************************************************************** - * - * setSettings - configures the settings of a selected adapter - * - * Description: - * Possible settings that may be altered are a)speed, b)duplex or - * c)autonegotiation. - * - * Returns: - * 0: everything fine, no error - * <0: the return value is the error code of the failure - */ -static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - u32 instance; - char buf[4]; - int len = 1; - - if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100 - && ecmd->speed != SPEED_1000) - return -EINVAL; - - if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) - return -EINVAL; - - if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) - return -EINVAL; - - if (ecmd->autoneg == AUTONEG_DISABLE) - *buf = (ecmd->duplex == DUPLEX_FULL) - ? SK_LMODE_FULL : SK_LMODE_HALF; - else - *buf = (ecmd->duplex == DUPLEX_FULL) - ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF; - - instance = pnmiInstance(pNet); - if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, - &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK) - return -EINVAL; - - switch(ecmd->speed) { - case SPEED_1000: - *buf = SK_LSPEED_1000MBPS; - break; - case SPEED_100: - *buf = SK_LSPEED_100MBPS; - break; - case SPEED_10: - *buf = SK_LSPEED_10MBPS; - } - - if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, - &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK) - return -EINVAL; - - return 0; -} - -/***************************************************************************** - * - * getDriverInfo - returns generic driver and adapter information - * - * Description: - * Generic driver information is returned via this function, such as - * the name of the driver, its version and and firmware version. - * In addition to this, the location of the selected adapter is - * returned as a bus info string (e.g. '01:05.0'). - * - * Returns: N/A - * - */ -static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - const DEV_NET *pNet = netdev_priv(dev); - const SK_AC *pAC = pNet->pAC; - char vers[32]; - - snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)", - (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf); - - strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver)); - strcpy(info->version, vers); - strcpy(info->fw_version, "N/A"); - strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN); -} - -/* - * Ethtool statistics support. - */ -static const char StringsStats[][ETH_GSTRING_LEN] = { - "rx_packets", "tx_packets", - "rx_bytes", "tx_bytes", - "rx_errors", "tx_errors", - "rx_dropped", "tx_dropped", - "multicasts", "collisions", - "rx_length_errors", "rx_buffer_overflow_errors", - "rx_crc_errors", "rx_frame_errors", - "rx_too_short_errors", "rx_too_long_errors", - "rx_carrier_extension_errors", "rx_symbol_errors", - "rx_llc_mac_size_errors", "rx_carrier_errors", - "rx_jabber_errors", "rx_missed_errors", - "tx_abort_collision_errors", "tx_carrier_errors", - "tx_buffer_underrun_errors", "tx_heartbeat_errors", - "tx_window_errors", -}; - -static int getStatsCount(struct net_device *dev) -{ - return ARRAY_SIZE(StringsStats); -} - -static void getStrings(struct net_device *dev, u32 stringset, u8 *data) -{ - switch(stringset) { - case ETH_SS_STATS: - memcpy(data, *StringsStats, sizeof(StringsStats)); - break; - } -} - -static void getEthtoolStats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data) -{ - const DEV_NET *pNet = netdev_priv(dev); - const SK_AC *pAC = pNet->pAC; - const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct; - - *data++ = pPnmiStruct->Stat[0].StatRxOkCts; - *data++ = pPnmiStruct->Stat[0].StatTxOkCts; - *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts; - *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts; - *data++ = pPnmiStruct->InErrorsCts; - *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts; - *data++ = pPnmiStruct->RxNoBufCts; - *data++ = pPnmiStruct->TxNoBufCts; - *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts; - *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts; - *data++ = pPnmiStruct->Stat[0].StatRxRuntCts; - *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts; - *data++ = pPnmiStruct->Stat[0].StatRxFcsCts; - *data++ = pPnmiStruct->Stat[0].StatRxFramingCts; - *data++ = pPnmiStruct->Stat[0].StatRxShortsCts; - *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts; - *data++ = pPnmiStruct->Stat[0].StatRxCextCts; - *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts; - *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts; - *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts; - *data++ = pPnmiStruct->Stat[0].StatRxJabberCts; - *data++ = pPnmiStruct->Stat[0].StatRxMissedCts; - *data++ = pAC->stats.tx_aborted_errors; - *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts; - *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts; - *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts; - *data++ = pAC->stats.tx_window_errors; -} - - -/***************************************************************************** - * - * toggleLeds - Changes the LED state of an adapter - * - * Description: - * This function changes the current state of all LEDs of an adapter so - * that it can be located by a user. - * - * Returns: N/A - * - */ -static void toggleLeds(DEV_NET *pNet, int on) -{ - SK_AC *pAC = pNet->pAC; - int port = pNet->PortNr; - void __iomem *io = pAC->IoBase; - - if (pAC->GIni.GIGenesis) { - SK_OUT8(io, MR_ADDR(port,LNK_LED_REG), - on ? SK_LNK_ON : SK_LNK_OFF); - SkGeYellowLED(pAC, io, - on ? (LED_ON >> 1) : (LED_OFF >> 1)); - SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI), - on ? SK_LED_TST : SK_LED_DIS); - - if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) - SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL, - on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF); - else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) - SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG, - on ? 0x0800 : PHY_L_LC_LEDT); - else - SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI), - on ? SK_LED_TST : SK_LED_DIS); - } else { - const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) | - PHY_M_LED_MO_10(MO_LED_ON) | - PHY_M_LED_MO_100(MO_LED_ON) | - PHY_M_LED_MO_1000(MO_LED_ON) | - PHY_M_LED_MO_RX(MO_LED_ON)); - const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) | - PHY_M_LED_MO_10(MO_LED_OFF) | - PHY_M_LED_MO_100(MO_LED_OFF) | - PHY_M_LED_MO_1000(MO_LED_OFF) | - PHY_M_LED_MO_RX(MO_LED_OFF)); - - - SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0); - SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER, - on ? YukLedOn : YukLedOff); - } -} - -/***************************************************************************** - * - * skGeBlinkTimer - Changes the LED state of an adapter - * - * Description: - * This function changes the current state of all LEDs of an adapter so - * that it can be located by a user. If the requested time interval for - * this test has elapsed, this function cleans up everything that was - * temporarily setup during the locate NIC test. This involves of course - * also closing or opening any adapter so that the initial board state - * is recovered. - * - * Returns: N/A - * - */ -void SkGeBlinkTimer(unsigned long data) -{ - struct net_device *dev = (struct net_device *) data; - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - toggleLeds(pNet, pAC->LedsOn); - - pAC->LedsOn = !pAC->LedsOn; - mod_timer(&pAC->BlinkTimer, jiffies + HZ/4); -} - -/***************************************************************************** - * - * locateDevice - start the locate NIC feature of the elected adapter - * - * Description: - * This function is used if the user want to locate a particular NIC. - * All LEDs are regularly switched on and off, so the NIC can easily - * be identified. - * - * Returns: - * ==0: everything fine, no error, locateNIC test was started - * !=0: one locateNIC test runs already - * - */ -static int locateDevice(struct net_device *dev, u32 data) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) - data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); - - /* start blinking */ - pAC->LedsOn = 0; - mod_timer(&pAC->BlinkTimer, jiffies); - msleep_interruptible(data * 1000); - del_timer_sync(&pAC->BlinkTimer); - toggleLeds(pNet, 0); - - return 0; -} - -/***************************************************************************** - * - * getPauseParams - retrieves the pause parameters - * - * Description: - * All current pause parameters of a selected adapter are placed - * in the passed ethtool_pauseparam structure and are returned. - * - * Returns: N/A - * - */ -static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr]; - - epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || - (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM); - - epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND); - epause->autoneg = epause->rx_pause || epause->tx_pause; -} - -/***************************************************************************** - * - * setPauseParams - configures the pause parameters of an adapter - * - * Description: - * This function sets the Rx or Tx pause parameters - * - * Returns: - * ==0: everything fine, no error - * !=0: the return value is the error code of the failure - */ -static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr]; - u32 instance = pnmiInstance(pNet); - struct ethtool_pauseparam old; - u8 oldspeed = pPort->PLinkSpeedUsed; - char buf[4]; - int len = 1; - int ret; - - /* - ** we have to determine the current settings to see if - ** the operator requested any modification of the flow - ** control parameters... - */ - getPauseParams(dev, &old); - - /* - ** perform modifications regarding the changes - ** requested by the operator - */ - if (epause->autoneg != old.autoneg) - *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC; - else { - if (epause->rx_pause && epause->tx_pause) - *buf = SK_FLOW_MODE_SYMMETRIC; - else if (epause->rx_pause && !epause->tx_pause) - *buf = SK_FLOW_MODE_SYM_OR_REM; - else if (!epause->rx_pause && epause->tx_pause) - *buf = SK_FLOW_MODE_LOC_SEND; - else - *buf = SK_FLOW_MODE_NONE; - } - - ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE, - &buf, &len, instance, pNet->NetNr); - - if (ret != SK_PNMI_ERR_OK) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, - ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret)); - goto err; - } - - /* - ** It may be that autoneg has been disabled! Therefore - ** set the speed to the previously used value... - */ - if (!epause->autoneg) { - len = 1; - ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, - &oldspeed, &len, instance, pNet->NetNr); - if (ret != SK_PNMI_ERR_OK) - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, - ("ethtool (sk98lin): error setting speed (%i)\n", ret)); - } - err: - return ret ? -EIO : 0; -} - -/* Only Yukon supports checksum offload. */ -static int setScatterGather(struct net_device *dev, u32 data) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) - return -EOPNOTSUPP; - return ethtool_op_set_sg(dev, data); -} - -static int setTxCsum(struct net_device *dev, u32 data) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) - return -EOPNOTSUPP; - - return ethtool_op_set_tx_csum(dev, data); -} - -static u32 getRxCsum(struct net_device *dev) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - return pAC->RxPort[pNet->PortNr].RxCsum; -} - -static int setRxCsum(struct net_device *dev, u32 data) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) - return -EOPNOTSUPP; - - pAC->RxPort[pNet->PortNr].RxCsum = data != 0; - return 0; -} - -static int getRegsLen(struct net_device *dev) -{ - return 0x4000; -} - -/* - * Returns copy of whole control register region - * Note: skip RAM address register because accessing it will - * cause bus hangs! - */ -static void getRegs(struct net_device *dev, struct ethtool_regs *regs, - void *p) -{ - DEV_NET *pNet = netdev_priv(dev); - const void __iomem *io = pNet->pAC->IoBase; - - regs->version = 1; - memset(p, 0, regs->len); - memcpy_fromio(p, io, B3_RAM_ADDR); - - memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, - regs->len - B3_RI_WTO_R1); -} - -const struct ethtool_ops SkGeEthtoolOps = { - .get_settings = getSettings, - .set_settings = setSettings, - .get_drvinfo = getDriverInfo, - .get_strings = getStrings, - .get_stats_count = getStatsCount, - .get_ethtool_stats = getEthtoolStats, - .phys_id = locateDevice, - .get_pauseparam = getPauseParams, - .set_pauseparam = setPauseParams, - .get_link = ethtool_op_get_link, - .get_perm_addr = ethtool_op_get_perm_addr, - .get_sg = ethtool_op_get_sg, - .set_sg = setScatterGather, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = setTxCsum, - .get_rx_csum = getRxCsum, - .set_rx_csum = setRxCsum, - .get_regs = getRegs, - .get_regs_len = getRegsLen, -}; diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c deleted file mode 100644 index bf218621db16..000000000000 --- a/drivers/net/sk98lin/skge.c +++ /dev/null @@ -1,5211 +0,0 @@ -/****************************************************************************** - * - * Name: skge.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.45 $ - * Date: $Date: 2004/02/12 14:41:02 $ - * Purpose: The main driver source module - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet - * Server Adapters. - * - * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and - * SysKonnects GEnesis Solaris driver - * Author: Christoph Goos (cgoos@syskonnect.de) - * Mirko Lindner (mlindner@syskonnect.de) - * - * Address all question to: linux@syskonnect.de - * - * The technical manual for the adapters is available from SysKonnect's - * web pages: www.syskonnect.com - * Goto "Support" and search Knowledge Base for "manual". - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Possible compiler options (#define xxx / -Dxxx): - * - * debugging can be enable by changing SK_DEBUG_CHKMOD and - * SK_DEBUG_CHKCAT in makefile (described there). - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This is the main module of the Linux GE driver. - * - * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h - * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters. - * Those are used for drivers on multiple OS', so some thing may seem - * unnecessary complicated on Linux. Please do not try to 'clean up' - * them without VERY good reasons, because this will make it more - * difficult to keep the Linux driver in synchronisation with the - * other versions. - * - * Include file hierarchy: - * - * - * - * "h/skdrv1st.h" - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * those three depending on kernel version used: - * - * - * - * - * - * "h/skerror.h" - * "h/skdebug.h" - * "h/sktypes.h" - * "h/lm80.h" - * "h/xmac_ii.h" - * - * "h/skdrv2nd.h" - * "h/skqueue.h" - * "h/skgehwt.h" - * "h/sktimer.h" - * "h/ski2c.h" - * "h/skgepnmi.h" - * "h/skvpd.h" - * "h/skgehw.h" - * "h/skgeinit.h" - * "h/skaddr.h" - * "h/skgesirq.h" - * "h/skrlmt.h" - * - ******************************************************************************/ - -#include "h/skversion.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" - -/******************************************************************************* - * - * Defines - * - ******************************************************************************/ - -/* for debuging on x86 only */ -/* #define BREAKPOINT() asm(" int $3"); */ - -/* use the transmit hw checksum driver functionality */ -#define USE_SK_TX_CHECKSUM - -/* use the receive hw checksum driver functionality */ -#define USE_SK_RX_CHECKSUM - -/* use the scatter-gather functionality with sendfile() */ -#define SK_ZEROCOPY - -/* use of a transmit complete interrupt */ -#define USE_TX_COMPLETE - -/* - * threshold for copying small receive frames - * set to 0 to avoid copying, set to 9001 to copy all frames - */ -#define SK_COPY_THRESHOLD 50 - -/* number of adapters that can be configured via command line params */ -#define SK_MAX_CARD_PARAM 16 - - - -/* - * use those defines for a compile-in version of the driver instead - * of command line parameters - */ -// #define LINK_SPEED_A {"Auto", } -// #define LINK_SPEED_B {"Auto", } -// #define AUTO_NEG_A {"Sense", } -// #define AUTO_NEG_B {"Sense", } -// #define DUP_CAP_A {"Both", } -// #define DUP_CAP_B {"Both", } -// #define FLOW_CTRL_A {"SymOrRem", } -// #define FLOW_CTRL_B {"SymOrRem", } -// #define ROLE_A {"Auto", } -// #define ROLE_B {"Auto", } -// #define PREF_PORT {"A", } -// #define CON_TYPE {"Auto", } -// #define RLMT_MODE {"CheckLinkState", } - -#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) -#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) -#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) - - -/* Set blink mode*/ -#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \ - SK_DUP_LED_NORMAL | \ - SK_LED_LINK100_ON) - - -/* Isr return value */ -#define SkIsrRetVar irqreturn_t -#define SkIsrRetNone IRQ_NONE -#define SkIsrRetHandled IRQ_HANDLED - - -/******************************************************************************* - * - * Local Function Prototypes - * - ******************************************************************************/ - -static void FreeResources(struct SK_NET_DEVICE *dev); -static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); -static SK_BOOL BoardAllocMem(SK_AC *pAC); -static void BoardFreeMem(SK_AC *pAC); -static void BoardInitMem(SK_AC *pAC); -static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); -static SkIsrRetVar SkGeIsr(int irq, void *dev_id); -static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id); -static int SkGeOpen(struct SK_NET_DEVICE *dev); -static int SkGeClose(struct SK_NET_DEVICE *dev); -static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); -static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p); -static void SkGeSetRxMode(struct SK_NET_DEVICE *dev); -static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev); -static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd); -static void GetConfiguration(SK_AC*); -static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*); -static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*); -static void FillRxRing(SK_AC*, RX_PORT*); -static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); -static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); -static void ClearAndStartRx(SK_AC*, int); -static void ClearTxIrq(SK_AC*, int, int); -static void ClearRxRing(SK_AC*, RX_PORT*); -static void ClearTxRing(SK_AC*, TX_PORT*); -static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); -static void PortReInitBmu(SK_AC*, int); -static int SkGeIocMib(DEV_NET*, unsigned int, int); -static int SkGeInitPCI(SK_AC *pAC); -static void StartDrvCleanupTimer(SK_AC *pAC); -static void StopDrvCleanupTimer(SK_AC *pAC); -static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); - -#ifdef SK_DIAG_SUPPORT -static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); -static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); -static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); -#endif - -/******************************************************************************* - * - * Extern Function Prototypes - * - ******************************************************************************/ -extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); -extern void SkDimDisplayModerationSettings(SK_AC *pAC); -extern void SkDimStartModerationTimer(SK_AC *pAC); -extern void SkDimModerate(SK_AC *pAC); -extern void SkGeBlinkTimer(unsigned long data); - -#ifdef DEBUG -static void DumpMsg(struct sk_buff*, char*); -static void DumpData(char*, int); -static void DumpLong(char*, int); -#endif - -/* global variables *********************************************************/ -static SK_BOOL DoPrintInterfaceChange = SK_TRUE; -extern const struct ethtool_ops SkGeEthtoolOps; - -/* local variables **********************************************************/ -static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; -static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; - -/***************************************************************************** - * - * SkPciWriteCfgDWord - write a 32 bit value to pci config space - * - * Description: - * This routine writes a 32 bit value to the pci configuration - * space. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -static inline int SkPciWriteCfgDWord( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U32 Val) /* pointer to store the read value */ -{ - pci_write_config_dword(pAC->PciDev, PciAddr, Val); - return(0); -} /* SkPciWriteCfgDWord */ - -/***************************************************************************** - * - * SkGeInitPCI - Init the PCI resources - * - * Description: - * This function initialize the PCI resources and IO - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -static __devinit int SkGeInitPCI(SK_AC *pAC) -{ - struct SK_NET_DEVICE *dev = pAC->dev[0]; - struct pci_dev *pdev = pAC->PciDev; - int retval; - - dev->mem_start = pci_resource_start (pdev, 0); - pci_set_master(pdev); - - retval = pci_request_regions(pdev, "sk98lin"); - if (retval) - goto out; - -#ifdef SK_BIG_ENDIAN - /* - * On big endian machines, we use the adapter's aibility of - * reading the descriptors as big endian. - */ - { - SK_U32 our2; - SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); - our2 |= PCI_REV_DESC; - SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); - } -#endif - - /* - * Remap the regs into kernel space. - */ - pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000); - if (!pAC->IoBase) { - retval = -EIO; - goto out_release; - } - - return 0; - - out_release: - pci_release_regions(pdev); - out: - return retval; -} - - -/***************************************************************************** - * - * FreeResources - release resources allocated for adapter - * - * Description: - * This function releases the IRQ, unmaps the IO and - * frees the desriptor ring. - * - * Returns: N/A - * - */ -static void FreeResources(struct SK_NET_DEVICE *dev) -{ -SK_U32 AllocFlag; -DEV_NET *pNet; -SK_AC *pAC; - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - AllocFlag = pAC->AllocFlag; - if (pAC->PciDev) { - pci_release_regions(pAC->PciDev); - } - if (AllocFlag & SK_ALLOC_IRQ) { - free_irq(dev->irq, dev); - } - if (pAC->IoBase) { - iounmap(pAC->IoBase); - } - if (pAC->pDescrMem) { - BoardFreeMem(pAC); - } - -} /* FreeResources */ - -MODULE_AUTHOR("Mirko Lindner "); -MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); -MODULE_LICENSE("GPL"); - -#ifdef LINK_SPEED_A -static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; -#else -static char *Speed_A[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef LINK_SPEED_B -static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED; -#else -static char *Speed_B[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef AUTO_NEG_A -static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A; -#else -static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef DUP_CAP_A -static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A; -#else -static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef FLOW_CTRL_A -static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A; -#else -static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef ROLE_A -static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A; -#else -static char *Role_A[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef AUTO_NEG_B -static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B; -#else -static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef DUP_CAP_B -static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B; -#else -static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef FLOW_CTRL_B -static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B; -#else -static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef ROLE_B -static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B; -#else -static char *Role_B[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef CON_TYPE -static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE; -#else -static char *ConType[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef PREF_PORT -static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT; -#else -static char *PrefPort[SK_MAX_CARD_PARAM] = {"", }; -#endif - -#ifdef RLMT_MODE -static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE; -#else -static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; -#endif - -static int IntsPerSec[SK_MAX_CARD_PARAM]; -static char *Moderation[SK_MAX_CARD_PARAM]; -static char *ModerationMask[SK_MAX_CARD_PARAM]; -static char *AutoSizing[SK_MAX_CARD_PARAM]; -static char *Stats[SK_MAX_CARD_PARAM]; - -module_param_array(Speed_A, charp, NULL, 0); -module_param_array(Speed_B, charp, NULL, 0); -module_param_array(AutoNeg_A, charp, NULL, 0); -module_param_array(AutoNeg_B, charp, NULL, 0); -module_param_array(DupCap_A, charp, NULL, 0); -module_param_array(DupCap_B, charp, NULL, 0); -module_param_array(FlowCtrl_A, charp, NULL, 0); -module_param_array(FlowCtrl_B, charp, NULL, 0); -module_param_array(Role_A, charp, NULL, 0); -module_param_array(Role_B, charp, NULL, 0); -module_param_array(ConType, charp, NULL, 0); -module_param_array(PrefPort, charp, NULL, 0); -module_param_array(RlmtMode, charp, NULL, 0); -/* used for interrupt moderation */ -module_param_array(IntsPerSec, int, NULL, 0); -module_param_array(Moderation, charp, NULL, 0); -module_param_array(Stats, charp, NULL, 0); -module_param_array(ModerationMask, charp, NULL, 0); -module_param_array(AutoSizing, charp, NULL, 0); - -/***************************************************************************** - * - * SkGeBoardInit - do level 0 and 1 initialization - * - * Description: - * This function prepares the board hardware for running. The desriptor - * ring is set up, the IRQ is allocated and the configuration settings - * are examined. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) -{ -short i; -unsigned long Flags; -char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */ -char *VerStr = VER_STRING; -int Ret; /* return code of request_irq */ -SK_BOOL DualNet; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("IoBase: %08lX\n", (unsigned long)pAC->IoBase)); - for (i=0; iTxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0]; - pAC->TxPort[i][0].PortIndex = i; - pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i]; - pAC->RxPort[i].PortIndex = i; - } - - /* Initialize the mutexes */ - for (i=0; iTxPort[i][0].TxDesRingLock); - spin_lock_init(&pAC->RxPort[i].RxDesRingLock); - } - spin_lock_init(&pAC->SlowPathLock); - - /* setup phy_id blink timer */ - pAC->BlinkTimer.function = SkGeBlinkTimer; - pAC->BlinkTimer.data = (unsigned long) dev; - init_timer(&pAC->BlinkTimer); - - /* level 0 init common modules here */ - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - /* Does a RESET on board ...*/ - if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { - printk("HWInit (0) failed.\n"); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return -EIO; - } - SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); - SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); - - pAC->BoardLevel = SK_INIT_DATA; - pAC->RxBufSize = ETH_BUF_SIZE; - - SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString); - SK_PNMI_SET_DRIVER_VER(pAC, VerStr); - - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - /* level 1 init common modules here (HW init) */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { - printk("sk98lin: HWInit (1) failed.\n"); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return -EIO; - } - SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); - SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); - - /* Set chipset type support */ - pAC->ChipsetType = 0; - if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || - (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { - pAC->ChipsetType = 1; - } - - GetConfiguration(pAC); - if (pAC->RlmtNets == 2) { - pAC->GIni.GIPortUsage = SK_MUL_LINK; - } - - pAC->BoardLevel = SK_INIT_IO; - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - if (pAC->GIni.GIMacsFound == 2) { - Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); - } else if (pAC->GIni.GIMacsFound == 1) { - Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, - "sk98lin", dev); - } else { - printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", - pAC->GIni.GIMacsFound); - return -EIO; - } - - if (Ret) { - printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", - dev->irq); - return Ret; - } - pAC->AllocFlag |= SK_ALLOC_IRQ; - - /* Alloc memory for this board (Mem for RxD/TxD) : */ - if(!BoardAllocMem(pAC)) { - printk("No memory for descriptor rings.\n"); - return -ENOMEM; - } - - BoardInitMem(pAC); - /* tschilling: New common function with minimum size check. */ - DualNet = SK_FALSE; - if (pAC->RlmtNets == 2) { - DualNet = SK_TRUE; - } - - if (SkGeInitAssignRamToQueues( - pAC, - pAC->ActivePort, - DualNet)) { - BoardFreeMem(pAC); - printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); - return -EIO; - } - - return (0); -} /* SkGeBoardInit */ - - -/***************************************************************************** - * - * BoardAllocMem - allocate the memory for the descriptor rings - * - * Description: - * This function allocates the memory for all descriptor rings. - * Each ring is aligned for the desriptor alignment and no ring - * has a 4 GByte boundary in it (because the upper 32 bit must - * be constant for all descriptiors in one rings). - * - * Returns: - * SK_TRUE, if all memory could be allocated - * SK_FALSE, if not - */ -static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC) -{ -caddr_t pDescrMem; /* pointer to descriptor memory area */ -size_t AllocLength; /* length of complete descriptor area */ -int i; /* loop counter */ -unsigned long BusAddr; - - - /* rings plus one for alignment (do not cross 4 GB boundary) */ - /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */ -#if (BITS_PER_LONG == 32) - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; -#else - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound - + RX_RING_SIZE + 8; -#endif - - pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength, - &pAC->pDescrMemDMA); - - if (pDescrMem == NULL) { - return (SK_FALSE); - } - pAC->pDescrMem = pDescrMem; - BusAddr = (unsigned long) pAC->pDescrMemDMA; - - /* Descriptors need 8 byte alignment, and this is ensured - * by pci_alloc_consistent. - */ - for (i=0; iGIni.GIMacsFound; i++) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, - ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n", - i, (unsigned long) pDescrMem, - BusAddr)); - pAC->TxPort[i][0].pTxDescrRing = pDescrMem; - pAC->TxPort[i][0].VTxDescrRing = BusAddr; - pDescrMem += TX_RING_SIZE; - BusAddr += TX_RING_SIZE; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, - ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n", - i, (unsigned long) pDescrMem, - (unsigned long)BusAddr)); - pAC->RxPort[i].pRxDescrRing = pDescrMem; - pAC->RxPort[i].VRxDescrRing = BusAddr; - pDescrMem += RX_RING_SIZE; - BusAddr += RX_RING_SIZE; - } /* for */ - - return (SK_TRUE); -} /* BoardAllocMem */ - - -/**************************************************************************** - * - * BoardFreeMem - reverse of BoardAllocMem - * - * Description: - * Free all memory allocated in BoardAllocMem: adapter context, - * descriptor rings, locks. - * - * Returns: N/A - */ -static void BoardFreeMem( -SK_AC *pAC) -{ -size_t AllocLength; /* length of complete descriptor area */ - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("BoardFreeMem\n")); -#if (BITS_PER_LONG == 32) - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; -#else - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound - + RX_RING_SIZE + 8; -#endif - - pci_free_consistent(pAC->PciDev, AllocLength, - pAC->pDescrMem, pAC->pDescrMemDMA); - pAC->pDescrMem = NULL; -} /* BoardFreeMem */ - - -/***************************************************************************** - * - * BoardInitMem - initiate the descriptor rings - * - * Description: - * This function sets the descriptor rings up in memory. - * The adapter is initialized with the descriptor start addresses. - * - * Returns: N/A - */ -static __devinit void BoardInitMem(SK_AC *pAC) -{ -int i; /* loop counter */ -int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ -int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/ - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("BoardInitMem\n")); - - RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; - pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize; - TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; - pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize; - - for (i=0; iGIni.GIMacsFound; i++) { - SetupRing( - pAC, - pAC->TxPort[i][0].pTxDescrRing, - pAC->TxPort[i][0].VTxDescrRing, - (RXD**)&pAC->TxPort[i][0].pTxdRingHead, - (RXD**)&pAC->TxPort[i][0].pTxdRingTail, - (RXD**)&pAC->TxPort[i][0].pTxdRingPrev, - &pAC->TxPort[i][0].TxdRingFree, - SK_TRUE); - SetupRing( - pAC, - pAC->RxPort[i].pRxDescrRing, - pAC->RxPort[i].VRxDescrRing, - &pAC->RxPort[i].pRxdRingHead, - &pAC->RxPort[i].pRxdRingTail, - &pAC->RxPort[i].pRxdRingPrev, - &pAC->RxPort[i].RxdRingFree, - SK_FALSE); - } -} /* BoardInitMem */ - - -/***************************************************************************** - * - * SetupRing - create one descriptor ring - * - * Description: - * This function creates one descriptor ring in the given memory area. - * The head, tail and number of free descriptors in the ring are set. - * - * Returns: - * none - */ -static void SetupRing( -SK_AC *pAC, -void *pMemArea, /* a pointer to the memory area for the ring */ -uintptr_t VMemArea, /* the virtual bus address of the memory area */ -RXD **ppRingHead, /* address where the head should be written */ -RXD **ppRingTail, /* address where the tail should be written */ -RXD **ppRingPrev, /* address where the tail should be written */ -int *pRingFree, /* address where the # of free descr. goes */ -SK_BOOL IsTx) /* flag: is this a tx ring */ -{ -int i; /* loop counter */ -int DescrSize; /* the size of a descriptor rounded up to alignment*/ -int DescrNum; /* number of descriptors per ring */ -RXD *pDescr; /* pointer to a descriptor (receive or transmit) */ -RXD *pNextDescr; /* pointer to the next descriptor */ -RXD *pPrevDescr; /* pointer to the previous descriptor */ -uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */ - - if (IsTx == SK_TRUE) { - DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * - DESCR_ALIGN; - DescrNum = TX_RING_SIZE / DescrSize; - } else { - DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * - DESCR_ALIGN; - DescrNum = RX_RING_SIZE / DescrSize; - } - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, - ("Descriptor size: %d Descriptor Number: %d\n", - DescrSize,DescrNum)); - - pDescr = (RXD*) pMemArea; - pPrevDescr = NULL; - pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); - VNextDescr = VMemArea + DescrSize; - for(i=0; iVNextRxd = VNextDescr & 0xffffffffULL; - pDescr->pNextRxd = pNextDescr; - if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN; - - /* advance one step */ - pPrevDescr = pDescr; - pDescr = pNextDescr; - pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); - VNextDescr += DescrSize; - } - pPrevDescr->pNextRxd = (RXD*) pMemArea; - pPrevDescr->VNextRxd = VMemArea; - pDescr = (RXD*) pMemArea; - *ppRingHead = (RXD*) pMemArea; - *ppRingTail = *ppRingHead; - *ppRingPrev = pPrevDescr; - *pRingFree = DescrNum; -} /* SetupRing */ - - -/***************************************************************************** - * - * PortReInitBmu - re-initiate the descriptor rings for one port - * - * Description: - * This function reinitializes the descriptor rings of one port - * in memory. The port must be stopped before. - * The HW is initialized with the descriptor start addresses. - * - * Returns: - * none - */ -static void PortReInitBmu( -SK_AC *pAC, /* pointer to adapter context */ -int PortIndex) /* index of the port for which to re-init */ -{ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("PortReInitBmu ")); - - /* set address of first descriptor of ring in BMU */ - SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L, - (uint32_t)(((caddr_t) - (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + - pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) & - 0xFFFFFFFF)); - SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H, - (uint32_t)(((caddr_t) - (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + - pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32)); - SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L, - (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - - pAC->RxPort[PortIndex].pRxDescrRing + - pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF)); - SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H, - (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - - pAC->RxPort[PortIndex].pRxDescrRing + - pAC->RxPort[PortIndex].VRxDescrRing) >> 32)); -} /* PortReInitBmu */ - - -/**************************************************************************** - * - * SkGeIsr - handle adapter interrupts - * - * Description: - * The interrupt routine is called when the network adapter - * generates an interrupt. It may also be called if another device - * shares this interrupt vector with the driver. - * - * Returns: N/A - * - */ -static SkIsrRetVar SkGeIsr(int irq, void *dev_id) -{ -struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; -DEV_NET *pNet; -SK_AC *pAC; -SK_U32 IntSrc; /* interrupts source register contents */ - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - /* - * Check and process if its our interrupt - */ - SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); - if (IntSrc == 0) { - return SkIsrRetNone; - } - - while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { -#if 0 /* software irq currently not used */ - if (IntSrc & IS_IRQ_SW) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("Software IRQ\n")); - } -#endif - if (IntSrc & IS_R1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF RX1 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); - SK_PNMI_CNT_RX_INTR(pAC, 0); - } - if (IntSrc & IS_R2_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF RX2 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); - SK_PNMI_CNT_RX_INTR(pAC, 1); - } -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF AS TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 0); - spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - } - if (IntSrc & IS_XA2_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF AS TX2 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 1); - spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); - } -#if 0 /* only if sync. queues used */ - if (IntSrc & IS_XS1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF SY TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 1); - spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 0, TX_PRIO_HIGH); - } - if (IntSrc & IS_XS2_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF SY TX2 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 1); - spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 1, TX_PRIO_HIGH); - } -#endif -#endif - - /* do all IO at once */ - if (IntSrc & IS_R1_F) - ClearAndStartRx(pAC, 0); - if (IntSrc & IS_R2_F) - ClearAndStartRx(pAC, 1); -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) - ClearTxIrq(pAC, 0, TX_PRIO_LOW); - if (IntSrc & IS_XA2_F) - ClearTxIrq(pAC, 1, TX_PRIO_LOW); -#endif - SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); - } /* while (IntSrc & IRQ_MASK != 0) */ - - IntSrc &= pAC->GIni.GIValIrqMask; - if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, - ("SPECIAL IRQ DP-Cards => %x\n", IntSrc)); - pAC->CheckQueue = SK_FALSE; - spin_lock(&pAC->SlowPathLock); - if (IntSrc & SPECIAL_IRQS) - SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); - - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock(&pAC->SlowPathLock); - } - /* - * do it all again is case we cleared an interrupt that - * came in after handling the ring (OUTs may be delayed - * in hardware buffers, but are through after IN) - * - * rroesler: has been commented out and shifted to - * SkGeDrvEvent(), because it is timer - * guarded now - * - ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); - ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); - */ - - if (pAC->CheckQueue) { - pAC->CheckQueue = SK_FALSE; - spin_lock(&pAC->SlowPathLock); - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock(&pAC->SlowPathLock); - } - - /* IRQ is processed - Enable IRQs again*/ - SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - - return SkIsrRetHandled; -} /* SkGeIsr */ - - -/**************************************************************************** - * - * SkGeIsrOnePort - handle adapter interrupts for single port adapter - * - * Description: - * The interrupt routine is called when the network adapter - * generates an interrupt. It may also be called if another device - * shares this interrupt vector with the driver. - * This is the same as above, but handles only one port. - * - * Returns: N/A - * - */ -static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id) -{ -struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; -DEV_NET *pNet; -SK_AC *pAC; -SK_U32 IntSrc; /* interrupts source register contents */ - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - /* - * Check and process if its our interrupt - */ - SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); - if (IntSrc == 0) { - return SkIsrRetNone; - } - - while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { -#if 0 /* software irq currently not used */ - if (IntSrc & IS_IRQ_SW) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("Software IRQ\n")); - } -#endif - if (IntSrc & IS_R1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF RX1 IRQ\n")); - ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); - SK_PNMI_CNT_RX_INTR(pAC, 0); - } -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF AS TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 0); - spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); - spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); - } -#if 0 /* only if sync. queues used */ - if (IntSrc & IS_XS1_F) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_INT_SRC, - ("EOF SY TX1 IRQ\n")); - SK_PNMI_CNT_TX_INTR(pAC, 0); - spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); - spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 0, TX_PRIO_HIGH); - } -#endif -#endif - - /* do all IO at once */ - if (IntSrc & IS_R1_F) - ClearAndStartRx(pAC, 0); -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) - ClearTxIrq(pAC, 0, TX_PRIO_LOW); -#endif - SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); - } /* while (IntSrc & IRQ_MASK != 0) */ - - IntSrc &= pAC->GIni.GIValIrqMask; - if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, - ("SPECIAL IRQ SP-Cards => %x\n", IntSrc)); - pAC->CheckQueue = SK_FALSE; - spin_lock(&pAC->SlowPathLock); - if (IntSrc & SPECIAL_IRQS) - SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); - - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock(&pAC->SlowPathLock); - } - /* - * do it all again is case we cleared an interrupt that - * came in after handling the ring (OUTs may be delayed - * in hardware buffers, but are through after IN) - * - * rroesler: has been commented out and shifted to - * SkGeDrvEvent(), because it is timer - * guarded now - * - ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); - */ - - /* IRQ is processed - Enable IRQs again*/ - SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - - return SkIsrRetHandled; -} /* SkGeIsrOnePort */ - -#ifdef CONFIG_NET_POLL_CONTROLLER -/**************************************************************************** - * - * SkGePollController - polling receive, for netconsole - * - * Description: - * Polling receive - used by netconsole and other diagnostic tools - * to allow network i/o with interrupts disabled. - * - * Returns: N/A - */ -static void SkGePollController(struct net_device *dev) -{ - disable_irq(dev->irq); - SkGeIsr(dev->irq, dev); - enable_irq(dev->irq); -} -#endif - -/**************************************************************************** - * - * SkGeOpen - handle start of initialized adapter - * - * Description: - * This function starts the initialized adapter. - * The board level variable is set and the adapter is - * brought to full functionality. - * The device flags are set for operation. - * Do all necessary level 2 initialization, enable interrupts and - * give start command to RLMT. - * - * Returns: - * 0 on success - * != 0 on error - */ -static int SkGeOpen( -struct SK_NET_DEVICE *dev) -{ - DEV_NET *pNet; - SK_AC *pAC; - unsigned long Flags; /* for spin lock */ - int i; - SK_EVPARA EvPara; /* an event parameter union */ - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC)); - -#ifdef SK_DIAG_SUPPORT - if (pAC->DiagModeActive == DIAG_ACTIVE) { - if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { - return (-1); /* still in use by diag; deny actions */ - } - } -#endif - - /* Set blink mode */ - if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) - pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE; - - if (pAC->BoardLevel == SK_INIT_DATA) { - /* level 1 init common modules here */ - if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { - printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name); - return (-1); - } - SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO); - SkEventInit (pAC, pAC->IoBase, SK_INIT_IO); - SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO); - SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO); - SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO); - SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO); - pAC->BoardLevel = SK_INIT_IO; - } - - if (pAC->BoardLevel != SK_INIT_RUN) { - /* tschilling: Level 2 init modules here, check return value. */ - if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) { - printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name); - return (-1); - } - SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN); - SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN); - SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN); - SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN); - SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN); - SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN); - pAC->BoardLevel = SK_INIT_RUN; - } - - for (i=0; iGIni.GIMacsFound; i++) { - /* Enable transmit descriptor polling. */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); - } - SkGeYellowLED(pAC, pAC->IoBase, 1); - - StartDrvCleanupTimer(pAC); - SkDimEnableModerationIfNeeded(pAC); - SkDimDisplayModerationSettings(pAC); - - pAC->GIni.GIValIrqMask &= IRQ_MASK; - - /* enable Interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - - if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) { - EvPara.Para32[0] = pAC->RlmtNets; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, - EvPara); - EvPara.Para32[0] = pAC->RlmtMode; - EvPara.Para32[1] = 0; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE, - EvPara); - } - - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - pAC->MaxPorts++; - - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeOpen suceeded\n")); - - return (0); -} /* SkGeOpen */ - - -/**************************************************************************** - * - * SkGeClose - Stop initialized adapter - * - * Description: - * Close initialized adapter. - * - * Returns: - * 0 - on success - * error code - on error - */ -static int SkGeClose( -struct SK_NET_DEVICE *dev) -{ - DEV_NET *pNet; - DEV_NET *newPtrNet; - SK_AC *pAC; - - unsigned long Flags; /* for spin lock */ - int i; - int PortIdx; - SK_EVPARA EvPara; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - -#ifdef SK_DIAG_SUPPORT - if (pAC->DiagModeActive == DIAG_ACTIVE) { - if (pAC->DiagFlowCtrl == SK_FALSE) { - /* - ** notify that the interface which has been closed - ** by operator interaction must not be started up - ** again when the DIAG has finished. - */ - newPtrNet = netdev_priv(pAC->dev[0]); - if (newPtrNet == pNet) { - pAC->WasIfUp[0] = SK_FALSE; - } else { - pAC->WasIfUp[1] = SK_FALSE; - } - return 0; /* return to system everything is fine... */ - } else { - pAC->DiagFlowCtrl = SK_FALSE; - } - } -#endif - - netif_stop_queue(dev); - - if (pAC->RlmtNets == 1) - PortIdx = pAC->ActivePort; - else - PortIdx = pNet->NetNr; - - StopDrvCleanupTimer(pAC); - - /* - * Clear multicast table, promiscuous mode .... - */ - SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); - SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, - SK_PROM_MODE_NONE); - - if (pAC->MaxPorts == 1) { - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - /* stop the hardware */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = SK_INIT_DATA; - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - } else { - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - /* Stop port */ - spin_lock_irqsave(&pAC->TxPort[pNet->PortNr] - [TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, - SK_STOP_ALL, SK_HARD_RST); - spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr] - [TX_PRIO_LOW].TxDesRingLock, Flags); - } - - if (pAC->RlmtNets == 1) { - /* clear all descriptor rings */ - for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[i]); - ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]); - } - } else { - /* clear port descriptor rings */ - ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); - ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); - } - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeClose: done ")); - - SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); - SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), - sizeof(SK_PNMI_STRUCT_DATA)); - - pAC->MaxPorts--; - - return (0); -} /* SkGeClose */ - - -/***************************************************************************** - * - * SkGeXmit - Linux frame transmit function - * - * Description: - * The system calls this function to send frames onto the wire. - * It puts the frame in the tx descriptor ring. If the ring is - * full then, the 'tbusy' flag is set. - * - * Returns: - * 0, if everything is ok - * !=0, on error - * WARNING: returning 1 in 'tbusy' case caused system crashes (double - * allocated skb's) !!! - */ -static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev) -{ -DEV_NET *pNet; -SK_AC *pAC; -int Rc; /* return code of XmitFrame */ - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - if ((!skb_shinfo(skb)->nr_frags) || - (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) { - /* Don't activate scatter-gather and hardware checksum */ - - if (pAC->RlmtNets == 2) - Rc = XmitFrame( - pAC, - &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], - skb); - else - Rc = XmitFrame( - pAC, - &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], - skb); - } else { - /* scatter-gather and hardware TCP checksumming anabled*/ - if (pAC->RlmtNets == 2) - Rc = XmitFrameSG( - pAC, - &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW], - skb); - else - Rc = XmitFrameSG( - pAC, - &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW], - skb); - } - - /* Transmitter out of resources? */ - if (Rc <= 0) { - netif_stop_queue(dev); - } - - /* If not taken, give buffer ownership back to the - * queueing layer. - */ - if (Rc < 0) - return (1); - - dev->trans_start = jiffies; - return (0); -} /* SkGeXmit */ - - -/***************************************************************************** - * - * XmitFrame - fill one socket buffer into the transmit ring - * - * Description: - * This function puts a message into the transmit descriptor ring - * if there is a descriptors left. - * Linux skb's consist of only one continuous buffer. - * The first step locks the ring. It is held locked - * all time to avoid problems with SWITCH_../PORT_RESET. - * Then the descriptoris allocated. - * The second part is linking the buffer to the descriptor. - * At the very last, the Control field of the descriptor - * is made valid for the BMU and a start TX command is given - * if necessary. - * - * Returns: - * > 0 - on succes: the number of bytes in the message - * = 0 - on resource shortage: this frame sent or dropped, now - * the ring is full ( -> set tbusy) - * < 0 - on failure: other problems ( -> return failure to upper layers) - */ -static int XmitFrame( -SK_AC *pAC, /* pointer to adapter context */ -TX_PORT *pTxPort, /* pointer to struct of port to send to */ -struct sk_buff *pMessage) /* pointer to send-message */ -{ - TXD *pTxd; /* the rxd to fill */ - TXD *pOldTxd; - unsigned long Flags; - SK_U64 PhysAddr; - int BytesSend = pMessage->len; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X")); - - spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); -#ifndef USE_TX_COMPLETE - FreeTxDescriptors(pAC, pTxPort); -#endif - if (pTxPort->TxdRingFree == 0) { - /* - ** no enough free descriptors in ring at the moment. - ** Maybe free'ing some old one help? - */ - FreeTxDescriptors(pAC, pTxPort); - if (pTxPort->TxdRingFree == 0) { - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_TX_PROGRESS, - ("XmitFrame failed\n")); - /* - ** the desired message can not be sent - ** Because tbusy seems to be set, the message - ** should not be freed here. It will be used - ** by the scheduler of the ethernet handler - */ - return (-1); - } - } - - /* - ** If the passed socket buffer is of smaller MTU-size than 60, - ** copy everything into new buffer and fill all bytes between - ** the original packet end and the new packet end of 60 with 0x00. - ** This is to resolve faulty padding by the HW with 0xaa bytes. - */ - if (BytesSend < C_LEN_ETHERNET_MINSIZE) { - if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) { - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - return 0; - } - pMessage->len = C_LEN_ETHERNET_MINSIZE; - } - - /* - ** advance head counter behind descriptor needed for this frame, - ** so that needed descriptor is reserved from that on. The next - ** action will be to add the passed buffer to the TX-descriptor - */ - pTxd = pTxPort->pTxdRingHead; - pTxPort->pTxdRingHead = pTxd->pNextTxd; - pTxPort->TxdRingFree--; - -#ifdef SK_DUMP_TX - DumpMsg(pMessage, "XmitFrame"); -#endif - - /* - ** First step is to map the data to be sent via the adapter onto - ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4 - ** and 2.6 need to use pci_map_page() for that mapping. - */ - PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, - virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & ~PAGE_MASK), - pMessage->len, - PCI_DMA_TODEVICE); - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); - pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pTxd->pMBuf = pMessage; - - if (pMessage->ip_summed == CHECKSUM_PARTIAL) { - u16 hdrlen = skb_transport_offset(pMessage); - u16 offset = hdrlen + pMessage->csum_offset; - - if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && - (pAC->GIni.GIChipRev == 0) && - (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { - pTxd->TBControl = BMU_TCP_CHECK; - } else { - pTxd->TBControl = BMU_UDP_CHECK; - } - - pTxd->TcpSumOfs = 0; - pTxd->TcpSumSt = hdrlen; - pTxd->TcpSumWr = offset; - - pTxd->TBControl |= BMU_OWN | BMU_STF | - BMU_SW | BMU_EOF | -#ifdef USE_TX_COMPLETE - BMU_IRQ_EOF | -#endif - pMessage->len; - } else { - pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | - BMU_SW | BMU_EOF | -#ifdef USE_TX_COMPLETE - BMU_IRQ_EOF | -#endif - pMessage->len; - } - - /* - ** If previous descriptor already done, give TX start cmd - */ - pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd); - if ((pOldTxd->TBControl & BMU_OWN) == 0) { - SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); - } - - /* - ** after releasing the lock, the skb may immediately be free'd - */ - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - if (pTxPort->TxdRingFree != 0) { - return (BytesSend); - } else { - return (0); - } - -} /* XmitFrame */ - -/***************************************************************************** - * - * XmitFrameSG - fill one socket buffer into the transmit ring - * (use SG and TCP/UDP hardware checksumming) - * - * Description: - * This function puts a message into the transmit descriptor ring - * if there is a descriptors left. - * - * Returns: - * > 0 - on succes: the number of bytes in the message - * = 0 - on resource shortage: this frame sent or dropped, now - * the ring is full ( -> set tbusy) - * < 0 - on failure: other problems ( -> return failure to upper layers) - */ -static int XmitFrameSG( -SK_AC *pAC, /* pointer to adapter context */ -TX_PORT *pTxPort, /* pointer to struct of port to send to */ -struct sk_buff *pMessage) /* pointer to send-message */ -{ - - TXD *pTxd; - TXD *pTxdFst; - TXD *pTxdLst; - int CurrFrag; - int BytesSend; - skb_frag_t *sk_frag; - SK_U64 PhysAddr; - unsigned long Flags; - SK_U32 Control; - - spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); -#ifndef USE_TX_COMPLETE - FreeTxDescriptors(pAC, pTxPort); -#endif - if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) { - FreeTxDescriptors(pAC, pTxPort); - if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) { - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_TX_PROGRESS, - ("XmitFrameSG failed - Ring full\n")); - /* this message can not be sent now */ - return(-1); - } - } - - pTxd = pTxPort->pTxdRingHead; - pTxdFst = pTxd; - pTxdLst = pTxd; - BytesSend = 0; - - /* - ** Map the first fragment (header) into the DMA-space - */ - PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, - virt_to_page(pMessage->data), - ((unsigned long) pMessage->data & ~PAGE_MASK), - skb_headlen(pMessage), - PCI_DMA_TODEVICE); - - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); - pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - - /* - ** Does the HW need to evaluate checksum for TCP or UDP packets? - */ - if (pMessage->ip_summed == CHECKSUM_PARTIAL) { - u16 hdrlen = skb_transport_offset(pMessage); - u16 offset = hdrlen + pMessage->csum_offset; - - Control = BMU_STFWD; - - /* - ** We have to use the opcode for tcp here, because the - ** opcode for udp is not working in the hardware yet - ** (Revision 2.0) - */ - if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && - (pAC->GIni.GIChipRev == 0) && - (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { - Control |= BMU_TCP_CHECK; - } else { - Control |= BMU_UDP_CHECK; - } - - pTxd->TcpSumOfs = 0; - pTxd->TcpSumSt = hdrlen; - pTxd->TcpSumWr = offset; - } else - Control = BMU_CHECK | BMU_SW; - - pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage); - - pTxd = pTxd->pNextTxd; - pTxPort->TxdRingFree--; - BytesSend += skb_headlen(pMessage); - - /* - ** Browse over all SG fragments and map each of them into the DMA space - */ - for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) { - sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag]; - /* - ** we already have the proper value in entry - */ - PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, - sk_frag->page, - sk_frag->page_offset, - sk_frag->size, - PCI_DMA_TODEVICE); - - pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); - pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pTxd->pMBuf = pMessage; - - pTxd->TBControl = Control | BMU_OWN | sk_frag->size; - - /* - ** Do we have the last fragment? - */ - if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) { -#ifdef USE_TX_COMPLETE - pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF; -#else - pTxd->TBControl |= BMU_EOF; -#endif - pTxdFst->TBControl |= BMU_OWN | BMU_SW; - } - pTxdLst = pTxd; - pTxd = pTxd->pNextTxd; - pTxPort->TxdRingFree--; - BytesSend += sk_frag->size; - } - - /* - ** If previous descriptor already done, give TX start cmd - */ - if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) { - SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START); - } - - pTxPort->pTxdRingPrev = pTxdLst; - pTxPort->pTxdRingHead = pTxd; - - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); - - if (pTxPort->TxdRingFree > 0) { - return (BytesSend); - } else { - return (0); - } -} - -/***************************************************************************** - * - * FreeTxDescriptors - release descriptors from the descriptor ring - * - * Description: - * This function releases descriptors from a transmit ring if they - * have been sent by the BMU. - * If a descriptors is sent, it can be freed and the message can - * be freed, too. - * The SOFTWARE controllable bit is used to prevent running around a - * completely free ring for ever. If this bit is no set in the - * frame (by XmitFrame), this frame has never been sent or is - * already freed. - * The Tx descriptor ring lock must be held while calling this function !!! - * - * Returns: - * none - */ -static void FreeTxDescriptors( -SK_AC *pAC, /* pointer to the adapter context */ -TX_PORT *pTxPort) /* pointer to destination port structure */ -{ -TXD *pTxd; /* pointer to the checked descriptor */ -TXD *pNewTail; /* pointer to 'end' of the ring */ -SK_U32 Control; /* TBControl field of descriptor */ -SK_U64 PhysAddr; /* address of DMA mapping */ - - pNewTail = pTxPort->pTxdRingTail; - pTxd = pNewTail; - /* - ** loop forever; exits if BMU_SW bit not set in start frame - ** or BMU_OWN bit set in any frame - */ - while (1) { - Control = pTxd->TBControl; - if ((Control & BMU_SW) == 0) { - /* - ** software controllable bit is set in first - ** fragment when given to BMU. Not set means that - ** this fragment was never sent or is already - ** freed ( -> ring completely free now). - */ - pTxPort->pTxdRingTail = pTxd; - netif_wake_queue(pAC->dev[pTxPort->PortIndex]); - return; - } - if (Control & BMU_OWN) { - pTxPort->pTxdRingTail = pTxd; - if (pTxPort->TxdRingFree > 0) { - netif_wake_queue(pAC->dev[pTxPort->PortIndex]); - } - return; - } - - /* - ** release the DMA mapping, because until not unmapped - ** this buffer is considered being under control of the - ** adapter card! - */ - PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; - PhysAddr |= (SK_U64) pTxd->VDataLow; - pci_unmap_page(pAC->PciDev, PhysAddr, - pTxd->pMBuf->len, - PCI_DMA_TODEVICE); - - if (Control & BMU_EOF) - DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */ - - pTxPort->TxdRingFree++; - pTxd->TBControl &= ~BMU_SW; - pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */ - } /* while(forever) */ -} /* FreeTxDescriptors */ - -/***************************************************************************** - * - * FillRxRing - fill the receive ring with valid descriptors - * - * Description: - * This function fills the receive ring descriptors with data - * segments and makes them valid for the BMU. - * The active ring is filled completely, if possible. - * The non-active ring is filled only partial to save memory. - * - * Description of rx ring structure: - * head - points to the descriptor which will be used next by the BMU - * tail - points to the next descriptor to give to the BMU - * - * Returns: N/A - */ -static void FillRxRing( -SK_AC *pAC, /* pointer to the adapter context */ -RX_PORT *pRxPort) /* ptr to port struct for which the ring - should be filled */ -{ -unsigned long Flags; - - spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags); - while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) { - if(!FillRxDescriptor(pAC, pRxPort)) - break; - } - spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags); -} /* FillRxRing */ - - -/***************************************************************************** - * - * FillRxDescriptor - fill one buffer into the receive ring - * - * Description: - * The function allocates a new receive buffer and - * puts it into the next descriptor. - * - * Returns: - * SK_TRUE - a buffer was added to the ring - * SK_FALSE - a buffer could not be added - */ -static SK_BOOL FillRxDescriptor( -SK_AC *pAC, /* pointer to the adapter context struct */ -RX_PORT *pRxPort) /* ptr to port struct of ring to fill */ -{ -struct sk_buff *pMsgBlock; /* pointer to a new message block */ -RXD *pRxd; /* the rxd to fill */ -SK_U16 Length; /* data fragment length */ -SK_U64 PhysAddr; /* physical address of a rx buffer */ - - pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC); - if (pMsgBlock == NULL) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_ENTRY, - ("%s: Allocation of rx buffer failed !\n", - pAC->dev[pRxPort->PortIndex]->name)); - SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex); - return(SK_FALSE); - } - skb_reserve(pMsgBlock, 2); /* to align IP frames */ - /* skb allocated ok, so add buffer */ - pRxd = pRxPort->pRxdRingTail; - pRxPort->pRxdRingTail = pRxd->pNextRxd; - pRxPort->RxdRingFree--; - Length = pAC->RxBufSize; - PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, - virt_to_page(pMsgBlock->data), - ((unsigned long) pMsgBlock->data & - ~PAGE_MASK), - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); - - pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); - pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); - pRxd->pMBuf = pMsgBlock; - pRxd->RBControl = BMU_OWN | - BMU_STF | - BMU_IRQ_EOF | - BMU_TCP_CHECK | - Length; - return (SK_TRUE); - -} /* FillRxDescriptor */ - - -/***************************************************************************** - * - * ReQueueRxBuffer - fill one buffer back into the receive ring - * - * Description: - * Fill a given buffer back into the rx ring. The buffer - * has been previously allocated and aligned, and its phys. - * address calculated, so this is no more necessary. - * - * Returns: N/A - */ -static void ReQueueRxBuffer( -SK_AC *pAC, /* pointer to the adapter context struct */ -RX_PORT *pRxPort, /* ptr to port struct of ring to fill */ -struct sk_buff *pMsg, /* pointer to the buffer */ -SK_U32 PhysHigh, /* phys address high dword */ -SK_U32 PhysLow) /* phys address low dword */ -{ -RXD *pRxd; /* the rxd to fill */ -SK_U16 Length; /* data fragment length */ - - pRxd = pRxPort->pRxdRingTail; - pRxPort->pRxdRingTail = pRxd->pNextRxd; - pRxPort->RxdRingFree--; - Length = pAC->RxBufSize; - - pRxd->VDataLow = PhysLow; - pRxd->VDataHigh = PhysHigh; - pRxd->pMBuf = pMsg; - pRxd->RBControl = BMU_OWN | - BMU_STF | - BMU_IRQ_EOF | - BMU_TCP_CHECK | - Length; - return; -} /* ReQueueRxBuffer */ - -/***************************************************************************** - * - * ReceiveIrq - handle a receive IRQ - * - * Description: - * This function is called when a receive IRQ is set. - * It walks the receive descriptor ring and sends up all - * frames that are complete. - * - * Returns: N/A - */ -static void ReceiveIrq( - SK_AC *pAC, /* pointer to adapter context */ - RX_PORT *pRxPort, /* pointer to receive port struct */ - SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ -{ -RXD *pRxd; /* pointer to receive descriptors */ -SK_U32 Control; /* control field of descriptor */ -struct sk_buff *pMsg; /* pointer to message holding frame */ -struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ -int FrameLength; /* total length of received frame */ -SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ -SK_EVPARA EvPara; /* an event parameter union */ -unsigned long Flags; /* for spin lock */ -int PortIndex = pRxPort->PortIndex; -unsigned int Offset; -unsigned int NumBytes; -unsigned int ForRlmt; -SK_BOOL IsBc; -SK_BOOL IsMc; -SK_BOOL IsBadFrame; /* Bad frame */ - -SK_U32 FrameStat; -SK_U64 PhysAddr; - -rx_start: - /* do forever; exit if BMU_OWN found */ - for ( pRxd = pRxPort->pRxdRingHead ; - pRxPort->RxdRingFree < pAC->RxDescrPerRing ; - pRxd = pRxd->pNextRxd, - pRxPort->pRxdRingHead = pRxd, - pRxPort->RxdRingFree ++) { - - /* - * For a better understanding of this loop - * Go through every descriptor beginning at the head - * Please note: the ring might be completely received so the OWN bit - * set is not a good crirteria to leave that loop. - * Therefore the RingFree counter is used. - * On entry of this loop pRxd is a pointer to the Rxd that needs - * to be checked next. - */ - - Control = pRxd->RBControl; - - /* check if this descriptor is ready */ - if ((Control & BMU_OWN) != 0) { - /* this descriptor is not yet ready */ - /* This is the usual end of the loop */ - /* We don't need to start the ring again */ - FillRxRing(pAC, pRxPort); - return; - } - pAC->DynIrqModInfo.NbrProcessedDescr++; - - /* get length of frame and check it */ - FrameLength = Control & BMU_BBC; - if (FrameLength > pAC->RxBufSize) { - goto rx_failed; - } - - /* check for STF and EOF */ - if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) { - goto rx_failed; - } - - /* here we have a complete frame in the ring */ - pMsg = pRxd->pMBuf; - - FrameStat = pRxd->FrameStat; - - /* check for frame length mismatch */ -#define XMR_FS_LEN_SHIFT 18 -#define GMR_FS_LEN_SHIFT 16 - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("skge: Frame length mismatch (%u/%u).\n", - FrameLength, - (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); - goto rx_failed; - } - } - else { - if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("skge: Frame length mismatch (%u/%u).\n", - FrameLength, - (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); - goto rx_failed; - } - } - - /* Set Rx Status */ - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - IsBc = (FrameStat & XMR_FS_BC) != 0; - IsMc = (FrameStat & XMR_FS_MC) != 0; - IsBadFrame = (FrameStat & - (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0; - } else { - IsBc = (FrameStat & GMR_FS_BC) != 0; - IsMc = (FrameStat & GMR_FS_MC) != 0; - IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) || - ((FrameStat & GMR_FS_RX_OK) == 0)); - } - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, - ("Received frame of length %d on port %d\n", - FrameLength, PortIndex)); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0, - ("Number of free rx descriptors: %d\n", - pRxPort->RxdRingFree)); -/* DumpMsg(pMsg, "Rx"); */ - - if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) { -#if 0 - (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) { -#endif - /* there is a receive error in this frame */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("skge: Error in received frame, dropped!\n" - "Control: %x\nRxStat: %x\n", - Control, FrameStat)); - - ReQueueRxBuffer(pAC, pRxPort, pMsg, - pRxd->VDataHigh, pRxd->VDataLow); - - continue; - } - - /* - * if short frame then copy data to reduce memory waste - */ - if ((FrameLength < SK_COPY_THRESHOLD) && - ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) { - /* - * Short frame detected and allocation successfull - */ - /* use new skb and copy data */ - skb_reserve(pNewMsg, 2); - skb_put(pNewMsg, FrameLength); - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - - pci_dma_sync_single_for_cpu(pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); - skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength); - - pci_dma_sync_single_for_device(pAC->PciDev, - (dma_addr_t) PhysAddr, - FrameLength, - PCI_DMA_FROMDEVICE); - ReQueueRxBuffer(pAC, pRxPort, pMsg, - pRxd->VDataHigh, pRxd->VDataLow); - - pMsg = pNewMsg; - - } - else { - /* - * if large frame, or SKB allocation failed, pass - * the SKB directly to the networking - */ - - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - - /* release the DMA mapping */ - pci_unmap_single(pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); - - /* set length in message */ - skb_put(pMsg, FrameLength); - } /* frame > SK_COPY_TRESHOLD */ - -#ifdef USE_SK_RX_CHECKSUM - pMsg->csum = pRxd->TcpSums & 0xffff; - pMsg->ip_summed = CHECKSUM_COMPLETE; -#else - pMsg->ip_summed = CHECKSUM_NONE; -#endif - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); - ForRlmt = SK_RLMT_RX_PROTOCOL; -#if 0 - IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC; -#endif - SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength, - IsBc, &Offset, &NumBytes); - if (NumBytes != 0) { -#if 0 - IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC; -#endif - SK_RLMT_LOOKAHEAD(pAC, PortIndex, - &pMsg->data[Offset], - IsBc, IsMc, &ForRlmt); - } - if (ForRlmt == SK_RLMT_RX_PROTOCOL) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W")); - /* send up only frames from active port */ - if ((PortIndex == pAC->ActivePort) || - (pAC->RlmtNets == 2)) { - /* frame for upper layer */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U")); -#ifdef xDEBUG - DumpMsg(pMsg, "Rx"); -#endif - SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC, - FrameLength, pRxPort->PortIndex); - - pMsg->protocol = eth_type_trans(pMsg, - pAC->dev[pRxPort->PortIndex]); - netif_rx(pMsg); - pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; - } - else { - /* drop frame */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("D")); - DEV_KFREE_SKB(pMsg); - } - - } /* if not for rlmt */ - else { - /* packet for rlmt */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, ("R")); - pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, - pAC->IoBase, FrameLength); - if (pRlmtMbuf != NULL) { - pRlmtMbuf->pNext = NULL; - pRlmtMbuf->Length = FrameLength; - pRlmtMbuf->PortIdx = PortIndex; - EvPara.pParaPtr = pRlmtMbuf; - memcpy((char*)(pRlmtMbuf->pData), - (char*)(pMsg->data), - FrameLength); - - /* SlowPathLock needed? */ - if (SlowPathLock == SK_TRUE) { - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - SkEventQueue(pAC, SKGE_RLMT, - SK_RLMT_PACKET_RECEIVED, - EvPara); - pAC->CheckQueue = SK_TRUE; - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - } else { - SkEventQueue(pAC, SKGE_RLMT, - SK_RLMT_PACKET_RECEIVED, - EvPara); - pAC->CheckQueue = SK_TRUE; - } - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("Q")); - } - if ((pAC->dev[pRxPort->PortIndex]->flags & - (IFF_PROMISC | IFF_ALLMULTI)) != 0 || - (ForRlmt & SK_RLMT_RX_PROTOCOL) == - SK_RLMT_RX_PROTOCOL) { - pMsg->protocol = eth_type_trans(pMsg, - pAC->dev[pRxPort->PortIndex]); - netif_rx(pMsg); - pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; - } - else { - DEV_KFREE_SKB(pMsg); - } - - } /* if packet for rlmt */ - } /* for ... scanning the RXD ring */ - - /* RXD ring is empty -> fill and restart */ - FillRxRing(pAC, pRxPort); - /* do not start if called from Close */ - if (pAC->BoardLevel > SK_INIT_DATA) { - ClearAndStartRx(pAC, PortIndex); - } - return; - -rx_failed: - /* remove error frame */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR, - ("Schrottdescriptor, length: 0x%x\n", FrameLength)); - - /* release the DMA mapping */ - - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_unmap_page(pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); - DEV_KFREE_SKB_IRQ(pRxd->pMBuf); - pRxd->pMBuf = NULL; - pRxPort->RxdRingFree++; - pRxPort->pRxdRingHead = pRxd->pNextRxd; - goto rx_start; - -} /* ReceiveIrq */ - - -/***************************************************************************** - * - * ClearAndStartRx - give a start receive command to BMU, clear IRQ - * - * Description: - * This function sends a start command and a clear interrupt - * command for one receive queue to the BMU. - * - * Returns: N/A - * none - */ -static void ClearAndStartRx( -SK_AC *pAC, /* pointer to the adapter context */ -int PortIndex) /* index of the receive port (XMAC) */ -{ - SK_OUT8(pAC->IoBase, - RxQueueAddr[PortIndex]+Q_CSR, - CSR_START | CSR_IRQ_CL_F); -} /* ClearAndStartRx */ - - -/***************************************************************************** - * - * ClearTxIrq - give a clear transmit IRQ command to BMU - * - * Description: - * This function sends a clear tx IRQ command for one - * transmit queue to the BMU. - * - * Returns: N/A - */ -static void ClearTxIrq( -SK_AC *pAC, /* pointer to the adapter context */ -int PortIndex, /* index of the transmit port (XMAC) */ -int Prio) /* priority or normal queue */ -{ - SK_OUT8(pAC->IoBase, - TxQueueAddr[PortIndex][Prio]+Q_CSR, - CSR_IRQ_CL_F); -} /* ClearTxIrq */ - - -/***************************************************************************** - * - * ClearRxRing - remove all buffers from the receive ring - * - * Description: - * This function removes all receive buffers from the ring. - * The receive BMU must be stopped before calling this function. - * - * Returns: N/A - */ -static void ClearRxRing( -SK_AC *pAC, /* pointer to adapter context */ -RX_PORT *pRxPort) /* pointer to rx port struct */ -{ -RXD *pRxd; /* pointer to the current descriptor */ -unsigned long Flags; -SK_U64 PhysAddr; - - if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) { - return; - } - spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags); - pRxd = pRxPort->pRxdRingHead; - do { - if (pRxd->pMBuf != NULL) { - - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; - PhysAddr |= (SK_U64) pRxd->VDataLow; - pci_unmap_page(pAC->PciDev, - PhysAddr, - pAC->RxBufSize - 2, - PCI_DMA_FROMDEVICE); - DEV_KFREE_SKB(pRxd->pMBuf); - pRxd->pMBuf = NULL; - } - pRxd->RBControl &= BMU_OWN; - pRxd = pRxd->pNextRxd; - pRxPort->RxdRingFree++; - } while (pRxd != pRxPort->pRxdRingTail); - pRxPort->pRxdRingTail = pRxPort->pRxdRingHead; - spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags); -} /* ClearRxRing */ - -/***************************************************************************** - * - * ClearTxRing - remove all buffers from the transmit ring - * - * Description: - * This function removes all transmit buffers from the ring. - * The transmit BMU must be stopped before calling this function - * and transmitting at the upper level must be disabled. - * The BMU own bit of all descriptors is cleared, the rest is - * done by calling FreeTxDescriptors. - * - * Returns: N/A - */ -static void ClearTxRing( -SK_AC *pAC, /* pointer to adapter context */ -TX_PORT *pTxPort) /* pointer to tx prt struct */ -{ -TXD *pTxd; /* pointer to the current descriptor */ -int i; -unsigned long Flags; - - spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); - pTxd = pTxPort->pTxdRingHead; - for (i=0; iTxDescrPerRing; i++) { - pTxd->TBControl &= ~BMU_OWN; - pTxd = pTxd->pNextTxd; - } - FreeTxDescriptors(pAC, pTxPort); - spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); -} /* ClearTxRing */ - -/***************************************************************************** - * - * SkGeSetMacAddr - Set the hardware MAC address - * - * Description: - * This function sets the MAC address used by the adapter. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) -{ - -DEV_NET *pNet = netdev_priv(dev); -SK_AC *pAC = pNet->pAC; - -struct sockaddr *addr = p; -unsigned long Flags; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeSetMacAddr starts now...\n")); - if(netif_running(dev)) - return -EBUSY; - - memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - - if (pAC->RlmtNets == 2) - SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr, - (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); - else - SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, - (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); - - - - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return 0; -} /* SkGeSetMacAddr */ - - -/***************************************************************************** - * - * SkGeSetRxMode - set receive mode - * - * Description: - * This function sets the receive mode of an adapter. The adapter - * supports promiscuous mode, allmulticast mode and a number of - * multicast addresses. If more multicast addresses the available - * are selected, a hash function in the hardware is used. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static void SkGeSetRxMode(struct SK_NET_DEVICE *dev) -{ - -DEV_NET *pNet; -SK_AC *pAC; - -struct dev_mc_list *pMcList; -int i; -int PortIdx; -unsigned long Flags; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeSetRxMode starts now... ")); - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - if (pAC->RlmtNets == 1) - PortIdx = pAC->ActivePort; - else - PortIdx = pNet->NetNr; - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - if (dev->flags & IFF_PROMISC) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("PROMISCUOUS mode\n")); - SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, - SK_PROM_MODE_LLC); - } else if (dev->flags & IFF_ALLMULTI) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("ALLMULTI mode\n")); - SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, - SK_PROM_MODE_ALL_MC); - } else { - SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx, - SK_PROM_MODE_NONE); - SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0); - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("Number of MC entries: %d ", dev->mc_count)); - - pMcList = dev->mc_list; - for (i=0; imc_count; i++, pMcList = pMcList->next) { - SkAddrMcAdd(pAC, pAC->IoBase, PortIdx, - (SK_MAC_ADDR*)pMcList->dmi_addr, 0); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA, - ("%02x:%02x:%02x:%02x:%02x:%02x\n", - pMcList->dmi_addr[0], - pMcList->dmi_addr[1], - pMcList->dmi_addr[2], - pMcList->dmi_addr[3], - pMcList->dmi_addr[4], - pMcList->dmi_addr[5])); - } - SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx); - } - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - return; -} /* SkGeSetRxMode */ - - -/***************************************************************************** - * - * SkGeChangeMtu - set the MTU to another value - * - * Description: - * This function sets is called whenever the MTU size is changed - * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard - * ethernet MTU size, long frame support is activated. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) -{ -DEV_NET *pNet; -struct net_device *pOtherDev; -SK_AC *pAC; -unsigned long Flags; -int i; -SK_EVPARA EvPara; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeChangeMtu starts now...\n")); - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { - return -EINVAL; - } - - if(pAC->BoardLevel != SK_INIT_RUN) { - return -EINVAL; - } - -#ifdef SK_DIAG_SUPPORT - if (pAC->DiagModeActive == DIAG_ACTIVE) { - if (pAC->DiagFlowCtrl == SK_FALSE) { - return -1; /* still in use, deny any actions of MTU */ - } else { - pAC->DiagFlowCtrl = SK_FALSE; - } - } -#endif - - pOtherDev = pAC->dev[1 - pNet->NetNr]; - - if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500) - && (NewMtu <= 1500)) - return 0; - - pAC->RxBufSize = NewMtu + 32; - dev->mtu = NewMtu; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("New MTU: %d\n", NewMtu)); - - /* - ** Prevent any reconfiguration while changing the MTU - ** by disabling any interrupts - */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - - /* - ** Notify RLMT that any ports are to be stopped - */ - EvPara.Para32[0] = 0; - EvPara.Para32[1] = -1; - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - } - - /* - ** After calling the SkEventDispatcher(), RLMT is aware about - ** the stopped ports -> configuration can take place! - */ - SkEventDispatcher(pAC, pAC->IoBase); - - for (i=0; iGIni.GIMacsFound; i++) { - spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); - netif_stop_queue(pAC->dev[i]); - - } - - /* - ** Depending on the desired MTU size change, a different number of - ** RX buffers need to be allocated - */ - if (NewMtu > 1500) { - /* - ** Use less rx buffers - */ - for (i=0; iGIni.GIMacsFound; i++) { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } else { - if (i == pAC->ActivePort) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } else { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 10); - } - } - } - } else { - /* - ** Use the normal amount of rx buffers - */ - for (i=0; iGIni.GIMacsFound; i++) { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = 1; - } else { - if (i == pAC->ActivePort) { - pAC->RxPort[i].RxFillLimit = 1; - } else { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } - } - } - } - - SkGeDeInit(pAC, pAC->IoBase); - - /* - ** enable/disable hardware support for long frames - */ - if (NewMtu > 1500) { -// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ - pAC->GIni.GIPortUsage = SK_JUMBO_LINK; - } else { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->GIni.GIPortUsage = SK_MUL_LINK; - } else { - pAC->GIni.GIPortUsage = SK_RED_LINK; - } - } - - SkGeInit( pAC, pAC->IoBase, SK_INIT_IO); - SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); - SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); - - /* - ** tschilling: - ** Speed and others are set back to default in level 1 init! - */ - GetConfiguration(pAC); - - SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN); - - /* - ** clear and reinit the rx rings here - */ - for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[i]); - FillRxRing(pAC, &pAC->RxPort[i]); - - /* - ** Enable transmit descriptor polling - */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); - }; - - SkGeYellowLED(pAC, pAC->IoBase, 1); - SkDimEnableModerationIfNeeded(pAC); - SkDimDisplayModerationSettings(pAC); - - netif_start_queue(pAC->dev[pNet->PortNr]); - for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) { - spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); - } - - /* - ** Enable Interrupts again - */ - SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); - - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - - /* - ** Notify RLMT about the changing and restarting one (or more) ports - */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - EvPara.Para32[0] = pAC->RlmtNets; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara); - EvPara.Para32[0] = pNet->PortNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - - if (netif_running(pOtherDev)) { - DEV_NET *pOtherNet = netdev_priv(pOtherDev); - EvPara.Para32[0] = pOtherNet->PortNr; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - } - } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - } - - SkEventDispatcher(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - /* - ** While testing this driver with latest kernel 2.5 (2.5.70), it - ** seems as if upper layers have a problem to handle a successful - ** return value of '0'. If such a zero is returned, the complete - ** system hangs for several minutes (!), which is in acceptable. - ** - ** Currently it is not clear, what the exact reason for this problem - ** is. The implemented workaround for 2.5 is to return the desired - ** new MTU size if all needed changes for the new MTU size where - ** performed. In kernels 2.2 and 2.4, a zero value is returned, - ** which indicates the successful change of the mtu-size. - */ - return NewMtu; - -} /* SkGeChangeMtu */ - - -/***************************************************************************** - * - * SkGeStats - return ethernet device statistics - * - * Description: - * This function return statistic data about the ethernet device - * to the operating system. - * - * Returns: - * pointer to the statistic structure. - */ -static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) -{ -DEV_NET *pNet = netdev_priv(dev); -SK_AC *pAC = pNet->pAC; -SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ -SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ -SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ -unsigned int Size; /* size of pnmi struct */ -unsigned long Flags; /* for spin lock */ - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeStats starts now...\n")); - pPnmiStruct = &pAC->PnmiStruct; - -#ifdef SK_DIAG_SUPPORT - if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && - (pAC->BoardLevel == SK_INIT_RUN)) { -#endif - SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - Size = SK_PNMI_STRUCT_SIZE; - SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); -#ifdef SK_DIAG_SUPPORT - } -#endif - - pPnmiStat = &pPnmiStruct->Stat[0]; - pPnmiConf = &pPnmiStruct->Conf[0]; - - pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF; - pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF; - pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts; - pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts; - - if (dev->mtu <= 1500) { - pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; - } else { - pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts - - pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF); - } - - - if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12) - pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts; - - pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; - pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF; - pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF; - pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF; - pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; - - /* detailed rx_errors: */ - pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF; - pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; - pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF; - pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF; - pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; - pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF; - - /* detailed tx_errors */ - pAC->stats.tx_aborted_errors = (SK_U32) 0; - pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; - pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF; - pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; - pAC->stats.tx_window_errors = (SK_U32) 0; - - return(&pAC->stats); -} /* SkGeStats */ - -/* - * Basic MII register access - */ -static int SkGeMiiIoctl(struct net_device *dev, - struct mii_ioctl_data *data, int cmd) -{ - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - SK_IOC IoC = pAC->IoBase; - int Port = pNet->PortNr; - SK_GEPORT *pPrt = &pAC->GIni.GP[Port]; - unsigned long Flags; - int err = 0; - int reg = data->reg_num & 0x1f; - SK_U16 val = data->val_in; - - if (!netif_running(dev)) - return -ENODEV; /* Phy still in reset */ - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - switch(cmd) { - case SIOCGMIIPHY: - data->phy_id = pPrt->PhyAddr; - - /* fallthru */ - case SIOCGMIIREG: - if (pAC->GIni.GIGenesis) - SkXmPhyRead(pAC, IoC, Port, reg, &val); - else - SkGmPhyRead(pAC, IoC, Port, reg, &val); - - data->val_out = val; - break; - - case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) - err = -EPERM; - - else if (pAC->GIni.GIGenesis) - SkXmPhyWrite(pAC, IoC, Port, reg, val); - else - SkGmPhyWrite(pAC, IoC, Port, reg, val); - break; - default: - err = -EOPNOTSUPP; - } - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return err; -} - - -/***************************************************************************** - * - * SkGeIoctl - IO-control function - * - * Description: - * This function is called if an ioctl is issued on the device. - * There are three subfunction for reading, writing and test-writing - * the private MIB data structure (useful for SysKonnect-internal tools). - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd) -{ -DEV_NET *pNet; -SK_AC *pAC; -void *pMemBuf; -struct pci_dev *pdev = NULL; -SK_GE_IOCTL Ioctl; -unsigned int Err = 0; -int Size = 0; -int Ret = 0; -unsigned int Length = 0; -int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeIoctl starts now...\n")); - - pNet = netdev_priv(dev); - pAC = pNet->pAC; - - if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG) - return SkGeMiiIoctl(dev, if_mii(rq), cmd); - - if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) { - return -EFAULT; - } - - switch(cmd) { - case SK_IOCTL_SETMIB: - case SK_IOCTL_PRESETMIB: - if (!capable(CAP_NET_ADMIN)) return -EPERM; - case SK_IOCTL_GETMIB: - if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, - Ioctl.LenPnmiStruct)? - Ioctl.Len : sizeof(pAC->PnmiStruct))) { - return -EFAULT; - } - Size = SkGeIocMib(pNet, Ioctl.Len, cmd); - if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct, - Ioctl.Lenifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { - return -EFAULT; - } - break; - case SK_IOCTL_GEN: - if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { - Length = Ioctl.Len; - } else { - Length = sizeof(pAC->PnmiStruct) + HeaderLength; - } - if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { - return -ENOMEM; - } - if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { - Err = -EFAULT; - goto fault_gen; - } - if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) { - Err = -EFAULT; - goto fault_gen; - } - if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { - Err = -EFAULT; - goto fault_gen; - } - Ioctl.Len = Length; - if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { - Err = -EFAULT; - goto fault_gen; - } -fault_gen: - kfree(pMemBuf); /* cleanup everything */ - break; -#ifdef SK_DIAG_SUPPORT - case SK_IOCTL_DIAG: - if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { - Length = Ioctl.Len; - } else { - Length = sizeof(pAC->PnmiStruct) + HeaderLength; - } - if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { - return -ENOMEM; - } - if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { - Err = -EFAULT; - goto fault_diag; - } - pdev = pAC->PciDev; - Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */ - /* - ** While coding this new IOCTL interface, only a few lines of code - ** are to to be added. Therefore no dedicated function has been - ** added. If more functionality is added, a separate function - ** should be used... - */ - * ((SK_U32 *)pMemBuf) = 0; - * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number; - * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev)); - if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) { - Err = -EFAULT; - goto fault_diag; - } - Ioctl.Len = Length; - if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) { - Err = -EFAULT; - goto fault_diag; - } -fault_diag: - kfree(pMemBuf); /* cleanup everything */ - break; -#endif - default: - Err = -EOPNOTSUPP; - } - - return(Err); - -} /* SkGeIoctl */ - - -/***************************************************************************** - * - * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message - * - * Description: - * This function reads/writes the MIB data using PNMI (Private Network - * Management Interface). - * The destination for the data must be provided with the - * ioctl call and is given to the driver in the form of - * a user space address. - * Copying from the user-provided data area into kernel messages - * and back is done by copy_from_user and copy_to_user calls in - * SkGeIoctl. - * - * Returns: - * returned size from PNMI call - */ -static int SkGeIocMib( -DEV_NET *pNet, /* pointer to the adapter context */ -unsigned int Size, /* length of ioctl data */ -int mode) /* flag for set/preset */ -{ -unsigned long Flags; /* for spin lock */ -SK_AC *pAC; - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeIocMib starts now...\n")); - pAC = pNet->pAC; - /* access MIB */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - switch(mode) { - case SK_IOCTL_GETMIB: - SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, - pNet->NetNr); - break; - case SK_IOCTL_PRESETMIB: - SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, - pNet->NetNr); - break; - case SK_IOCTL_SETMIB: - SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size, - pNet->NetNr); - break; - default: - break; - } - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("MIB data access succeeded\n")); - return (Size); -} /* SkGeIocMib */ - - -/***************************************************************************** - * - * GetConfiguration - read configuration information - * - * Description: - * This function reads per-adapter configuration information from - * the options provided on the command line. - * - * Returns: - * none - */ -static void GetConfiguration( -SK_AC *pAC) /* pointer to the adapter context structure */ -{ -SK_I32 Port; /* preferred port */ -SK_BOOL AutoSet; -SK_BOOL DupSet; -int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ -int AutoNeg = 1; /* autoneg off (0) or on (1) */ -int DuplexCap = 0; /* 0=both,1=full,2=half */ -int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ -int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ - -SK_BOOL IsConTypeDefined = SK_TRUE; -SK_BOOL IsLinkSpeedDefined = SK_TRUE; -SK_BOOL IsFlowCtrlDefined = SK_TRUE; -SK_BOOL IsRoleDefined = SK_TRUE; -SK_BOOL IsModeDefined = SK_TRUE; -/* - * The two parameters AutoNeg. and DuplexCap. map to one configuration - * parameter. The mapping is described by this table: - * DuplexCap -> | both | full | half | - * AutoNeg | | | | - * ----------------------------------------------------------------- - * Off | illegal | Full | Half | - * ----------------------------------------------------------------- - * On | AutoBoth | AutoFull | AutoHalf | - * ----------------------------------------------------------------- - * Sense | AutoSense | AutoSense | AutoSense | - */ -int Capabilities[3][3] = - { { -1, SK_LMODE_FULL , SK_LMODE_HALF }, - {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF }, - {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} }; - -#define DC_BOTH 0 -#define DC_FULL 1 -#define DC_HALF 2 -#define AN_OFF 0 -#define AN_ON 1 -#define AN_SENS 2 -#define M_CurrPort pAC->GIni.GP[Port] - - - /* - ** Set the default values first for both ports! - */ - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; - } - - /* - ** Check merged parameter ConType. If it has not been used, - ** verify any other parameter (e.g. AutoNeg) and use default values. - ** - ** Stating both ConType and other lowlevel link parameters is also - ** possible. If this is the case, the passed ConType-parameter is - ** overwritten by the lowlevel link parameter. - ** - ** The following settings are used for a merged ConType-parameter: - ** - ** ConType DupCap AutoNeg FlowCtrl Role Speed - ** ------- ------ ------- -------- ---------- ----- - ** Auto Both On SymOrRem Auto Auto - ** 100FD Full Off None 100 - ** 100HD Half Off None 100 - ** 10FD Full Off None 10 - ** 10HD Half Off None 10 - ** - ** This ConType parameter is used for all ports of the adapter! - */ - if ( (ConType != NULL) && - (pAC->Index < SK_MAX_CARD_PARAM) && - (ConType[pAC->Index] != NULL) ) { - - /* Check chipset family */ - if ((!pAC->ChipsetType) && - (strcmp(ConType[pAC->Index],"Auto")!=0) && - (strcmp(ConType[pAC->Index],"")!=0)) { - /* Set the speed parameter back */ - printk("sk98lin: Illegal value \"%s\" " - "for ConType." - " Using Auto.\n", - ConType[pAC->Index]); - - sprintf(ConType[pAC->Index], "Auto"); - } - - if (strcmp(ConType[pAC->Index],"")==0) { - IsConTypeDefined = SK_FALSE; /* No ConType defined */ - } else if (strcmp(ConType[pAC->Index],"Auto")==0) { - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; - } - } else if (strcmp(ConType[pAC->Index],"100FD")==0) { - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; - } - } else if (strcmp(ConType[pAC->Index],"100HD")==0) { - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; - } - } else if (strcmp(ConType[pAC->Index],"10FD")==0) { - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; - } - } else if (strcmp(ConType[pAC->Index],"10HD")==0) { - for (Port = 0; Port < SK_MAX_MACS; Port++) { - M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; - M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; - M_CurrPort.PMSMode = SK_MS_MODE_AUTO; - M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; - } - } else { - printk("sk98lin: Illegal value \"%s\" for ConType\n", - ConType[pAC->Index]); - IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ - } - } else { - IsConTypeDefined = SK_FALSE; /* No ConType defined */ - } - - /* - ** Parse any parameter settings for port A: - ** a) any LinkSpeed stated? - */ - if (Speed_A != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(Speed_A[pAC->Index],"")==0) { - IsLinkSpeedDefined = SK_FALSE; - } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } else if (strcmp(Speed_A[pAC->Index],"10")==0) { - LinkSpeed = SK_LSPEED_10MBPS; - } else if (strcmp(Speed_A[pAC->Index],"100")==0) { - LinkSpeed = SK_LSPEED_100MBPS; - } else if (strcmp(Speed_A[pAC->Index],"1000")==0) { - LinkSpeed = SK_LSPEED_1000MBPS; - } else { - printk("sk98lin: Illegal value \"%s\" for Speed_A\n", - Speed_A[pAC->Index]); - IsLinkSpeedDefined = SK_FALSE; - } - } else { - IsLinkSpeedDefined = SK_FALSE; - } - - /* - ** Check speed parameter: - ** Only copper type adapter and GE V2 cards - */ - if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && - ((LinkSpeed != SK_LSPEED_AUTO) && - (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("sk98lin: Illegal value for Speed_A. " - "Not a copper card or GE V2 card\n Using " - "speed 1000\n"); - LinkSpeed = SK_LSPEED_1000MBPS; - } - - /* - ** Decide whether to set new config value if somethig valid has - ** been received. - */ - if (IsLinkSpeedDefined) { - pAC->GIni.GP[0].PLinkSpeed = LinkSpeed; - } - - /* - ** b) Any Autonegotiation and DuplexCapabilities set? - ** Please note that both belong together... - */ - AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */ - AutoSet = SK_FALSE; - if (AutoNeg_A != NULL && pAC->IndexIndex] != NULL) { - AutoSet = SK_TRUE; - if (strcmp(AutoNeg_A[pAC->Index],"")==0) { - AutoSet = SK_FALSE; - } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) { - AutoNeg = AN_ON; - } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) { - AutoNeg = AN_OFF; - } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) { - AutoNeg = AN_SENS; - } else { - printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n", - AutoNeg_A[pAC->Index]); - } - } - - DuplexCap = DC_BOTH; - DupSet = SK_FALSE; - if (DupCap_A != NULL && pAC->IndexIndex] != NULL) { - DupSet = SK_TRUE; - if (strcmp(DupCap_A[pAC->Index],"")==0) { - DupSet = SK_FALSE; - } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) { - DuplexCap = DC_BOTH; - } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) { - DuplexCap = DC_FULL; - } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) { - DuplexCap = DC_HALF; - } else { - printk("sk98lin: Illegal value \"%s\" for DupCap_A\n", - DupCap_A[pAC->Index]); - } - } - - /* - ** Check for illegal combinations - */ - if ((LinkSpeed == SK_LSPEED_1000MBPS) && - ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || - (DuplexCap == SK_LMODE_STAT_HALF)) && - (pAC->ChipsetType)) { - printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" - " Using Full Duplex.\n"); - DuplexCap = DC_FULL; - } - - if ( AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("sk98lin, Port A: DuplexCapabilities" - " ignored using Sense mode\n"); - } - - if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("sk98lin: Port A: Illegal combination" - " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n"); - DuplexCap = DC_FULL; - } - - if (AutoSet && AutoNeg==AN_OFF && !DupSet) { - DuplexCap = DC_FULL; - } - - if (!AutoSet && DupSet) { - printk("sk98lin: Port A: Duplex setting not" - " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n"); - AutoNeg = AN_ON; - } - - /* - ** set the desired mode - */ - if (AutoSet || DupSet) { - pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; - } - - /* - ** c) Any Flowcontrol-parameter set? - */ - if (FlowCtrl_A != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) { - IsFlowCtrlDefined = SK_FALSE; - } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) { - FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; - } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) { - FlowCtrl = SK_FLOW_MODE_SYMMETRIC; - } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) { - FlowCtrl = SK_FLOW_MODE_LOC_SEND; - } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) { - FlowCtrl = SK_FLOW_MODE_NONE; - } else { - printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", - FlowCtrl_A[pAC->Index]); - IsFlowCtrlDefined = SK_FALSE; - } - } else { - IsFlowCtrlDefined = SK_FALSE; - } - - if (IsFlowCtrlDefined) { - if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { - printk("sk98lin: Port A: FlowControl" - " impossible without AutoNegotiation," - " disabled\n"); - FlowCtrl = SK_FLOW_MODE_NONE; - } - pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl; - } - - /* - ** d) What is with the RoleParameter? - */ - if (Role_A != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(Role_A[pAC->Index],"")==0) { - IsRoleDefined = SK_FALSE; - } else if (strcmp(Role_A[pAC->Index],"Auto")==0) { - MSMode = SK_MS_MODE_AUTO; - } else if (strcmp(Role_A[pAC->Index],"Master")==0) { - MSMode = SK_MS_MODE_MASTER; - } else if (strcmp(Role_A[pAC->Index],"Slave")==0) { - MSMode = SK_MS_MODE_SLAVE; - } else { - printk("sk98lin: Illegal value \"%s\" for Role_A\n", - Role_A[pAC->Index]); - IsRoleDefined = SK_FALSE; - } - } else { - IsRoleDefined = SK_FALSE; - } - - if (IsRoleDefined == SK_TRUE) { - pAC->GIni.GP[0].PMSMode = MSMode; - } - - - - /* - ** Parse any parameter settings for port B: - ** a) any LinkSpeed stated? - */ - IsConTypeDefined = SK_TRUE; - IsLinkSpeedDefined = SK_TRUE; - IsFlowCtrlDefined = SK_TRUE; - IsModeDefined = SK_TRUE; - - if (Speed_B != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(Speed_B[pAC->Index],"")==0) { - IsLinkSpeedDefined = SK_FALSE; - } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) { - LinkSpeed = SK_LSPEED_AUTO; - } else if (strcmp(Speed_B[pAC->Index],"10")==0) { - LinkSpeed = SK_LSPEED_10MBPS; - } else if (strcmp(Speed_B[pAC->Index],"100")==0) { - LinkSpeed = SK_LSPEED_100MBPS; - } else if (strcmp(Speed_B[pAC->Index],"1000")==0) { - LinkSpeed = SK_LSPEED_1000MBPS; - } else { - printk("sk98lin: Illegal value \"%s\" for Speed_B\n", - Speed_B[pAC->Index]); - IsLinkSpeedDefined = SK_FALSE; - } - } else { - IsLinkSpeedDefined = SK_FALSE; - } - - /* - ** Check speed parameter: - ** Only copper type adapter and GE V2 cards - */ - if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) && - ((LinkSpeed != SK_LSPEED_AUTO) && - (LinkSpeed != SK_LSPEED_1000MBPS))) { - printk("sk98lin: Illegal value for Speed_B. " - "Not a copper card or GE V2 card\n Using " - "speed 1000\n"); - LinkSpeed = SK_LSPEED_1000MBPS; - } - - /* - ** Decide whether to set new config value if somethig valid has - ** been received. - */ - if (IsLinkSpeedDefined) { - pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; - } - - /* - ** b) Any Autonegotiation and DuplexCapabilities set? - ** Please note that both belong together... - */ - AutoNeg = AN_SENS; /* default: do auto Sense */ - AutoSet = SK_FALSE; - if (AutoNeg_B != NULL && pAC->IndexIndex] != NULL) { - AutoSet = SK_TRUE; - if (strcmp(AutoNeg_B[pAC->Index],"")==0) { - AutoSet = SK_FALSE; - } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) { - AutoNeg = AN_ON; - } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) { - AutoNeg = AN_OFF; - } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) { - AutoNeg = AN_SENS; - } else { - printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n", - AutoNeg_B[pAC->Index]); - } - } - - DuplexCap = DC_BOTH; - DupSet = SK_FALSE; - if (DupCap_B != NULL && pAC->IndexIndex] != NULL) { - DupSet = SK_TRUE; - if (strcmp(DupCap_B[pAC->Index],"")==0) { - DupSet = SK_FALSE; - } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) { - DuplexCap = DC_BOTH; - } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) { - DuplexCap = DC_FULL; - } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) { - DuplexCap = DC_HALF; - } else { - printk("sk98lin: Illegal value \"%s\" for DupCap_B\n", - DupCap_B[pAC->Index]); - } - } - - - /* - ** Check for illegal combinations - */ - if ((LinkSpeed == SK_LSPEED_1000MBPS) && - ((DuplexCap == SK_LMODE_STAT_AUTOHALF) || - (DuplexCap == SK_LMODE_STAT_HALF)) && - (pAC->ChipsetType)) { - printk("sk98lin: Half Duplex not possible with Gigabit speed!\n" - " Using Full Duplex.\n"); - DuplexCap = DC_FULL; - } - - if (AutoSet && AutoNeg==AN_SENS && DupSet) { - printk("sk98lin, Port B: DuplexCapabilities" - " ignored using Sense mode\n"); - } - - if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){ - printk("sk98lin: Port B: Illegal combination" - " of values AutoNeg. and DuplexCap.\n Using " - "Full Duplex\n"); - DuplexCap = DC_FULL; - } - - if (AutoSet && AutoNeg==AN_OFF && !DupSet) { - DuplexCap = DC_FULL; - } - - if (!AutoSet && DupSet) { - printk("sk98lin: Port B: Duplex setting not" - " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n"); - AutoNeg = AN_ON; - } - - /* - ** set the desired mode - */ - if (AutoSet || DupSet) { - pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap]; - } - - /* - ** c) Any FlowCtrl parameter set? - */ - if (FlowCtrl_B != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) { - IsFlowCtrlDefined = SK_FALSE; - } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) { - FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; - } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) { - FlowCtrl = SK_FLOW_MODE_SYMMETRIC; - } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) { - FlowCtrl = SK_FLOW_MODE_LOC_SEND; - } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) { - FlowCtrl = SK_FLOW_MODE_NONE; - } else { - printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n", - FlowCtrl_B[pAC->Index]); - IsFlowCtrlDefined = SK_FALSE; - } - } else { - IsFlowCtrlDefined = SK_FALSE; - } - - if (IsFlowCtrlDefined) { - if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) { - printk("sk98lin: Port B: FlowControl" - " impossible without AutoNegotiation," - " disabled\n"); - FlowCtrl = SK_FLOW_MODE_NONE; - } - pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl; - } - - /* - ** d) What is the RoleParameter? - */ - if (Role_B != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(Role_B[pAC->Index],"")==0) { - IsRoleDefined = SK_FALSE; - } else if (strcmp(Role_B[pAC->Index],"Auto")==0) { - MSMode = SK_MS_MODE_AUTO; - } else if (strcmp(Role_B[pAC->Index],"Master")==0) { - MSMode = SK_MS_MODE_MASTER; - } else if (strcmp(Role_B[pAC->Index],"Slave")==0) { - MSMode = SK_MS_MODE_SLAVE; - } else { - printk("sk98lin: Illegal value \"%s\" for Role_B\n", - Role_B[pAC->Index]); - IsRoleDefined = SK_FALSE; - } - } else { - IsRoleDefined = SK_FALSE; - } - - if (IsRoleDefined) { - pAC->GIni.GP[1].PMSMode = MSMode; - } - - /* - ** Evaluate settings for both ports - */ - pAC->ActivePort = 0; - if (PrefPort != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */ - pAC->ActivePort = 0; - pAC->Rlmt.Net[0].Preference = -1; /* auto */ - pAC->Rlmt.Net[0].PrefPort = 0; - } else if (strcmp(PrefPort[pAC->Index],"A") == 0) { - /* - ** do not set ActivePort here, thus a port - ** switch is issued after net up. - */ - Port = 0; - pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; - } else if (strcmp(PrefPort[pAC->Index],"B") == 0) { - /* - ** do not set ActivePort here, thus a port - ** switch is issued after net up. - */ - if (pAC->GIni.GIMacsFound == 1) { - printk("sk98lin: Illegal value \"B\" for PrefPort.\n" - " Port B not available on single port adapters.\n"); - - pAC->ActivePort = 0; - pAC->Rlmt.Net[0].Preference = -1; /* auto */ - pAC->Rlmt.Net[0].PrefPort = 0; - } else { - Port = 1; - pAC->Rlmt.Net[0].Preference = Port; - pAC->Rlmt.Net[0].PrefPort = Port; - } - } else { - printk("sk98lin: Illegal value \"%s\" for PrefPort\n", - PrefPort[pAC->Index]); - } - } - - pAC->RlmtNets = 1; - - if (RlmtMode != NULL && pAC->IndexIndex] != NULL) { - if (strcmp(RlmtMode[pAC->Index], "") == 0) { - pAC->RlmtMode = 0; - } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK; - } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK | - SK_RLMT_CHECK_LOC_LINK; - } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK | - SK_RLMT_CHECK_LOC_LINK | - SK_RLMT_CHECK_SEG; - } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) && - (pAC->GIni.GIMacsFound == 2)) { - pAC->RlmtMode = SK_RLMT_CHECK_LINK; - pAC->RlmtNets = 2; - } else { - printk("sk98lin: Illegal value \"%s\" for" - " RlmtMode, using default\n", - RlmtMode[pAC->Index]); - pAC->RlmtMode = 0; - } - } else { - pAC->RlmtMode = 0; - } - - /* - ** Check the interrupt moderation parameters - */ - if (Moderation[pAC->Index] != NULL) { - if (strcmp(Moderation[pAC->Index], "") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } else if (strcmp(Moderation[pAC->Index], "Static") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; - } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC; - } else if (strcmp(Moderation[pAC->Index], "None") == 0) { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } else { - printk("sk98lin: Illegal value \"%s\" for Moderation.\n" - " Disable interrupt moderation.\n", - Moderation[pAC->Index]); - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } - } else { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } - - if (Stats[pAC->Index] != NULL) { - if (strcmp(Stats[pAC->Index], "Yes") == 0) { - pAC->DynIrqModInfo.DisplayStats = SK_TRUE; - } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; - } - } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; - } - - if (ModerationMask[pAC->Index] != NULL) { - if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; - } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; - } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; - } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; - } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; - } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else { /* some rubbish */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; - } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } - - if (AutoSizing[pAC->Index] != NULL) { - if (strcmp(AutoSizing[pAC->Index], "On") == 0) { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } else { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } - - if (IntsPerSec[pAC->Index] != 0) { - if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || - (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { - printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n" - " Using default value of %i.\n", - IntsPerSec[pAC->Index], - C_INT_MOD_IPS_LOWER_RANGE, - C_INT_MOD_IPS_UPPER_RANGE, - C_INTS_PER_SEC_DEFAULT); - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; - } else { - pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; - } - } else { - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; - } - - /* - ** Evaluate upper and lower moderation threshold - */ - pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = - pAC->DynIrqModInfo.MaxModIntsPerSec + - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); - - pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = - pAC->DynIrqModInfo.MaxModIntsPerSec - - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); - - pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ - - -} /* GetConfiguration */ - - -/***************************************************************************** - * - * ProductStr - return a adapter identification string from vpd - * - * Description: - * This function reads the product name string from the vpd area - * and puts it the field pAC->DeviceString. - * - * Returns: N/A - */ -static inline int ProductStr( - SK_AC *pAC, /* pointer to adapter context */ - char *DeviceStr, /* result string */ - int StrLen /* length of the string */ -) -{ -char Keyword[] = VPD_NAME; /* vpd productname identifier */ -int ReturnCode; /* return code from vpd_read */ -unsigned long Flags; - - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - return ReturnCode; -} /* ProductStr */ - -/***************************************************************************** - * - * StartDrvCleanupTimer - Start timer to check for descriptors which - * might be placed in descriptor ring, but - * havent been handled up to now - * - * Description: - * This function requests a HW-timer fo the Yukon card. The actions to - * perform when this timer expires, are located in the SkDrvEvent(). - * - * Returns: N/A - */ -static void -StartDrvCleanupTimer(SK_AC *pAC) { - SK_EVPARA EventParam; /* Event struct for timer event */ - - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER; - SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer, - SK_DRV_RX_CLEANUP_TIMER_LENGTH, - SKGE_DRV, SK_DRV_TIMER, EventParam); -} - -/***************************************************************************** - * - * StopDrvCleanupTimer - Stop timer to check for descriptors - * - * Description: - * This function requests a HW-timer fo the Yukon card. The actions to - * perform when this timer expires, are located in the SkDrvEvent(). - * - * Returns: N/A - */ -static void -StopDrvCleanupTimer(SK_AC *pAC) { - SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer); - SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER)); -} - -/****************************************************************************/ -/* functions for common modules *********************************************/ -/****************************************************************************/ - - -/***************************************************************************** - * - * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf - * - * Description: - * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure - * is embedded into a socket buff data area. - * - * Context: - * runtime - * - * Returns: - * NULL or pointer to Mbuf. - */ -SK_MBUF *SkDrvAllocRlmtMbuf( -SK_AC *pAC, /* pointer to adapter context */ -SK_IOC IoC, /* the IO-context */ -unsigned BufferSize) /* size of the requested buffer */ -{ -SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */ -struct sk_buff *pMsgBlock; /* pointer to a new message block */ - - pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC); - if (pMsgBlock == NULL) { - return (NULL); - } - pRlmtMbuf = (SK_MBUF*) pMsgBlock->data; - skb_reserve(pMsgBlock, sizeof(SK_MBUF)); - pRlmtMbuf->pNext = NULL; - pRlmtMbuf->pOs = pMsgBlock; - pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */ - pRlmtMbuf->Size = BufferSize; /* Data buffer size. */ - pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */ - return (pRlmtMbuf); - -} /* SkDrvAllocRlmtMbuf */ - - -/***************************************************************************** - * - * SkDrvFreeRlmtMbuf - free an RLMT mbuf - * - * Description: - * This routine frees one or more RLMT mbuf(s). - * - * Context: - * runtime - * - * Returns: - * Nothing - */ -void SkDrvFreeRlmtMbuf( -SK_AC *pAC, /* pointer to adapter context */ -SK_IOC IoC, /* the IO-context */ -SK_MBUF *pMbuf) /* size of the requested buffer */ -{ -SK_MBUF *pFreeMbuf; -SK_MBUF *pNextMbuf; - - pFreeMbuf = pMbuf; - do { - pNextMbuf = pFreeMbuf->pNext; - DEV_KFREE_SKB_ANY(pFreeMbuf->pOs); - pFreeMbuf = pNextMbuf; - } while ( pFreeMbuf != NULL ); -} /* SkDrvFreeRlmtMbuf */ - - -/***************************************************************************** - * - * SkOsGetTime - provide a time value - * - * Description: - * This routine provides a time value. The unit is 1/HZ (defined by Linux). - * It is not used for absolute time, but only for time differences. - * - * - * Returns: - * Time value - */ -SK_U64 SkOsGetTime(SK_AC *pAC) -{ - SK_U64 PrivateJiffies; - SkOsGetTimeCurrent(pAC, &PrivateJiffies); - return PrivateJiffies; -} /* SkOsGetTime */ - - -/***************************************************************************** - * - * SkPciReadCfgDWord - read a 32 bit value from pci config space - * - * Description: - * This routine reads a 32 bit value from the pci configuration - * space. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -int SkPciReadCfgDWord( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U32 *pVal) /* pointer to store the read value */ -{ - pci_read_config_dword(pAC->PciDev, PciAddr, pVal); - return(0); -} /* SkPciReadCfgDWord */ - - -/***************************************************************************** - * - * SkPciReadCfgWord - read a 16 bit value from pci config space - * - * Description: - * This routine reads a 16 bit value from the pci configuration - * space. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -int SkPciReadCfgWord( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U16 *pVal) /* pointer to store the read value */ -{ - pci_read_config_word(pAC->PciDev, PciAddr, pVal); - return(0); -} /* SkPciReadCfgWord */ - - -/***************************************************************************** - * - * SkPciReadCfgByte - read a 8 bit value from pci config space - * - * Description: - * This routine reads a 8 bit value from the pci configuration - * space. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -int SkPciReadCfgByte( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U8 *pVal) /* pointer to store the read value */ -{ - pci_read_config_byte(pAC->PciDev, PciAddr, pVal); - return(0); -} /* SkPciReadCfgByte */ - - -/***************************************************************************** - * - * SkPciWriteCfgWord - write a 16 bit value to pci config space - * - * Description: - * This routine writes a 16 bit value to the pci configuration - * space. The flag PciConfigUp indicates whether the config space - * is accesible or must be set up first. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -int SkPciWriteCfgWord( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U16 Val) /* pointer to store the read value */ -{ - pci_write_config_word(pAC->PciDev, PciAddr, Val); - return(0); -} /* SkPciWriteCfgWord */ - - -/***************************************************************************** - * - * SkPciWriteCfgWord - write a 8 bit value to pci config space - * - * Description: - * This routine writes a 8 bit value to the pci configuration - * space. The flag PciConfigUp indicates whether the config space - * is accesible or must be set up first. - * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication - */ -int SkPciWriteCfgByte( -SK_AC *pAC, /* Adapter Control structure pointer */ -int PciAddr, /* PCI register address */ -SK_U8 Val) /* pointer to store the read value */ -{ - pci_write_config_byte(pAC->PciDev, PciAddr, Val); - return(0); -} /* SkPciWriteCfgByte */ - - -/***************************************************************************** - * - * SkDrvEvent - handle driver events - * - * Description: - * This function handles events from all modules directed to the driver - * - * Context: - * Is called under protection of slow path lock. - * - * Returns: - * 0 if everything ok - * < 0 on error - * - */ -int SkDrvEvent( -SK_AC *pAC, /* pointer to adapter context */ -SK_IOC IoC, /* io-context */ -SK_U32 Event, /* event-id */ -SK_EVPARA Param) /* event-parameter */ -{ -SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */ -struct sk_buff *pMsg; /* pointer to a message block */ -int FromPort; /* the port from which we switch away */ -int ToPort; /* the port we switch to */ -SK_EVPARA NewPara; /* parameter for further events */ -int Stat; -unsigned long Flags; -SK_BOOL DualNet; - - switch (Event) { - case SK_DRV_ADAP_FAIL: - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("ADAPTER FAIL EVENT\n")); - printk("%s: Adapter failed.\n", pAC->dev[0]->name); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - /* cgoos */ - break; - case SK_DRV_PORT_FAIL: - FromPort = Param.Para32[0]; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("PORT FAIL EVENT, Port: %d\n", FromPort)); - if (FromPort == 0) { - printk("%s: Port A failed.\n", pAC->dev[0]->name); - } else { - printk("%s: Port B failed.\n", pAC->dev[1]->name); - } - /* cgoos */ - break; - case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */ - /* action list 4 */ - FromPort = Param.Para32[0]; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("PORT RESET EVENT, Port: %d ", FromPort)); - NewPara.Para64 = FromPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); - spin_lock_irqsave( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - - SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); - netif_carrier_off(pAC->dev[Param.Para32[0]]); - spin_unlock_irqrestore( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - - /* clear rx ring from received frames */ - ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); - - ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); - spin_lock_irqsave( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - - /* tschilling: Handling of return value inserted. */ - if (SkGeInitPort(pAC, IoC, FromPort)) { - if (FromPort == 0) { - printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); - } else { - printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); - } - } - SkAddrMcUpdate(pAC,IoC, FromPort); - PortReInitBmu(pAC, FromPort); - SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); - ClearAndStartRx(pAC, FromPort); - spin_unlock_irqrestore( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - break; - case SK_DRV_NET_UP: /* SK_U32 PortIdx */ - { struct net_device *dev = pAC->dev[Param.Para32[0]]; - /* action list 5 */ - FromPort = Param.Para32[0]; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("NET UP EVENT, Port: %d ", Param.Para32[0])); - /* Mac update */ - SkAddrMcUpdate(pAC,IoC, FromPort); - - if (DoPrintInterfaceChange) { - printk("%s: network connection up using" - " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); - - /* tschilling: Values changed according to LinkSpeedUsed. */ - Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed; - if (Stat == SK_LSPEED_STAT_10MBPS) { - printk(" speed: 10\n"); - } else if (Stat == SK_LSPEED_STAT_100MBPS) { - printk(" speed: 100\n"); - } else if (Stat == SK_LSPEED_STAT_1000MBPS) { - printk(" speed: 1000\n"); - } else { - printk(" speed: unknown\n"); - } - - - Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; - if (Stat == SK_LMODE_STAT_AUTOHALF || - Stat == SK_LMODE_STAT_AUTOFULL) { - printk(" autonegotiation: yes\n"); - } - else { - printk(" autonegotiation: no\n"); - } - if (Stat == SK_LMODE_STAT_AUTOHALF || - Stat == SK_LMODE_STAT_HALF) { - printk(" duplex mode: half\n"); - } - else { - printk(" duplex mode: full\n"); - } - Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus; - if (Stat == SK_FLOW_STAT_REM_SEND ) { - printk(" flowctrl: remote send\n"); - } - else if (Stat == SK_FLOW_STAT_LOC_SEND ){ - printk(" flowctrl: local send\n"); - } - else if (Stat == SK_FLOW_STAT_SYMMETRIC ){ - printk(" flowctrl: symmetric\n"); - } - else { - printk(" flowctrl: none\n"); - } - - /* tschilling: Check against CopperType now. */ - if ((pAC->GIni.GICopperType == SK_TRUE) && - (pAC->GIni.GP[FromPort].PLinkSpeedUsed == - SK_LSPEED_STAT_1000MBPS)) { - Stat = pAC->GIni.GP[FromPort].PMSStatus; - if (Stat == SK_MS_STAT_MASTER ) { - printk(" role: master\n"); - } - else if (Stat == SK_MS_STAT_SLAVE ) { - printk(" role: slave\n"); - } - else { - printk(" role: ???\n"); - } - } - - /* - Display dim (dynamic interrupt moderation) - informations - */ - if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) - printk(" irq moderation: static (%d ints/sec)\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) - printk(" irq moderation: dynamic (%d ints/sec)\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - else - printk(" irq moderation: disabled\n"); - - - printk(" scatter-gather: %s\n", - (dev->features & NETIF_F_SG) ? "enabled" : "disabled"); - printk(" tx-checksum: %s\n", - (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled"); - printk(" rx-checksum: %s\n", - pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled"); - - } else { - DoPrintInterfaceChange = SK_TRUE; - } - - if ((Param.Para32[0] != pAC->ActivePort) && - (pAC->RlmtNets == 1)) { - NewPara.Para32[0] = pAC->ActivePort; - NewPara.Para32[1] = Param.Para32[0]; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, - NewPara); - } - - /* Inform the world that link protocol is up. */ - netif_carrier_on(dev); - break; - } - case SK_DRV_NET_DOWN: /* SK_U32 Reason */ - /* action list 7 */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("NET DOWN EVENT ")); - if (DoPrintInterfaceChange) { - printk("%s: network connection down\n", - pAC->dev[Param.Para32[1]]->name); - } else { - DoPrintInterfaceChange = SK_TRUE; - } - netif_carrier_off(pAC->dev[Param.Para32[1]]); - break; - case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("PORT SWITCH HARD ")); - case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ - /* action list 6 */ - printk("%s: switching to port %c\n", pAC->dev[0]->name, - 'A'+Param.Para32[1]); - case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ - FromPort = Param.Para32[0]; - ToPort = Param.Para32[1]; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ", - FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort)); - NewPara.Para64 = FromPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); - NewPara.Para64 = ToPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); - spin_lock_irqsave( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); - SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); - SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); - spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); - spin_unlock_irqrestore( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - - ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ - ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ - - ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); - ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); - spin_lock_irqsave( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); - pAC->ActivePort = ToPort; -#if 0 - SetQueueSizes(pAC); -#else - /* tschilling: New common function with minimum size check. */ - DualNet = SK_FALSE; - if (pAC->RlmtNets == 2) { - DualNet = SK_TRUE; - } - - if (SkGeInitAssignRamToQueues( - pAC, - pAC->ActivePort, - DualNet)) { - spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); - spin_unlock_irqrestore( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - printk("SkGeInitAssignRamToQueues failed.\n"); - break; - } -#endif - /* tschilling: Handling of return values inserted. */ - if (SkGeInitPort(pAC, IoC, FromPort) || - SkGeInitPort(pAC, IoC, ToPort)) { - printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name); - } - if (Event == SK_DRV_SWITCH_SOFT) { - SkMacRxTxEnable(pAC, IoC, FromPort); - } - SkMacRxTxEnable(pAC, IoC, ToPort); - SkAddrSwap(pAC, IoC, FromPort, ToPort); - SkAddrMcUpdate(pAC, IoC, FromPort); - SkAddrMcUpdate(pAC, IoC, ToPort); - PortReInitBmu(pAC, FromPort); - PortReInitBmu(pAC, ToPort); - SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); - SkGePollTxD(pAC, IoC, ToPort, SK_TRUE); - ClearAndStartRx(pAC, FromPort); - ClearAndStartRx(pAC, ToPort); - spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); - spin_unlock_irqrestore( - &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, - Flags); - break; - case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("RLS ")); - pRlmtMbuf = (SK_MBUF*) Param.pParaPtr; - pMsg = (struct sk_buff*) pRlmtMbuf->pOs; - skb_put(pMsg, pRlmtMbuf->Length); - if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], - pMsg) < 0) - - DEV_KFREE_SKB_ANY(pMsg); - break; - case SK_DRV_TIMER: - if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) { - /* - ** expiration of the moderation timer implies that - ** dynamic moderation is to be applied - */ - SkDimStartModerationTimer(pAC); - SkDimModerate(pAC); - if (pAC->DynIrqModInfo.DisplayStats) { - SkDimDisplayModerationSettings(pAC); - } - } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) { - /* - ** check if we need to check for descriptors which - ** haven't been handled the last millisecs - */ - StartDrvCleanupTimer(pAC); - if (pAC->GIni.GIMacsFound == 2) { - ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE); - } - ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE); - } else { - printk("Expiration of unknown timer\n"); - } - break; - default: - break; - } - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("END EVENT ")); - - return (0); -} /* SkDrvEvent */ - - -/***************************************************************************** - * - * SkErrorLog - log errors - * - * Description: - * This function logs errors to the system buffer and to the console - * - * Returns: - * 0 if everything ok - * < 0 on error - * - */ -void SkErrorLog( -SK_AC *pAC, -int ErrClass, -int ErrNum, -char *pErrorMsg) -{ -char ClassStr[80]; - - switch (ErrClass) { - case SK_ERRCL_OTHER: - strcpy(ClassStr, "Other error"); - break; - case SK_ERRCL_CONFIG: - strcpy(ClassStr, "Configuration error"); - break; - case SK_ERRCL_INIT: - strcpy(ClassStr, "Initialization error"); - break; - case SK_ERRCL_NORES: - strcpy(ClassStr, "Out of resources error"); - break; - case SK_ERRCL_SW: - strcpy(ClassStr, "internal Software error"); - break; - case SK_ERRCL_HW: - strcpy(ClassStr, "Hardware failure"); - break; - case SK_ERRCL_COMM: - strcpy(ClassStr, "Communication error"); - break; - } - printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n" - " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name, - ClassStr, ErrNum, pErrorMsg); - -} /* SkErrorLog */ - -#ifdef SK_DIAG_SUPPORT - -/***************************************************************************** - * - * SkDrvEnterDiagMode - handles DIAG attach request - * - * Description: - * Notify the kernel to NOT access the card any longer due to DIAG - * Deinitialize the Card - * - * Returns: - * int - */ -int SkDrvEnterDiagMode( -SK_AC *pAc) /* pointer to adapter context */ -{ - DEV_NET *pNet = netdev_priv(pAc->dev[0]); - SK_AC *pAC = pNet->pAC; - - SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), - sizeof(SK_PNMI_STRUCT_DATA)); - - pAC->DiagModeActive = DIAG_ACTIVE; - if (pAC->BoardLevel > SK_INIT_DATA) { - if (netif_running(pAC->dev[0])) { - pAC->WasIfUp[0] = SK_TRUE; - pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ - DoPrintInterfaceChange = SK_FALSE; - SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ - } else { - pAC->WasIfUp[0] = SK_FALSE; - } - if (pNet != netdev_priv(pAC->dev[1])) { - pNet = netdev_priv(pAC->dev[1]); - if (netif_running(pAC->dev[1])) { - pAC->WasIfUp[1] = SK_TRUE; - pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ - DoPrintInterfaceChange = SK_FALSE; - SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */ - } else { - pAC->WasIfUp[1] = SK_FALSE; - } - } - pAC->BoardLevel = SK_INIT_DATA; - } - return(0); -} - -/***************************************************************************** - * - * SkDrvLeaveDiagMode - handles DIAG detach request - * - * Description: - * Notify the kernel to may access the card again after use by DIAG - * Initialize the Card - * - * Returns: - * int - */ -int SkDrvLeaveDiagMode( -SK_AC *pAc) /* pointer to adapter control context */ -{ - SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), - sizeof(SK_PNMI_STRUCT_DATA)); - pAc->DiagModeActive = DIAG_NOTACTIVE; - pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; - if (pAc->WasIfUp[0] == SK_TRUE) { - pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ - DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAc, 0); /* first device */ - } - if (pAc->WasIfUp[1] == SK_TRUE) { - pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ - DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAc, 1); /* second device */ - } - return(0); -} - -/***************************************************************************** - * - * ParseDeviceNbrFromSlotName - Evaluate PCI device number - * - * Description: - * This function parses the PCI slot name information string and will - * retrieve the devcie number out of it. The slot_name maintianed by - * linux is in the form of '02:0a.0', whereas the first two characters - * represent the bus number in hex (in the sample above this is - * pci bus 0x02) and the next two characters the device number (0x0a). - * - * Returns: - * SK_U32: The device number from the PCI slot name - */ - -static SK_U32 ParseDeviceNbrFromSlotName( -const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */ -{ - char *CurrCharPos = (char *) SlotName; - int FirstNibble = -1; - int SecondNibble = -1; - SK_U32 Result = 0; - - while (*CurrCharPos != '\0') { - if (*CurrCharPos == ':') { - while (*CurrCharPos != '.') { - CurrCharPos++; - if ( (*CurrCharPos >= '0') && - (*CurrCharPos <= '9')) { - if (FirstNibble == -1) { - /* dec. value for '0' */ - FirstNibble = *CurrCharPos - 48; - } else { - SecondNibble = *CurrCharPos - 48; - } - } else if ( (*CurrCharPos >= 'a') && - (*CurrCharPos <= 'f') ) { - if (FirstNibble == -1) { - FirstNibble = *CurrCharPos - 87; - } else { - SecondNibble = *CurrCharPos - 87; - } - } else { - Result = 0; - } - } - - Result = FirstNibble; - Result = Result << 4; /* first nibble is higher one */ - Result = Result | SecondNibble; - } - CurrCharPos++; /* next character */ - } - return (Result); -} - -/**************************************************************************** - * - * SkDrvDeInitAdapter - deinitialize adapter (this function is only - * called if Diag attaches to that card) - * - * Description: - * Close initialized adapter. - * - * Returns: - * 0 - on success - * error code - on error - */ -static int SkDrvDeInitAdapter( -SK_AC *pAC, /* pointer to adapter context */ -int devNbr) /* what device is to be handled */ -{ - struct SK_NET_DEVICE *dev; - - dev = pAC->dev[devNbr]; - - /* On Linux 2.6 the network driver does NOT mess with reference - ** counts. The driver MUST be able to be unloaded at any time - ** due to the possibility of hotplug. - */ - if (SkGeClose(dev) != 0) { - return (-1); - } - return (0); - -} /* SkDrvDeInitAdapter() */ - -/**************************************************************************** - * - * SkDrvInitAdapter - Initialize adapter (this function is only - * called if Diag deattaches from that card) - * - * Description: - * Close initialized adapter. - * - * Returns: - * 0 - on success - * error code - on error - */ -static int SkDrvInitAdapter( -SK_AC *pAC, /* pointer to adapter context */ -int devNbr) /* what device is to be handled */ -{ - struct SK_NET_DEVICE *dev; - - dev = pAC->dev[devNbr]; - - if (SkGeOpen(dev) != 0) { - return (-1); - } - - /* - ** Use correct MTU size and indicate to kernel TX queue can be started - */ - if (SkGeChangeMtu(dev, dev->mtu) != 0) { - return (-1); - } - return (0); - -} /* SkDrvInitAdapter */ - -#endif - -#ifdef DEBUG -/****************************************************************************/ -/* "debug only" section *****************************************************/ -/****************************************************************************/ - - -/***************************************************************************** - * - * DumpMsg - print a frame - * - * Description: - * This function prints frames to the system logfile/to the console. - * - * Returns: N/A - * - */ -static void DumpMsg(struct sk_buff *skb, char *str) -{ - int msglen; - - if (skb == NULL) { - printk("DumpMsg(): NULL-Message\n"); - return; - } - - if (skb->data == NULL) { - printk("DumpMsg(): Message empty\n"); - return; - } - - msglen = skb->len; - if (msglen > 64) - msglen = 64; - - printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len); - - DumpData((char *)skb->data, msglen); - - printk("------- End of message ---------\n"); -} /* DumpMsg */ - - - -/***************************************************************************** - * - * DumpData - print a data area - * - * Description: - * This function prints a area of data to the system logfile/to the - * console. - * - * Returns: N/A - * - */ -static void DumpData(char *p, int size) -{ -register int i; -int haddr, addr; -char hex_buffer[180]; -char asc_buffer[180]; -char HEXCHAR[] = "0123456789ABCDEF"; - - addr = 0; - haddr = 0; - hex_buffer[0] = 0; - asc_buffer[0] = 0; - for (i=0; i < size; ) { - if (*p >= '0' && *p <='z') - asc_buffer[addr] = *p; - else - asc_buffer[addr] = '.'; - addr++; - asc_buffer[addr] = 0; - hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4]; - haddr++; - hex_buffer[haddr] = HEXCHAR[*p & 0x0f]; - haddr++; - hex_buffer[haddr] = ' '; - haddr++; - hex_buffer[haddr] = 0; - p++; - i++; - if (i%16 == 0) { - printk("%s %s\n", hex_buffer, asc_buffer); - addr = 0; - haddr = 0; - } - } -} /* DumpData */ - - -/***************************************************************************** - * - * DumpLong - print a data area as long values - * - * Description: - * This function prints a area of data to the system logfile/to the - * console. - * - * Returns: N/A - * - */ -static void DumpLong(char *pc, int size) -{ -register int i; -int haddr, addr; -char hex_buffer[180]; -char asc_buffer[180]; -char HEXCHAR[] = "0123456789ABCDEF"; -long *p; -int l; - - addr = 0; - haddr = 0; - hex_buffer[0] = 0; - asc_buffer[0] = 0; - p = (long*) pc; - for (i=0; i < size; ) { - l = (long) *p; - hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf]; - haddr++; - hex_buffer[haddr] = HEXCHAR[l & 0x0f]; - haddr++; - hex_buffer[haddr] = ' '; - haddr++; - hex_buffer[haddr] = 0; - p++; - i++; - if (i%8 == 0) { - printk("%4x %s\n", (i-8)*4, hex_buffer); - haddr = 0; - } - } - printk("------------------------\n"); -} /* DumpLong */ - -#endif - -static int __devinit skge_probe_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - SK_AC *pAC; - DEV_NET *pNet = NULL; - struct net_device *dev = NULL; - static int boards_found = 0; - int error = -ENODEV; - int using_dac = 0; - char DeviceStr[80]; - - if (pci_enable_device(pdev)) - goto out; - - /* Configure DMA attributes. */ - if (sizeof(dma_addr_t) > sizeof(u32) && - !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { - using_dac = 1; - error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (error < 0) { - printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA " - "for consistent allocations\n", pci_name(pdev)); - goto out_disable_device; - } - } else { - error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (error) { - printk(KERN_ERR "sk98lin %s no usable DMA configuration\n", - pci_name(pdev)); - goto out_disable_device; - } - } - - error = -ENOMEM; - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "sk98lin: unable to allocate etherdev " - "structure!\n"); - goto out_disable_device; - } - - pNet = netdev_priv(dev); - pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL); - if (!pNet->pAC) { - printk(KERN_ERR "sk98lin: unable to allocate adapter " - "structure!\n"); - goto out_free_netdev; - } - - pAC = pNet->pAC; - pAC->PciDev = pdev; - - pAC->dev[0] = dev; - pAC->dev[1] = dev; - pAC->CheckQueue = SK_FALSE; - - dev->irq = pdev->irq; - - error = SkGeInitPCI(pAC); - if (error) { - printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error); - goto out_free_netdev; - } - - SET_MODULE_OWNER(dev); - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &SkGePollController; -#endif - SET_NETDEV_DEV(dev, &pdev->dev); - SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); - - /* Use only if yukon hardware */ - if (pAC->ChipsetType) { -#ifdef USE_SK_TX_CHECKSUM - dev->features |= NETIF_F_IP_CSUM; -#endif -#ifdef SK_ZEROCOPY - dev->features |= NETIF_F_SG; -#endif -#ifdef USE_SK_RX_CHECKSUM - pAC->RxPort[0].RxCsum = 1; -#endif - } - - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - - pAC->Index = boards_found++; - - error = SkGeBoardInit(dev, pAC); - if (error) - goto out_free_netdev; - - /* Read Adapter name from VPD */ - if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) { - error = -EIO; - printk(KERN_ERR "sk98lin: Could not read VPD data.\n"); - goto out_free_resources; - } - - /* Register net device */ - error = register_netdev(dev); - if (error) { - printk(KERN_ERR "sk98lin: Could not register device.\n"); - goto out_free_resources; - } - - /* Print adapter specific string from vpd */ - printk("%s: %s\n", dev->name, DeviceStr); - - /* Print configuration settings */ - printk(" PrefPort:%c RlmtMode:%s\n", - 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, - (pAC->RlmtMode==0) ? "Check Link State" : - ((pAC->RlmtMode==1) ? "Check Link State" : - ((pAC->RlmtMode==3) ? "Check Local Port" : - ((pAC->RlmtMode==7) ? "Check Segmentation" : - ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); - - SkGeYellowLED(pAC, pAC->IoBase, 1); - - memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - pNet->PortNr = 0; - pNet->NetNr = 0; - - boards_found++; - - pci_set_drvdata(pdev, dev); - - /* More then one port found */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "sk98lin: unable to allocate etherdev " - "structure!\n"); - goto single_port; - } - - pNet = netdev_priv(dev); - pNet->PortNr = 1; - pNet->NetNr = 1; - pNet->pAC = pAC; - - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - SET_NETDEV_DEV(dev, &pdev->dev); - SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); - - if (pAC->ChipsetType) { -#ifdef USE_SK_TX_CHECKSUM - dev->features |= NETIF_F_IP_CSUM; -#endif -#ifdef SK_ZEROCOPY - dev->features |= NETIF_F_SG; -#endif -#ifdef USE_SK_RX_CHECKSUM - pAC->RxPort[1].RxCsum = 1; -#endif - } - - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - - error = register_netdev(dev); - if (error) { - printk(KERN_ERR "sk98lin: Could not register device" - " for second port. (%d)\n", error); - free_netdev(dev); - goto single_port; - } - - pAC->dev[1] = dev; - memcpy(&dev->dev_addr, - &pAC->Addr.Net[1].CurrentMacAddress, 6); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - printk("%s: %s\n", dev->name, DeviceStr); - printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - } - -single_port: - - /* Save the hardware revision */ - pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + - (pAC->GIni.GIPciHwRev & 0x0F); - - /* Set driver globals */ - pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; - pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; - - memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA)); - memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA)); - - return 0; - - out_free_resources: - FreeResources(dev); - out_free_netdev: - free_netdev(dev); - out_disable_device: - pci_disable_device(pdev); - out: - return error; -} - -static void __devexit skge_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - struct net_device *otherdev = pAC->dev[1]; - - unregister_netdev(dev); - - SkGeYellowLED(pAC, pAC->IoBase, 0); - - if (pAC->BoardLevel == SK_INIT_RUN) { - SK_EVPARA EvPara; - unsigned long Flags; - - /* board is still alive */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - EvPara.Para32[0] = 0; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - SkGeDeInit(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pAC->BoardLevel = SK_INIT_DATA; - /* We do NOT check here, if IRQ was pending, of course*/ - } - - if (pAC->BoardLevel == SK_INIT_IO) { - /* board is still alive */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = SK_INIT_DATA; - } - - FreeResources(dev); - free_netdev(dev); - if (otherdev != dev) - free_netdev(otherdev); - kfree(pAC); -} - -#ifdef CONFIG_PM -static int skge_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - struct net_device *otherdev = pAC->dev[1]; - - if (netif_running(dev)) { - netif_carrier_off(dev); - DoPrintInterfaceChange = SK_FALSE; - SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ - netif_device_detach(dev); - } - if (otherdev != dev) { - if (netif_running(otherdev)) { - netif_carrier_off(otherdev); - DoPrintInterfaceChange = SK_FALSE; - SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */ - netif_device_detach(otherdev); - } - } - - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); - if (pAC->AllocFlag & SK_ALLOC_IRQ) { - free_irq(dev->irq, dev); - } - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - return 0; -} - -static int skge_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - DEV_NET *pNet = netdev_priv(dev); - SK_AC *pAC = pNet->pAC; - struct net_device *otherdev = pAC->dev[1]; - int ret; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - ret = pci_enable_device(pdev); - if (ret) { - printk(KERN_WARNING "sk98lin: unable to enable device %s " - "in resume\n", dev->name); - goto err_out; - } - pci_set_master(pdev); - if (pAC->GIni.GIMacsFound == 2) - ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); - else - ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); - if (ret) { - printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); - ret = -EBUSY; - goto err_out_disable_pdev; - } - - netif_device_attach(dev); - if (netif_running(dev)) { - DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAC, 0); /* first device */ - } - if (otherdev != dev) { - netif_device_attach(otherdev); - if (netif_running(otherdev)) { - DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAC, 1); /* second device */ - } - } - - return 0; - -err_out_disable_pdev: - pci_disable_device(pdev); -err_out: - pAC->AllocFlag &= ~SK_ALLOC_IRQ; - dev->irq = 0; - return ret; -} -#else -#define skge_suspend NULL -#define skge_resume NULL -#endif - -static struct pci_device_id skge_pci_tbl[] = { - { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -/* DLink card does not have valid VPD so this driver gags - * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - */ - { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, }, - { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, skge_pci_tbl); - -static struct pci_driver skge_driver = { - .name = "sk98lin", - .id_table = skge_pci_tbl, - .probe = skge_probe_one, - .remove = __devexit_p(skge_remove_one), - .suspend = skge_suspend, - .resume = skge_resume, -}; - -static int __init skge_init(void) -{ - printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver" - " and is scheduled for removal\n"); - - return pci_register_driver(&skge_driver); -} - -static void __exit skge_exit(void) -{ - pci_unregister_driver(&skge_driver); -} - -module_init(skge_init); -module_exit(skge_exit); diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c deleted file mode 100644 index db670993c2df..000000000000 --- a/drivers/net/sk98lin/skgehwt.c +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** - * - * Name: skgehwt.c - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.15 $ - * Date: $Date: 2003/09/16 13:41:23 $ - * Purpose: Hardware Timer - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * Event queue and dispatcher - */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell."; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#ifdef __C2MAN__ -/* - * Hardware Timer function queue management. - */ -intro() -{} -#endif - -/* - * Prototypes of local functions. - */ -#define SK_HWT_MAX (65000) - -/* correction factor */ -#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100) - -/* - * Initialize hardware timer. - * - * Must be called during init level 1. - */ -void SkHwtInit( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc) /* IoContext */ -{ - pAC->Hwt.TStart = 0 ; - pAC->Hwt.TStop = 0 ; - pAC->Hwt.TActive = SK_FALSE; - - SkHwtStop(pAC, Ioc); -} - -/* - * - * Start hardware timer (clock ticks are 16us). - * - */ -void SkHwtStart( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc, /* IoContext */ -SK_U32 Time) /* Time in units of 16us to load the timer with. */ -{ - SK_U32 Cnt; - - if (Time > SK_HWT_MAX) - Time = SK_HWT_MAX; - - pAC->Hwt.TStart = Time; - pAC->Hwt.TStop = 0L; - - Cnt = Time; - - /* - * if time < 16 us - * time = 16 us - */ - if (!Cnt) { - Cnt++; - } - - SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC); - - SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */ - - pAC->Hwt.TActive = SK_TRUE; -} - -/* - * Stop hardware timer. - * and clear the timer IRQ - */ -void SkHwtStop( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc) /* IoContext */ -{ - SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP); - - SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ); - - pAC->Hwt.TActive = SK_FALSE; -} - - -/* - * Stop hardware timer and read time elapsed since last start. - * - * returns - * The elapsed time since last start in units of 16us. - * - */ -SK_U32 SkHwtRead( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc) /* IoContext */ -{ - SK_U32 TRead; - SK_U32 IStatus; - - if (pAC->Hwt.TActive) { - - SkHwtStop(pAC, Ioc); - - SK_IN32(Ioc, B2_TI_VAL, &TRead); - TRead /= SK_HWT_FAC; - - SK_IN32(Ioc, B0_ISRC, &IStatus); - - /* Check if timer expired (or wraped around) */ - if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { - - SkHwtStop(pAC, Ioc); - - pAC->Hwt.TStop = pAC->Hwt.TStart; - } - else { - - pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; - } - } - return(pAC->Hwt.TStop); -} - -/* - * interrupt source= timer - */ -void SkHwtIsr( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc) /* IoContext */ -{ - SkHwtStop(pAC, Ioc); - - pAC->Hwt.TStop = pAC->Hwt.TStart; - - SkTimerDone(pAC, Ioc); -} - -/* End of file */ diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c deleted file mode 100644 index 67f1d6a5c15d..000000000000 --- a/drivers/net/sk98lin/skgeinit.c +++ /dev/null @@ -1,2005 +0,0 @@ -/****************************************************************************** - * - * Name: skgeinit.c - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.97 $ - * Date: $Date: 2003/10/02 16:45:31 $ - * Purpose: Contains functions to initialize the adapter - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" - -/* global variables ***********************************************************/ - -/* local variables ************************************************************/ - -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell."; -#endif - -struct s_QOffTab { - int RxQOff; /* Receive Queue Address Offset */ - int XsQOff; /* Sync Tx Queue Address Offset */ - int XaQOff; /* Async Tx Queue Address Offset */ -}; -static struct s_QOffTab QOffTab[] = { - {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} -}; - -struct s_Config { - char ScanString[8]; - SK_U32 Value; -}; - -static struct s_Config OemConfig = { - {'O','E','M','_','C','o','n','f'}, -#ifdef SK_OEM_CONFIG - OEM_CONFIG_VALUE, -#else - 0, -#endif -}; - -/****************************************************************************** - * - * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings - * - * Description: - * Enable or disable the descriptor polling of the transmit descriptor - * ring(s) (TxD) for port 'Port'. - * The new configuration is *not* saved over any SkGeStopPort() and - * SkGeInitPort() calls. - * - * Returns: - * nothing - */ -void SkGePollTxD( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ -{ - SK_GEPORT *pPrt; - SK_U32 DWord; - - pPrt = &pAC->GIni.GP[Port]; - - DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL); - - if (pPrt->PXSQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); - } - - if (pPrt->PXAQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); - } -} /* SkGePollTxD */ - - -/****************************************************************************** - * - * SkGeYellowLED() - Switch the yellow LED on or off. - * - * Description: - * Switch the yellow LED on or off. - * - * Note: - * This function may be called any time after SkGeInit(Level 1). - * - * Returns: - * nothing - */ -void SkGeYellowLED( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int State) /* yellow LED state, 0 = OFF, 0 != ON */ -{ - if (State == 0) { - /* Switch yellow LED OFF */ - SK_OUT8(IoC, B0_LED, LED_STAT_OFF); - } - else { - /* Switch yellow LED ON */ - SK_OUT8(IoC, B0_LED, LED_STAT_ON); - } -} /* SkGeYellowLED */ - - -#if (!defined(SK_SLIM) || defined(GENESIS)) -/****************************************************************************** - * - * SkGeXmitLED() - Modify the Operational Mode of a transmission LED. - * - * Description: - * The Rx or Tx LED which is specified by 'Led' will be - * enabled, disabled or switched on in test mode. - * - * Note: - * 'Led' must contain the address offset of the LEDs INI register. - * - * Usage: - * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); - * - * Returns: - * nothing - */ -void SkGeXmitLED( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Led, /* offset to the LED Init Value register */ -int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */ -{ - SK_U32 LedIni; - - switch (Mode) { - case SK_LED_ENA: - LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; - SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni); - SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); - break; - case SK_LED_TST: - SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON); - SK_OUT32(IoC, Led + XMIT_LED_CNT, 100); - SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START); - break; - case SK_LED_DIS: - default: - /* - * Do NOT stop the LED Timer here. The LED might be - * in on state. But it needs to go off. - */ - SK_OUT32(IoC, Led + XMIT_LED_CNT, 0); - SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF); - break; - } - - /* - * 1000BT: The Transmit LED is driven by the PHY. - * But the default LED configuration is used for - * Level One and Broadcom PHYs. - * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.) - * (In this case it has to be added here. But we will see. XXX) - */ -} /* SkGeXmitLED */ -#endif /* !SK_SLIM || GENESIS */ - - -/****************************************************************************** - * - * DoCalcAddr() - Calculates the start and the end address of a queue. - * - * Description: - * This function calculates the start and the end address of a queue. - * Afterwards the 'StartVal' is incremented to the next start position. - * If the port is already initialized the calculated values - * will be checked against the configured values and an - * error will be returned, if they are not equal. - * If the port is not initialized the values will be written to - * *StartAdr and *EndAddr. - * - * Returns: - * 0: success - * 1: configuration error - */ -static int DoCalcAddr( -SK_AC *pAC, /* adapter context */ -SK_GEPORT SK_FAR *pPrt, /* port index */ -int QuSize, /* size of the queue to configure in kB */ -SK_U32 SK_FAR *StartVal, /* start value for address calculation */ -SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */ -SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */ -{ - SK_U32 EndVal; - SK_U32 NextStart; - int Rtv; - - Rtv = 0; - if (QuSize == 0) { - EndVal = *StartVal; - NextStart = EndVal; - } - else { - EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1; - NextStart = EndVal + 1; - } - - if (pPrt->PState >= SK_PRT_INIT) { - if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) { - Rtv = 1; - } - } - else { - *QuStartAddr = *StartVal; - *QuEndAddr = EndVal; - } - - *StartVal = NextStart; - return(Rtv); -} /* DoCalcAddr */ - -/****************************************************************************** - * - * SkGeInitAssignRamToQueues() - allocate default queue sizes - * - * Description: - * This function assigns the memory to the different queues and ports. - * When DualNet is set to SK_TRUE all ports get the same amount of memory. - * Otherwise the first port gets most of the memory and all the - * other ports just the required minimum. - * This function can only be called when pAC->GIni.GIRamSize and - * pAC->GIni.GIMacsFound have been initialized, usually this happens - * at init level 1 - * - * Returns: - * 0 - ok - * 1 - invalid input values - * 2 - not enough memory - */ - -int SkGeInitAssignRamToQueues( -SK_AC *pAC, /* Adapter context */ -int ActivePort, /* Active Port in RLMT mode */ -SK_BOOL DualNet) /* adapter context */ -{ - int i; - int UsedKilobytes; /* memory already assigned */ - int ActivePortKilobytes; /* memory available for active port */ - SK_GEPORT *pGePort; - - UsedKilobytes = 0; - - if (ActivePort >= pAC->GIni.GIMacsFound) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", - ActivePort)); - return(1); - } - if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + - ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", - pAC->GIni.GIRamSize)); - return(2); - } - - if (DualNet) { - /* every port gets the same amount of memory */ - ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - - pGePort = &pAC->GIni.GP[i]; - - /* take away the minimum memory for active queues */ - ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); - - /* receive queue gets the minimum + 80% of the rest */ - pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( - ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) - + SK_MIN_RXQ_SIZE; - - ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); - - /* synchronous transmit queue */ - pGePort->PXSQSize = 0; - - /* asynchronous transmit queue */ - pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + - SK_MIN_TXQ_SIZE); - } - } - else { - /* Rlmt Mode or single link adapter */ - - /* Set standby queue size defaults for all standby ports */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - - if (i != ActivePort) { - pGePort = &pAC->GIni.GP[i]; - - pGePort->PRxQSize = SK_MIN_RXQ_SIZE; - pGePort->PXAQSize = SK_MIN_TXQ_SIZE; - pGePort->PXSQSize = 0; - - /* Count used RAM */ - UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; - } - } - /* what's left? */ - ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; - - /* assign it to the active port */ - /* first take away the minimum memory */ - ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); - pGePort = &pAC->GIni.GP[ActivePort]; - - /* receive queue get's the minimum + 80% of the rest */ - pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * - (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; - - ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); - - /* synchronous transmit queue */ - pGePort->PXSQSize = 0; - - /* asynchronous transmit queue */ - pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + - SK_MIN_TXQ_SIZE; - } -#ifdef VCPU - VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", - pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); -#endif /* VCPU */ - - return(0); -} /* SkGeInitAssignRamToQueues */ - -/****************************************************************************** - * - * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration - * - * Description: - * This function verifies the Queue Size Configuration specified - * in the variables PRxQSize, PXSQSize, and PXAQSize of all - * used ports. - * This requirements must be fullfilled to have a valid configuration: - * - The size of all queues must not exceed GIRamSize. - * - The queue sizes must be specified in units of 8 kB. - * - The size of Rx queues of available ports must not be - * smaller than 16 kB. - * - The size of at least one Tx queue (synch. or asynch.) - * of available ports must not be smaller than 16 kB - * when Jumbo Frames are used. - * - The RAM start and end addresses must not be changed - * for ports which are already initialized. - * Furthermore SkGeCheckQSize() defines the Start and End Addresses - * of all ports and stores them into the HWAC port structure. - * - * Returns: - * 0: Queue Size Configuration valid - * 1: Queue Size Configuration invalid - */ -static int SkGeCheckQSize( -SK_AC *pAC, /* adapter context */ -int Port) /* port index */ -{ - SK_GEPORT *pPrt; - int i; - int Rtv; - int Rtv2; - SK_U32 StartAddr; -#ifndef SK_SLIM - int UsedMem; /* total memory used (max. found ports) */ -#endif - - Rtv = 0; - -#ifndef SK_SLIM - - UsedMem = 0; - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - pPrt = &pAC->GIni.GP[i]; - - if ((pPrt->PRxQSize & QZ_UNITS) != 0 || - (pPrt->PXSQSize & QZ_UNITS) != 0 || - (pPrt->PXAQSize & QZ_UNITS) != 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); - return(1); - } - - if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); - return(1); - } - - /* - * the size of at least one Tx queue (synch. or asynch.) has to be > 0. - * if Jumbo Frames are used, this size has to be >= 16 kB. - */ - if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || - (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && - ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || - (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); - return(1); - } - - UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; - } - - if (UsedMem > pAC->GIni.GIRamSize) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); - return(1); - } -#endif /* !SK_SLIM */ - - /* Now start address calculation */ - StartAddr = pAC->GIni.GIRamOffs; - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - pPrt = &pAC->GIni.GP[i]; - - /* Calculate/Check values for the receive queue */ - Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, - &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); - Rtv |= Rtv2; - - /* Calculate/Check values for the synchronous Tx queue */ - Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr, - &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd); - Rtv |= Rtv2; - - /* Calculate/Check values for the asynchronous Tx queue */ - Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr, - &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd); - Rtv |= Rtv2; - - if (Rtv) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG); - return(1); - } - } - - return(0); -} /* SkGeCheckQSize */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkGeInitMacArb() - Initialize the MAC Arbiter - * - * Description: - * This function initializes the MAC Arbiter. - * It must not be called if there is still an - * initialized or active port. - * - * Returns: - * nothing - */ -static void SkGeInitMacArb( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - /* release local reset */ - SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); - - /* configure timeout values */ - SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53); - SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53); - SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53); - SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53); - - SK_OUT8(IoC, B3_MA_RCINI_RX1, 0); - SK_OUT8(IoC, B3_MA_RCINI_RX2, 0); - SK_OUT8(IoC, B3_MA_RCINI_TX1, 0); - SK_OUT8(IoC, B3_MA_RCINI_TX2, 0); - - /* recovery values are needed for XMAC II Rev. B2 only */ - /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */ - - /* - * There is no start or enable button to push, therefore - * the MAC arbiter is configured and enabled now. - */ -} /* SkGeInitMacArb */ - - -/****************************************************************************** - * - * SkGeInitPktArb() - Initialize the Packet Arbiter - * - * Description: - * This function initializes the Packet Arbiter. - * It must not be called if there is still an - * initialized or active port. - * - * Returns: - * nothing - */ -static void SkGeInitPktArb( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - /* release local reset */ - SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); - - /* configure timeout values */ - SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX); - SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX); - SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX); - SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX); - - /* - * enable timeout timers if jumbo frames not used - * NOTE: the packet arbiter timeout interrupt is needed for - * half duplex hangup workaround - */ - if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { - if (pAC->GIni.GIMacsFound == 1) { - SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); - } - else { - SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2); - } - } -} /* SkGeInitPktArb */ -#endif /* GENESIS */ - - -/****************************************************************************** - * - * SkGeInitMacFifo() - Initialize the MAC FIFOs - * - * Description: - * Initialize all MAC FIFOs of the specified port - * - * Returns: - * nothing - */ -static void SkGeInitMacFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U16 Word; -#ifdef VCPU - SK_U32 DWord; -#endif /* VCPU */ - /* - * For each FIFO: - * - release local reset - * - use default value for MAC FIFO size - * - setup defaults for the control register - * - enable the FIFO - */ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* Configure Rx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Configure Tx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Enable frame flushing if jumbo frames used */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* set Rx GMAC FIFO Flush Mask */ - SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); - - Word = (SK_U16)GMF_RX_CTRL_DEF; - - /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ - if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { - - Word &= ~GMF_RX_F_FL_ON; - } - - /* Configure Rx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); - - /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ - SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); - - /* Configure Tx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); - SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); - -#ifdef VCPU - SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); - SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); -#endif /* VCPU */ - - /* set Tx GMAC FIFO Almost Empty Threshold */ -/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ - } -#endif /* YUKON */ - -} /* SkGeInitMacFifo */ - -#ifdef SK_LNK_SYNC_CNT -/****************************************************************************** - * - * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting - * - * Description: - * This function starts the Link Sync Counter of the specified - * port and enables the generation of an Link Sync IRQ. - * The Link Sync Counter may be used to detect an active link, - * if autonegotiation is not used. - * - * Note: - * o To ensure receiving the Link Sync Event the LinkSyncCounter - * should be initialized BEFORE clearing the XMAC's reset! - * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this - * function. - * - * Returns: - * nothing - */ -void SkGeLoadLnkSyncCnt( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U32 CntVal) /* Counter value */ -{ - SK_U32 OrgIMsk; - SK_U32 NewIMsk; - SK_U32 ISrc; - SK_BOOL IrqPend; - - /* stop counter */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); - - /* - * ASIC problem: - * Each time starting the Link Sync Counter an IRQ is generated - * by the adapter. See problem report entry from 21.07.98 - * - * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ - * if no IRQ is already pending. - */ - IrqPend = SK_FALSE; - SK_IN32(IoC, B0_ISRC, &ISrc); - SK_IN32(IoC, B0_IMSK, &OrgIMsk); - if (Port == MAC_1) { - NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; - if ((ISrc & IS_LNK_SYNC_M1) != 0) { - IrqPend = SK_TRUE; - } - } - else { - NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2; - if ((ISrc & IS_LNK_SYNC_M2) != 0) { - IrqPend = SK_TRUE; - } - } - if (!IrqPend) { - SK_OUT32(IoC, B0_IMSK, NewIMsk); - } - - /* load counter */ - SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); - - /* start counter */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); - - if (!IrqPend) { - /* clear the unexpected IRQ, and restore the interrupt mask */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); - SK_OUT32(IoC, B0_IMSK, OrgIMsk); - } -} /* SkGeLoadLnkSyncCnt*/ -#endif /* SK_LNK_SYNC_CNT */ - -#if defined(SK_DIAG) || defined(SK_CFG_SYNC) -/****************************************************************************** - * - * SkGeCfgSync() - Configure synchronous bandwidth for this port. - * - * Description: - * This function may be used to configure synchronous bandwidth - * to the specified port. This may be done any time after - * initializing the port. The configuration values are NOT saved - * in the HWAC port structure and will be overwritten any - * time when stopping and starting the port. - * Any values for the synchronous configuration will be ignored - * if the size of the synchronous queue is zero! - * - * The default configuration for the synchronous service is - * TXA_ENA_FSYNC. This means if the size of - * the synchronous queue is unequal zero but no specific - * synchronous bandwidth is configured, the synchronous queue - * will always have the 'unlimited' transmit priority! - * - * This mode will be restored if the synchronous bandwidth is - * deallocated ('IntTime' = 0 and 'LimCount' = 0). - * - * Returns: - * 0: success - * 1: parameter configuration error - * 2: try to configure quality of service although no - * synchronous queue is configured - */ -int SkGeCfgSync( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ -SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ -int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */ -{ - int Rtv; - - Rtv = 0; - - /* check the parameters */ - if (LimCount > IntTime || - (LimCount == 0 && IntTime != 0) || - (LimCount != 0 && IntTime == 0)) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); - return(1); - } - - if (pAC->GIni.GP[Port].PXSQSize == 0) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); - return(2); - } - - /* calculate register values */ - IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; - LimCount = LimCount / 8; - - if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); - return(1); - } - - /* - * - Enable 'Force Sync' to ensure the synchronous queue - * has the priority while configuring the new values. - * - Also 'disable alloc' to ensure the settings complies - * to the SyncMode parameter. - * - Disable 'Rate Control' to configure the new values. - * - write IntTime and LimCount - * - start 'Rate Control' and disable 'Force Sync' - * if Interval Timer or Limit Counter not zero. - */ - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - - SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); - SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); - - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); - - if (IntTime != 0 || LimCount != 0) { - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); - } - - return(0); -} /* SkGeCfgSync */ -#endif /* SK_DIAG || SK_CFG_SYNC*/ - - -/****************************************************************************** - * - * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue - * - * Desccription: - * If the queue is used, enable and initialize it. - * Make sure the queue is still reset, if it is not used. - * - * Returns: - * nothing - */ -static void DoInitRamQueue( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int QuIoOffs, /* Queue IO Address Offset */ -SK_U32 QuStartAddr, /* Queue Start Address */ -SK_U32 QuEndAddr, /* Queue End Address */ -int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */ -{ - SK_U32 RxUpThresVal; - SK_U32 RxLoThresVal; - - if (QuStartAddr != QuEndAddr) { - /* calculate thresholds, assume we have a big Rx queue */ - RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8; - RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8; - - /* build HW address format */ - QuStartAddr = QuStartAddr / 8; - QuEndAddr = QuEndAddr / 8; - - /* release local reset */ - SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR); - - /* configure addresses */ - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr); - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr); - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr); - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr); - - switch (QuType) { - case SK_RX_SRAM_Q: - /* configure threshold for small Rx Queue */ - RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8; - - /* continue with SK_RX_BRAM_Q */ - case SK_RX_BRAM_Q: - /* write threshold for Rx Queue */ - - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); - SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); - - /* the high priority threshold not used */ - break; - case SK_TX_RAM_Q: - /* - * Do NOT use Store & Forward under normal operation due to - * performance optimization (GENESIS only). - * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB) - * or YUKON is used ((GMAC Tx FIFO is only 1 kB) - * we NEED Store & Forward of the RAM buffer. - */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || - pAC->GIni.GIYukon) { - /* enable Store & Forward Mode for the Tx Side */ - SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); - } - break; - } - - /* set queue operational */ - SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD); - } - else { - /* ensure the queue is still disabled */ - SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET); - } -} /* DoInitRamQueue */ - - -/****************************************************************************** - * - * SkGeInitRamBufs() - Initialize the RAM Buffer Queues - * - * Description: - * Initialize all RAM Buffer Queues of the specified port - * - * Returns: - * nothing - */ -static void SkGeInitRamBufs( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - int RxQType; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { - RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ - } - else { - RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ - } - - DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, - pPrt->PRxQRamEnd, RxQType); - - DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, - pPrt->PXsQRamEnd, SK_TX_RAM_Q); - - DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, - pPrt->PXaQRamEnd, SK_TX_RAM_Q); - -} /* SkGeInitRamBufs */ - - -/****************************************************************************** - * - * SkGeInitRamIface() - Initialize the RAM Interface - * - * Description: - * This function initializes the Adapters RAM Interface. - * - * Note: - * This function is used in the diagnostics. - * - * Returns: - * nothing - */ -static void SkGeInitRamIface( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - /* release local reset */ - SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR); - - /* configure timeout values */ - SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); - -} /* SkGeInitRamIface */ - - -/****************************************************************************** - * - * SkGeInitBmu() - Initialize the BMU state machines - * - * Description: - * Initialize all BMU state machines of the specified port - * - * Returns: - * nothing - */ -static void SkGeInitBmu( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U32 RxWm; - SK_U32 TxWm; - - pPrt = &pAC->GIni.GP[Port]; - - RxWm = SK_BMU_RX_WM; - TxWm = SK_BMU_TX_WM; - - if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { - /* for better performance */ - RxWm /= 2; - TxWm /= 2; - } - - /* Rx Queue: Release all local resets and set the watermark */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); - - /* - * Tx Queue: Release all local resets if the queue is used ! - * set watermark - */ - if (pPrt->PXSQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); - } - - if (pPrt->PXAQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); - } - /* - * Do NOT enable the descriptor poll timers here, because - * the descriptor addresses are not specified yet. - */ -} /* SkGeInitBmu */ - - -/****************************************************************************** - * - * TestStopBit() - Test the stop bit of the queue - * - * Description: - * Stopping a queue is not as simple as it seems to be. - * If descriptor polling is enabled, it may happen - * that RX/TX stop is done and SV idle is NOT set. - * In this case we have to issue another stop command. - * - * Returns: - * The queues control status register - */ -static SK_U32 TestStopBit( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int QuIoOffs) /* Queue IO Address Offset */ -{ - SK_U32 QuCsr; /* CSR contents */ - - SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); - - if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { - /* Stop Descriptor overridden by start command */ - SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); - - SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); - } - - return(QuCsr); -} /* TestStopBit */ - - -/****************************************************************************** - * - * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'. - * - * Description: - * After calling this function the descriptor rings and Rx and Tx - * queues of this port may be reconfigured. - * - * It is possible to stop the receive and transmit path separate or - * both together. - * - * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC. - * The receive queue is still active and - * the pending Rx frames may be still transferred - * into the RxD. - * SK_STOP_RX Stop the receive path. The tansmit path - * has to be stopped once before. - * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX - * - * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. - * SK_HARD_RST Resets the MAC and the PHY. - * - * Example: - * 1) A Link Down event was signaled for a port. Therefore the activity - * of this port should be stopped and a hardware reset should be issued - * to enable the workaround of XMAC Errata #2. But the received frames - * should not be discarded. - * ... - * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST); - * (transfer all pending Rx frames) - * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST); - * ... - * - * 2) An event was issued which request the driver to switch - * the 'virtual active' link to an other already active port - * as soon as possible. The frames in the receive queue of this - * port may be lost. But the PHY must not be reset during this - * event. - * ... - * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST); - * ... - * - * Extended Description: - * If SK_STOP_TX is set, - * o disable the MAC's receive and transmitter to prevent - * from sending incomplete frames - * o stop the port's transmit queues before terminating the - * BMUs to prevent from performing incomplete PCI cycles - * on the PCI bus - * - The network Rx and Tx activity and PCI Tx transfer is - * disabled now. - * o reset the MAC depending on the RstMode - * o Stop Interval Timer and Limit Counter of Tx Arbiter, - * also disable Force Sync bit and Enable Alloc bit. - * o perform a local reset of the port's Tx path - * - reset the PCI FIFO of the async Tx queue - * - reset the PCI FIFO of the sync Tx queue - * - reset the RAM Buffer async Tx queue - * - reset the RAM Buffer sync Tx queue - * - reset the MAC Tx FIFO - * o switch Link and Tx LED off, stop the LED counters - * - * If SK_STOP_RX is set, - * o stop the port's receive queue - * - The path data transfer activity is fully stopped now. - * o perform a local reset of the port's Rx path - * - reset the PCI FIFO of the Rx queue - * - reset the RAM Buffer receive queue - * - reset the MAC Rx FIFO - * o switch Rx LED off, stop the LED counter - * - * If all ports are stopped, - * o reset the RAM Interface. - * - * Notes: - * o This function may be called during the driver states RESET_PORT and - * SWITCH_PORT. - */ -void SkGeStopPort( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -int Port, /* port to stop (MAC_1 + n) */ -int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ -int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ -{ -#ifndef SK_DIAG - SK_EVPARA Para; -#endif /* !SK_DIAG */ - SK_GEPORT *pPrt; - SK_U32 DWord; - SK_U32 XsCsr; - SK_U32 XaCsr; - SK_U64 ToutStart; - int i; - int ToutCnt; - - pPrt = &pAC->GIni.GP[Port]; - - if ((Dir & SK_STOP_TX) != 0) { - /* disable receiver and transmitter */ - SkMacRxTxDisable(pAC, IoC, Port); - - /* stop both transmit queues */ - /* - * If the BMU is in the reset state CSR_STOP will terminate - * immediately. - */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP); - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP); - - ToutStart = SkOsGetTime(pAC); - ToutCnt = 0; - do { - /* - * Clear packet arbiter timeout to make sure - * this loop will terminate. - */ - SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? - PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); - - /* - * If the transfer stucks at the MAC the STOP command will not - * terminate if we don't flush the XMAC's transmit FIFO ! - */ - SkMacFlushTxFifo(pAC, IoC, Port); - - XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); - XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); - - if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) { - /* - * Timeout of 1/18 second reached. - * This needs to be checked at 1/18 sec only. - */ - ToutCnt++; - if (ToutCnt > 1) { - /* Might be a problem when the driver event handler - * calls StopPort again. XXX. - */ - - /* Fatal Error, Loop aborted */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, - SKERR_HWI_E018MSG); -#ifndef SK_DIAG - Para.Para64 = Port; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); -#endif /* !SK_DIAG */ - return; - } - /* - * Cache incoherency workaround: Assume a start command - * has been lost while sending the frame. - */ - ToutStart = SkOsGetTime(pAC); - - if ((XsCsr & CSR_STOP) != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); - } - if ((XaCsr & CSR_STOP) != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); - } - } - - /* - * Because of the ASIC problem report entry from 21.08.1998 it is - * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. - */ - } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || - (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); - - /* Reset the MAC depending on the RstMode */ - if (RstMode == SK_SOFT_RST) { - SkMacSoftRst(pAC, IoC, Port); - } - else { - SkMacHardRst(pAC, IoC, Port); - } - - /* Disable Force Sync bit and Enable Alloc bit */ - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), - TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - - /* Stop Interval Timer and Limit Counter of Tx Arbiter */ - SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); - SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); - - /* Perform a local reset of the port's Tx path */ - - /* Reset the PCI FIFO of the async Tx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); - /* Reset the PCI FIFO of the sync Tx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); - /* Reset the RAM Buffer async Tx queue */ - SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); - /* Reset the RAM Buffer sync Tx queue */ - SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); - - /* Reset Tx MAC FIFO */ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* Note: MFF_RST_SET does NOT reset the XMAC ! */ - SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET); - - /* switch Link and Tx LED off, stop the LED counters */ - /* Link LED is switched off by the RLMT and the Diag itself */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* Reset TX MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); - } -#endif /* YUKON */ - } - - if ((Dir & SK_STOP_RX) != 0) { - /* - * The RX Stop Command will not terminate if no buffers - * are queued in the RxD ring. But it will always reach - * the Idle state. Therefore we can use this feature to - * stop the transfer of received packets. - */ - /* stop the port's receive queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); - - i = 100; - do { - /* - * Clear packet arbiter timeout to make sure - * this loop will terminate - */ - SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? - PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); - - DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); - - /* timeout if i==0 (bug fix for #10748) */ - if (--i == 0) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, - SKERR_HWI_E024MSG); - break; - } - /* - * because of the ASIC problem report entry from 21.08.98 - * it is required to wait until CSR_STOP is reset and - * CSR_SV_IDLE is set. - */ - } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); - - /* The path data transfer activity is fully stopped now */ - - /* Perform a local reset of the port's Rx path */ - - /* Reset the PCI FIFO of the Rx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); - /* Reset the RAM Buffer receive queue */ - SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); - - /* Reset Rx MAC FIFO */ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); - - /* switch Rx LED off, stop the LED counter */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* Reset Rx MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); - } -#endif /* YUKON */ - } -} /* SkGeStopPort */ - - -/****************************************************************************** - * - * SkGeInit0() - Level 0 Initialization - * - * Description: - * - Initialize the BMU address offsets - * - * Returns: - * nothing - */ -static void SkGeInit0( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - int i; - SK_GEPORT *pPrt; - - for (i = 0; i < SK_MAX_MACS; i++) { - pPrt = &pAC->GIni.GP[i]; - - pPrt->PState = SK_PRT_RESET; - pPrt->PRxQOff = QOffTab[i].RxQOff; - pPrt->PXsQOff = QOffTab[i].XsQOff; - pPrt->PXaQOff = QOffTab[i].XaQOff; - pPrt->PCheckPar = SK_FALSE; - pPrt->PIsave = 0; - pPrt->PPrevShorts = 0; - pPrt->PLinkResCt = 0; - pPrt->PAutoNegTOCt = 0; - pPrt->PPrevRx = 0; - pPrt->PPrevFcs = 0; - pPrt->PRxLim = SK_DEF_RX_WA_LIM; - pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; - pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS; - pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS; - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN; - pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE; - pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; - pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL | - SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL); - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM; - pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; - pPrt->PMSCap = 0; - pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO; - pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET; - pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; - pPrt->PAutoNegFail = SK_FALSE; - pPrt->PHWLinkUp = SK_FALSE; - pPrt->PLinkBroken = SK_TRUE; /* See WA code */ - pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; - pPrt->PMacColThres = TX_COL_DEF; - pPrt->PMacJamLen = TX_JAM_LEN_DEF; - pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; - pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; - pPrt->PMacIpgData = IPG_DATA_DEF; - pPrt->PMacLimit4 = SK_FALSE; - } - - pAC->GIni.GIPortUsage = SK_RED_LINK; - pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value; - pAC->GIni.GIValIrqMask = IS_ALL_MSK; - -} /* SkGeInit0*/ - - -/****************************************************************************** - * - * SkGeInit1() - Level 1 Initialization - * - * Description: - * o Do a software reset. - * o Clear all reset bits. - * o Verify that the detected hardware is present. - * Return an error if not. - * o Get the hardware configuration - * + Read the number of MACs/Ports. - * + Read the RAM size. - * + Read the PCI Revision Id. - * + Find out the adapters host clock speed - * + Read and check the PHY type - * - * Returns: - * 0: success - * 5: Unexpected PHY type detected - * 6: HW self test failed - */ -static int SkGeInit1( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - SK_U8 Byte; - SK_U16 Word; - SK_U16 CtrlStat; - SK_U32 DWord; - int RetVal; - int i; - - RetVal = 0; - - /* save CLK_RUN bits (YUKON-Lite) */ - SK_IN16(IoC, B0_CTST, &CtrlStat); - - /* do the SW-reset */ - SK_OUT8(IoC, B0_CTST, CS_RST_SET); - - /* release the SW-reset */ - SK_OUT8(IoC, B0_CTST, CS_RST_CLR); - - /* reset all error bits in the PCI STATUS register */ - /* - * Note: PCI Cfg cycles cannot be used, because they are not - * available on some platforms after 'boot time'. - */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - /* release Master Reset */ - SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); - -#ifdef CLK_RUN - CtrlStat |= CS_CLK_RUN_ENA; -#endif /* CLK_RUN */ - - /* restore CLK_RUN bits */ - SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & - (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); - - /* read Chip Identification Number */ - SK_IN8(IoC, B2_CHIP_ID, &Byte); - pAC->GIni.GIChipId = Byte; - - /* read number of MACs */ - SK_IN8(IoC, B2_MAC_CFG, &Byte); - pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; - - /* get Chip Revision Number */ - pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); - - /* get diff. PCI parameters */ - SK_IN16(IoC, B0_CTST, &CtrlStat); - - /* read the adapters RAM size */ - SK_IN8(IoC, B2_E_0, &Byte); - - pAC->GIni.GIGenesis = SK_FALSE; - pAC->GIni.GIYukon = SK_FALSE; - pAC->GIni.GIYukonLite = SK_FALSE; - -#ifdef GENESIS - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - - pAC->GIni.GIGenesis = SK_TRUE; - - if (Byte == (SK_U8)3) { - /* special case: 4 x 64k x 36, offset = 0x80000 */ - pAC->GIni.GIRamSize = 1024; - pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; - } - else { - pAC->GIni.GIRamSize = (int)Byte * 512; - pAC->GIni.GIRamOffs = 0; - } - /* all GE adapters work with 53.125 MHz host clock */ - pAC->GIni.GIHstClkFact = SK_FACT_53; - - /* set Descr. Poll Timer Init Value to 250 ms */ - pAC->GIni.GIPollTimerVal = - SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { - - pAC->GIni.GIYukon = SK_TRUE; - - pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4; - - pAC->GIni.GIRamOffs = 0; - - /* WA for chip Rev. A */ - pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON && - pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; - - /* get PM Capabilities of PCI config space */ - SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); - - /* check if VAUX is available */ - if (((CtrlStat & CS_VAUX_AVAIL) != 0) && - /* check also if PME from D3cold is set */ - ((Word & PCI_PME_D3C_SUP) != 0)) { - /* set entry in GE init struct */ - pAC->GIni.GIVauxAvail = SK_TRUE; - } - - if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { - /* this is Rev. A1 */ - pAC->GIni.GIYukonLite = SK_TRUE; - } - else { - /* save Flash-Address Register */ - SK_IN32(IoC, B2_FAR, &DWord); - - /* test Flash-Address Register */ - SK_OUT8(IoC, B2_FAR + 3, 0xff); - SK_IN8(IoC, B2_FAR + 3, &Byte); - - if (Byte != 0) { - /* this is Rev. A0 */ - pAC->GIni.GIYukonLite = SK_TRUE; - - /* restore Flash-Address Register */ - SK_OUT32(IoC, B2_FAR, DWord); - } - } - - /* switch power to VCC (WA for VAUX problem) */ - SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | - PC_VAUX_OFF | PC_VCC_ON)); - - /* read the Interrupt source */ - SK_IN32(IoC, B0_ISRC, &DWord); - - if ((DWord & IS_HW_ERR) != 0) { - /* read the HW Error Interrupt source */ - SK_IN32(IoC, B0_HWE_ISRC, &DWord); - - if ((DWord & IS_IRQ_SENSOR) != 0) { - /* disable HW Error IRQ */ - pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; - } - } - - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - /* set GMAC Link Control reset */ - SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); - - /* clear GMAC Link Control reset */ - SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); - } - /* all YU chips work with 78.125 MHz host clock */ - pAC->GIni.GIHstClkFact = SK_FACT_78; - - pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ - } -#endif /* YUKON */ - - /* check if 64-bit PCI Slot is present */ - pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); - - /* check if 66 MHz PCI Clock is active */ - pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); - - /* read PCI HW Revision Id. */ - SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); - pAC->GIni.GIPciHwRev = Byte; - - /* read the PMD type */ - SK_IN8(IoC, B2_PMD_TYP, &Byte); - pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); - - /* read the PHY type */ - SK_IN8(IoC, B2_E_1, &Byte); - - Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - switch (Byte) { - case SK_PHY_XMAC: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; - break; - case SK_PHY_BCOM: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; - pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | - SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; - break; - case SK_PHY_NAT: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; - break; -#endif /* OTHER_PHY */ - default: - /* ERROR: unexpected PHY type detected */ - RetVal = 5; - break; - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { - /* if this field is not initialized */ - Byte = (SK_U8)SK_PHY_MARV_COPPER; - - pAC->GIni.GICopperType = SK_TRUE; - } - - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; - - if (pAC->GIni.GICopperType) { - - pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | - SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | - SK_LSPEED_CAP_1000MBPS); - - pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; - - pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | - SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); - } - else { - Byte = (SK_U8)SK_PHY_MARV_FIBER; - } - } -#endif /* YUKON */ - - pAC->GIni.GP[i].PhyType = (int)Byte; - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("PHY type: %d PHY addr: %04x\n", Byte, - pAC->GIni.GP[i].PhyAddr)); - } - - /* get MAC Type & set function pointers dependent on */ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - pAC->GIni.GIMacType = SK_MAC_XMAC; - - pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; - pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; - pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; - pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - pAC->GIni.GIMacType = SK_MAC_GMAC; - - pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; - pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; - pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; - pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; - -#ifdef SPECIAL_HANDLING - if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { - /* check HW self test result */ - SK_IN8(IoC, B2_E_3, &Byte); - if (Byte & B2_E3_RES_MASK) { - RetVal = 6; - } - } -#endif - } -#endif /* YUKON */ - - return(RetVal); -} /* SkGeInit1 */ - - -/****************************************************************************** - * - * SkGeInit2() - Level 2 Initialization - * - * Description: - * - start the Blink Source Counter - * - start the Descriptor Poll Timer - * - configure the MAC-Arbiter - * - configure the Packet-Arbiter - * - enable the Tx Arbiters - * - enable the RAM Interface Arbiter - * - * Returns: - * nothing - */ -static void SkGeInit2( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ -#ifdef GENESIS - SK_U32 DWord; -#endif /* GENESIS */ - int i; - - /* start the Descriptor Poll Timer */ - if (pAC->GIni.GIPollTimerVal != 0) { - if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) { - pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); - } - SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); - SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); - } - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* start the Blink Source Counter */ - DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; - - SK_OUT32(IoC, B2_BSC_INI, DWord); - SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); - - /* - * Configure the MAC Arbiter and the Packet Arbiter. - * They will be started once and never be stopped. - */ - SkGeInitMacArb(pAC, IoC); - - SkGeInitPktArb(pAC, IoC); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* start Time Stamp Timer */ - SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); - } -#endif /* YUKON */ - - /* enable the Tx Arbiters */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB); - } - - /* enable the RAM Interface Arbiter */ - SkGeInitRamIface(pAC, IoC); - -} /* SkGeInit2 */ - -/****************************************************************************** - * - * SkGeInit() - Initialize the GE Adapter with the specified level. - * - * Description: - * Level 0: Initialize the Module structures. - * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has - * to be set before calling this level. - * - * o Do a software reset. - * o Clear all reset bits. - * o Verify that the detected hardware is present. - * Return an error if not. - * o Get the hardware configuration - * + Set GIMacsFound with the number of MACs. - * + Store the RAM size in GIRamSize. - * + Save the PCI Revision ID in GIPciHwRev. - * o return an error - * if Number of MACs > SK_MAX_MACS - * - * After returning from Level 0 the adapter - * may be accessed with IO operations. - * - * Level 2: start the Blink Source Counter - * - * Returns: - * 0: success - * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) - * 2: Adapter not present or not accessible - * 3: Illegal initialization level - * 4: Initialization Level 1 Call missing - * 5: Unexpected PHY type detected - * 6: HW self test failed - */ -int SkGeInit( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Level) /* initialization level */ -{ - int RetVal; /* return value */ - SK_U32 DWord; - - RetVal = 0; - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("SkGeInit(Level %d)\n", Level)); - - switch (Level) { - case SK_INIT_DATA: - /* Initialization Level 0 */ - SkGeInit0(pAC, IoC); - pAC->GIni.GILevel = SK_INIT_DATA; - break; - - case SK_INIT_IO: - /* Initialization Level 1 */ - RetVal = SkGeInit1(pAC, IoC); - if (RetVal != 0) { - break; - } - - /* check if the adapter seems to be accessible */ - SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); - SK_IN32(IoC, B2_IRQM_INI, &DWord); - SK_OUT32(IoC, B2_IRQM_INI, 0L); - - if (DWord != SK_TEST_VAL) { - RetVal = 2; - break; - } - - /* check if the number of GIMacsFound matches SK_MAX_MACS */ - if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { - RetVal = 1; - break; - } - - /* Level 1 successfully passed */ - pAC->GIni.GILevel = SK_INIT_IO; - break; - - case SK_INIT_RUN: - /* Initialization Level 2 */ - if (pAC->GIni.GILevel != SK_INIT_IO) { -#ifndef SK_DIAG - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG); -#endif /* !SK_DIAG */ - RetVal = 4; - break; - } - SkGeInit2(pAC, IoC); - - /* Level 2 successfully passed */ - pAC->GIni.GILevel = SK_INIT_RUN; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); - RetVal = 3; - break; - } - - return(RetVal); -} /* SkGeInit */ - - -/****************************************************************************** - * - * SkGeDeInit() - Deinitialize the adapter - * - * Description: - * All ports of the adapter will be stopped if not already done. - * Do a software reset and switch off all LEDs. - * - * Returns: - * nothing - */ -void SkGeDeInit( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - int i; - SK_U16 Word; - -#if (!defined(SK_SLIM) && !defined(VCPU)) - /* ensure I2C is ready */ - SkI2cWaitIrq(pAC, IoC); -#endif - - /* stop all current transfer activity */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - if (pAC->GIni.GP[i].PState != SK_PRT_STOP && - pAC->GIni.GP[i].PState != SK_PRT_RESET) { - - SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); - } - } - - /* Reset all bits in the PCI STATUS register */ - /* - * Note: PCI Cfg cycles cannot be used, because they are not - * available on some platforms after 'boot time'. - */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - /* do the reset, all LEDs are switched off now */ - SK_OUT8(IoC, B0_CTST, CS_RST_SET); - - pAC->GIni.GILevel = SK_INIT_DATA; -} /* SkGeDeInit */ - - -/****************************************************************************** - * - * SkGeInitPort() Initialize the specified port. - * - * Description: - * PRxQSize, PXSQSize, and PXAQSize has to be - * configured for the specified port before calling this function. - * The descriptor rings has to be initialized too. - * - * o (Re)configure queues of the specified port. - * o configure the MAC of the specified port. - * o put ASIC and MAC(s) in operational mode. - * o initialize Rx/Tx and Sync LED - * o initialize RAM Buffers and MAC FIFOs - * - * The port is ready to connect when returning. - * - * Note: - * The MAC's Rx and Tx state machine is still disabled when returning. - * - * Returns: - * 0: success - * 1: Queue size initialization error. The configured values - * for PRxQSize, PXSQSize, or PXAQSize are invalid for one - * or more queues. The specified port was NOT initialized. - * An error log entry was generated. - * 2: The port has to be stopped before it can be initialized again. - */ -int SkGeInitPort( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port to configure */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (SkGeCheckQSize(pAC, Port) != 0) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); - return(1); - } - - if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); - return(2); - } - - /* configuration ok, initialize the Port now */ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* initialize Rx, Tx and Link LED */ - /* - * If 1000BT Phy needs LED initialization than swap - * LED and XMAC initialization order - */ - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); - SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); - /* The Link LED is initialized by RLMT or Diagnostics itself */ - - SkXmInitMac(pAC, IoC, Port); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmInitMac(pAC, IoC, Port); - } -#endif /* YUKON */ - - /* do NOT initialize the Link Sync Counter */ - - SkGeInitMacFifo(pAC, IoC, Port); - - SkGeInitRamBufs(pAC, IoC, Port); - - if (pPrt->PXSQSize != 0) { - /* enable Force Sync bit if synchronous queue available */ - SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); - } - - SkGeInitBmu(pAC, IoC, Port); - - /* mark port as initialized */ - pPrt->PState = SK_PRT_INIT; - - return(0); -} /* SkGeInitPort */ diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c deleted file mode 100644 index 0a6f67a7a395..000000000000 --- a/drivers/net/sk98lin/skgemib.c +++ /dev/null @@ -1,1075 +0,0 @@ -/***************************************************************************** - * - * Name: skgemib.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.11 $ - * Date: $Date: 2003/09/15 13:38:12 $ - * Purpose: Private Network Management Interface Management Database - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * PRIVATE OID handler function prototypes - */ -PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int* pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); - -#ifdef SK_POWER_MGMT -PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -#endif /* SK_POWER_MGMT */ - -#ifdef SK_DIAG_SUPPORT -PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -#endif /* SK_DIAG_SUPPORT */ - - -/* defines *******************************************************************/ -#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) - - -/* global variables **********************************************************/ - -/* - * Table to correlate OID with handler function and index to - * hardware register stored in StatAddress if applicable. - */ -PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { - {OID_GEN_XMIT_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX}, - {OID_GEN_RCV_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX}, - {OID_GEN_XMIT_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_NO_BUFFER, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_DIRECTED_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST}, - {OID_GEN_DIRECTED_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST}, - {OID_GEN_RCV_CRC_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS}, - {OID_GEN_TRANSMIT_QUEUE_LENGTH, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_802_3_PERMANENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_CURRENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_RCV_ERROR_ALIGNMENT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING}, - {OID_802_3_XMIT_ONE_COLLISION, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL}, - {OID_802_3_XMIT_MORE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL}, - {OID_802_3_XMIT_DEFERRED, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL}, - {OID_802_3_XMIT_MAX_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL}, - {OID_802_3_RCV_OVERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW}, - {OID_802_3_XMIT_UNDERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN}, - {OID_802_3_XMIT_TIMES_CRS_LOST, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER}, - {OID_802_3_XMIT_LATE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL}, -#ifdef SK_POWER_MGMT - {OID_PNP_CAPABILITIES, - 0, - 0, - 0, - SK_PNMI_RO, PowerManagement, 0}, - {OID_PNP_SET_POWER, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_QUERY_POWER, - 0, - 0, - 0, - SK_PNMI_RO, PowerManagement, 0}, - {OID_PNP_ADD_WAKE_UP_PATTERN, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_REMOVE_WAKE_UP_PATTERN, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_ENABLE_WAKE_UP, - 0, - 0, - 0, - SK_PNMI_RW, PowerManagement, 0}, -#endif /* SK_POWER_MGMT */ -#ifdef SK_DIAG_SUPPORT - {OID_SKGE_DIAG_MODE, - 0, - 0, - 0, - SK_PNMI_RW, DiagActions, 0}, -#endif /* SK_DIAG_SUPPORT */ - {OID_SKGE_MDB_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(MgmtDBVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SUPPORTED_LIST, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_SKGE_ALL_DATA, - 0, - 0, - 0, - SK_PNMI_RW, OidStruct, 0}, - {OID_SKGE_VPD_FREE_BYTES, - 1, - 0, - SK_PNMI_MAI_OFF(VpdFreeBytes), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_LIST, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesList), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesNumber), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_KEY, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_VALUE, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACCESS, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACTION, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction), - SK_PNMI_RW, Vpd, 0}, - {OID_SKGE_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(PortNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DEVICE_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(DeviceType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(DriverDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(DriverVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_RELDATE, - 1, - 0, - SK_PNMI_MAI_OFF(DriverReleaseDate), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_FILENAME, - 1, - 0, - SK_PNMI_MAI_OFF(DriverFileName), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(HwDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(HwVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHIPSET, - 1, - 0, - SK_PNMI_MAI_OFF(Chipset), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHIPID, - 1, - 0, - SK_PNMI_MAI_OFF(ChipId), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RAMSIZE, - 1, - 0, - SK_PNMI_MAI_OFF(RamSize), - SK_PNMI_RO, General, 0}, - {OID_SKGE_VAUXAVAIL, - 1, - 0, - SK_PNMI_MAI_OFF(VauxAvail), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ACTION, - 1, - 0, - SK_PNMI_MAI_OFF(Action), - SK_PNMI_RW, Perform, 0}, - {OID_SKGE_RESULT, - 1, - 0, - SK_PNMI_MAI_OFF(TestResult), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(BusType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_SPEED, - 1, - 0, - SK_PNMI_MAI_OFF(BusSpeed), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_WIDTH, - 1, - 0, - SK_PNMI_MAI_OFF(BusWidth), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_LEN, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueLen), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_MAX, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueMax), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_RETRY, - 1, - 0, - SK_PNMI_MAI_OFF(TxRetryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_USED_DESCR_NO, - 1, - 0, - SK_PNMI_MAI_OFF(TxUsedDescrNo), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_DELIVERED_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_OCTETS_DELIV_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxOctetsDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_IN_ERRORS_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(InErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_OUT_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(OutErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ERR_RECOVERY_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(ErrRecoveryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SYSUPTIME, - 1, - 0, - SK_PNMI_MAI_OFF(SysUpTime), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(SensorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_INDEX, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_DESCR, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_TYPE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_VALUE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_STATUS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_CHKSM_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(ChecksumNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHKSM_RX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_ERR_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_STAT_TX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX}, - {OID_SKGE_STAT_TX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET}, - {OID_SKGE_STAT_TX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST}, - {OID_SKGE_STAT_TX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST}, - {OID_SKGE_STAT_TX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST}, - {OID_SKGE_STAT_TX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES}, - {OID_SKGE_STAT_TX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST}, - {OID_SKGE_STAT_TX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC}, - {OID_SKGE_STAT_TX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC}, - {OID_SKGE_STAT_TX_SINGLE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL}, - {OID_SKGE_STAT_TX_MULTI_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL}, - {OID_SKGE_STAT_TX_EXCESS_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL}, - {OID_SKGE_STAT_TX_LATE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL}, - {OID_SKGE_STAT_TX_DEFFERAL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL}, - {OID_SKGE_STAT_TX_EXCESS_DEF, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF}, - {OID_SKGE_STAT_TX_UNDERRUN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN}, - {OID_SKGE_STAT_TX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER}, -/* {OID_SKGE_STAT_TX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_TX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64}, - {OID_SKGE_STAT_TX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127}, - {OID_SKGE_STAT_TX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255}, - {OID_SKGE_STAT_TX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511}, - {OID_SKGE_STAT_TX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023}, - {OID_SKGE_STAT_TX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX}, - {OID_SKGE_STAT_TX_SYNC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC}, - {OID_SKGE_STAT_TX_SYNC_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET}, - {OID_SKGE_STAT_RX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX}, - {OID_SKGE_STAT_RX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET}, - {OID_SKGE_STAT_RX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST}, - {OID_SKGE_STAT_RX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST}, - {OID_SKGE_STAT_RX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST}, - {OID_SKGE_STAT_RX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES}, - {OID_SKGE_STAT_RX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC}, - {OID_SKGE_STAT_RX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC}, - {OID_SKGE_STAT_RX_PFLOWC_ERR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR}, - {OID_SKGE_STAT_RX_FLOWC_UNKWN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN}, - {OID_SKGE_STAT_RX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST}, - {OID_SKGE_STAT_RX_MISSED, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED}, - {OID_SKGE_STAT_RX_FRAMING, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING}, - {OID_SKGE_STAT_RX_OVERFLOW, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW}, - {OID_SKGE_STAT_RX_JABBER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER}, - {OID_SKGE_STAT_RX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER}, - {OID_SKGE_STAT_RX_IR_LENGTH, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH}, - {OID_SKGE_STAT_RX_SYMBOL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL}, - {OID_SKGE_STAT_RX_SHORTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS}, - {OID_SKGE_STAT_RX_RUNT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT}, - {OID_SKGE_STAT_RX_CEXT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT}, - {OID_SKGE_STAT_RX_TOO_LONG, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG}, - {OID_SKGE_STAT_RX_FCS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS}, -/* {OID_SKGE_STAT_RX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_RX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64}, - {OID_SKGE_STAT_RX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127}, - {OID_SKGE_STAT_RX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255}, - {OID_SKGE_STAT_RX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511}, - {OID_SKGE_STAT_RX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023}, - {OID_SKGE_STAT_RX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX}, - {OID_SKGE_PHYS_CUR_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr), - SK_PNMI_RW, Addr, 0}, - {OID_SKGE_PHYS_FAC_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr), - SK_PNMI_RO, Addr, 0}, - {OID_SKGE_PMD, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_CONNECTOR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_TYPE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_SPEED_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_SPEED_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_SPEED_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_TRAP, - 1, - 0, - SK_PNMI_MAI_OFF(Trap), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TRAP_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(TrapNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MODE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMode), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortNumber), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_ACTIVE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortActive), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_PREFERRED, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortPreferred), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeCts), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_TIME, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeTime), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_ESTIM, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeEstimate), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_THRES, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeThreshold), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_INDEX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_SP_REQ_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_SP_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_MONITOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMonitorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MONITOR_INDEX, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADDR, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ERRS, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_TIMESTAMP, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADMIN, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), - SK_PNMI_RW, Monitor, 0}, - {OID_SKGE_MTU, - 1, - 0, - SK_PNMI_MAI_OFF(MtuSize), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_VCT_GET, - 0, - 0, - 0, - SK_PNMI_RO, Vct, 0}, - {OID_SKGE_VCT_SET, - 0, - 0, - 0, - SK_PNMI_WO, Vct, 0}, - {OID_SKGE_VCT_STATUS, - 0, - 0, - 0, - SK_PNMI_RO, Vct, 0}, - {OID_SKGE_BOARDLEVEL, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, -}; - diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c deleted file mode 100644 index b36dd9ac6b29..000000000000 --- a/drivers/net/sk98lin/skgepnmi.c +++ /dev/null @@ -1,8210 +0,0 @@ -/***************************************************************************** - * - * Name: skgepnmi.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.111 $ - * Date: $Date: 2003/09/15 13:35:35 $ - * Purpose: Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - - -#ifndef _lint -static const char SysKonnectFileId[] = - "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell."; -#endif /* !_lint */ - -#include "h/skdrv1st.h" -#include "h/sktypes.h" -#include "h/xmac_ii.h" -#include "h/skdebug.h" -#include "h/skqueue.h" -#include "h/skgepnmi.h" -#include "h/skgesirq.h" -#include "h/skcsum.h" -#include "h/skvpd.h" -#include "h/skgehw.h" -#include "h/skgeinit.h" -#include "h/skdrv2nd.h" -#include "h/skgepnm2.h" -#ifdef SK_POWER_MGMT -#include "h/skgepmgt.h" -#endif -/* defines *******************************************************************/ - -#ifndef DEBUG -#define PNMI_STATIC static -#else /* DEBUG */ -#define PNMI_STATIC -#endif /* DEBUG */ - -/* - * Public Function prototypes - */ -int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); -int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); -int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, - unsigned int * pLen, SK_U32 NetIndex); - - -/* - * Private Function prototypes - */ - -PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int - PhysPortIndex); -PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int - PhysPortIndex); -PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); -PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); -PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, - unsigned int PhysPortIndex, unsigned int StatIndex); -PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, - unsigned int StatIndex, SK_U32 NetIndex); -PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); -PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, - unsigned int *pEntries); -PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, - unsigned int KeyArrLen, unsigned int *pKeyNo); -PNMI_STATIC int LookupId(SK_U32 Id); -PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, - unsigned int LastMac); -PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); -PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, - unsigned int PortIndex); -PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, - unsigned int SensorIndex); -PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); -PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); -PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); -PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, - unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); - -/* - * Table to correlate OID with handler function and index to - * hardware register stored in StatAddress if applicable. - */ -#include "skgemib.c" - -/* global variables **********************************************************/ - -/* - * Overflow status register bit table and corresponding counter - * dependent on MAC type - the number relates to the size of overflow - * mask returned by the pFnMacOverflow function - */ -PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { -/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, -/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST}, -/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC}, -/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST}, -/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW}, -/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH}, -/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64}, -/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127}, -/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255}, -/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511}, -/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023}, -/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX}, -/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES}, -/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED}, -/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL}, -/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL}, -/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL}, -/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL}, -/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL}, -/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN}, -/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED}, -/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED}, -/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED}, -/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED}, -/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED}, -/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED}, -/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST}, -/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST}, -/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC}, -/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST}, -/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS}, -/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED}, -/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW}, -/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH}, -/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW}, -/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH}, -/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE}, -/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT}, -/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64}, -/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127}, -/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255}, -/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511}, -/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023}, -/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX}, -/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES}, -/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG}, -/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER}, -/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED}, -/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW}, -/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED}, -/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED}, -/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED}, -/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED}, -/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED}, -/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED}, -/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED}, -/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED}, -/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED} -}; - -/* - * Table for hardware register saving on resets and port switches - */ -PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = { - /* SK_PNMI_HTX */ - {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_OCTETHIGH */ - {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}}, - /* SK_PNMI_HTX_OCTETLOW */ - {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}}, - /* SK_PNMI_HTX_BROADCAST */ - {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_MULTICAST */ - {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_UNICAST */ - {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_BURST */ - {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_PMACC */ - {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}}, - /* SK_PNMI_HTX_MACC */ - {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_COL */ - {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}}, - /* SK_PNMI_HTX_SINGLE_COL */ - {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}}, - /* SK_PNMI_HTX_MULTI_COL */ - {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}}, - /* SK_PNMI_HTX_EXCESS_COL */ - {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}}, - /* SK_PNMI_HTX_LATE_COL */ - {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}}, - /* SK_PNMI_HTX_DEFFERAL */ - {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_EXCESS_DEF */ - {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UNDERRUN */ - {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}}, - /* SK_PNMI_HTX_CARRIER */ - {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UTILUNDER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UTILOVER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_64 */ - {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}}, - /* SK_PNMI_HTX_127 */ - {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}}, - /* SK_PNMI_HTX_255 */ - {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}}, - /* SK_PNMI_HTX_511 */ - {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}}, - /* SK_PNMI_HTX_1023 */ - {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}}, - /* SK_PNMI_HTX_MAX */ - {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}}, - /* SK_PNMI_HTX_LONGFRAMES */ - {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}}, - /* SK_PNMI_HTX_SYNC */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_SYNC_OCTET */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_RESERVED */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX */ - {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_OCTETHIGH */ - {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}}, - /* SK_PNMI_HRX_OCTETLOW */ - {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}}, - /* SK_PNMI_HRX_BADOCTETHIGH */ - {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}}, - /* SK_PNMI_HRX_BADOCTETLOW */ - {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}}, - /* SK_PNMI_HRX_BROADCAST */ - {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_MULTICAST */ - {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_UNICAST */ - {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_PMACC */ - {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}}, - /* SK_PNMI_HRX_MACC */ - {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_PMACC_ERR */ - {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_MACC_UNKWN */ - {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_BURST */ - {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_MISSED */ - {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_FRAMING */ - {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UNDERSIZE */ - {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}}, - /* SK_PNMI_HRX_OVERFLOW */ - {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, - /* SK_PNMI_HRX_JABBER */ - {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}}, - /* SK_PNMI_HRX_CARRIER */ - {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_IRLENGTH */ - {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_SYMBOL */ - {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_SHORTS */ - {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_RUNT */ - {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}}, - /* SK_PNMI_HRX_TOO_LONG */ - {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}}, - /* SK_PNMI_HRX_FCS */ - {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}}, - /* SK_PNMI_HRX_CEXT */ - {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UTILUNDER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UTILOVER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_64 */ - {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}}, - /* SK_PNMI_HRX_127 */ - {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}}, - /* SK_PNMI_HRX_255 */ - {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}}, - /* SK_PNMI_HRX_511 */ - {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}}, - /* SK_PNMI_HRX_1023 */ - {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}}, - /* SK_PNMI_HRX_MAX */ - {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}}, - /* SK_PNMI_HRX_LONGFRAMES */ - {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}}, - /* SK_PNMI_HRX_RESERVED */ - {{0, SK_FALSE}, {0, SK_FALSE}} -}; - - -/***************************************************************************** - * - * Public functions - * - */ - -/***************************************************************************** - * - * SkPnmiInit - Init function of PNMI - * - * Description: - * SK_INIT_DATA: Initialises the data structures - * SK_INIT_IO: Resets the XMAC statistics, determines the device and - * connector type. - * SK_INIT_RUN: Starts a timer event for port switch per hour - * calculation. - * - * Returns: - * Always 0 - */ -int SkPnmiInit( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Level) /* Initialization level */ -{ - unsigned int PortMax; /* Number of ports */ - unsigned int PortIndex; /* Current port index in loop */ - SK_U16 Val16; /* Multiple purpose 16 bit variable */ - SK_U8 Val8; /* Mulitple purpose 8 bit variable */ - SK_EVPARA EventParam; /* Event struct for timer event */ - SK_PNMI_VCT *pVctBackupData; - - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiInit: Called, level=%d\n", Level)); - - switch (Level) { - - case SK_INIT_DATA: - SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi)); - pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN; - pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES; - for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) { - - pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; - pAC->Pnmi.DualNetActiveFlag = SK_FALSE; - } - -#ifdef SK_PNMI_CHECK - if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("CounterOffset struct size (%d) differs from" - "SK_PNMI_MAX_IDX (%d)\n", - SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); - } - - if (SK_PNMI_MAX_IDX != - (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("StatAddr table size (%d) differs from " - "SK_PNMI_MAX_IDX (%d)\n", - (sizeof(StatAddr) / - (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), - SK_PNMI_MAX_IDX)); - } -#endif /* SK_PNMI_CHECK */ - break; - - case SK_INIT_IO: - /* - * Reset MAC counters - */ - PortMax = pAC->GIni.GIMacsFound; - - for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - - pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); - } - - /* Initialize DSP variables for Vct() to 0xff => Never written! */ - for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - pAC->GIni.GP[PortIndex].PCableLen = 0xff; - pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; - pVctBackupData->PCableLen = 0xff; - } - - /* - * Get pci bus speed - */ - SK_IN16(IoC, B0_CTST, &Val16); - if ((Val16 & CS_BUS_CLOCK) == 0) { - - pAC->Pnmi.PciBusSpeed = 33; - } - else { - pAC->Pnmi.PciBusSpeed = 66; - } - - /* - * Get pci bus width - */ - SK_IN16(IoC, B0_CTST, &Val16); - if ((Val16 & CS_BUS_SLOT_SZ) == 0) { - - pAC->Pnmi.PciBusWidth = 32; - } - else { - pAC->Pnmi.PciBusWidth = 64; - } - - /* - * Get chipset - */ - switch (pAC->GIni.GIChipId) { - case CHIP_ID_GENESIS: - pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; - break; - - case CHIP_ID_YUKON: - pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; - break; - - default: - break; - } - - /* - * Get PMD and DeviceType - */ - SK_IN8(IoC, B2_PMD_TYP, &Val8); - switch (Val8) { - case 'S': - pAC->Pnmi.PMD = 3; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020002; - } - else { - pAC->Pnmi.DeviceType = 0x00020001; - } - break; - - case 'L': - pAC->Pnmi.PMD = 2; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020004; - } - else { - pAC->Pnmi.DeviceType = 0x00020003; - } - break; - - case 'C': - pAC->Pnmi.PMD = 4; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020006; - } - else { - pAC->Pnmi.DeviceType = 0x00020005; - } - break; - - case 'T': - pAC->Pnmi.PMD = 5; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020008; - } - else { - pAC->Pnmi.DeviceType = 0x00020007; - } - break; - - default : - pAC->Pnmi.PMD = 1; - pAC->Pnmi.DeviceType = 0; - break; - } - - /* - * Get connector - */ - SK_IN8(IoC, B2_CONN_TYP, &Val8); - switch (Val8) { - case 'C': - pAC->Pnmi.Connector = 2; - break; - - case 'D': - pAC->Pnmi.Connector = 3; - break; - - case 'F': - pAC->Pnmi.Connector = 4; - break; - - case 'J': - pAC->Pnmi.Connector = 5; - break; - - case 'V': - pAC->Pnmi.Connector = 6; - break; - - default: - pAC->Pnmi.Connector = 1; - break; - } - break; - - case SK_INIT_RUN: - /* - * Start timer for RLMT change counter - */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, - 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, - EventParam); - break; - - default: - break; /* Nothing todo */ - } - - return (0); -} - -/***************************************************************************** - * - * SkPnmiGetVar - Retrieves the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. If the instance - * -1 is passed, the values of all instances are returned in an - * array of values. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -static int SkPnmiGetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiPreSetVar - Presets the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is useful to check if a set might be successfull. - * If the instance -1 is passed, an array of values is supposed and - * all instances of the OID will be set. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -static int SkPnmiPreSetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* Total length of management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - - return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiSetVar - Sets the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is useful to check if a set might be successfull. - * If the instance -1 is passed, an array of values is supposed and - * all instances of the OID will be set. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiSetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* Total length of management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Runs through the IdTable, queries the single OIDs and stores the - * returned data into the management database structure - * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure - * is stored in the IdTable. The return value of the function will also - * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the - * minimum size of SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -int SkPnmiGetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer to which the management data will be copied. */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int TableIndex; - unsigned int DstOffset; - unsigned int InstanceNo; - unsigned int InstanceCnt; - SK_U32 Instance; - unsigned int TmpLen; - char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; - - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - if (*pLen < SK_PNMI_STRUCT_SIZE) { - - if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { - - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, - (SK_U32)(-1)); - } - - *pLen = SK_PNMI_STRUCT_SIZE; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Check NetIndex - */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - /* Update statistic */ - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call"); - - if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) != - SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - /* - * Increment semaphores to indicate that an update was - * already done - */ - pAC->Pnmi.MacUpdatedFlag ++; - pAC->Pnmi.RlmtUpdatedFlag ++; - pAC->Pnmi.SirqUpdatedFlag ++; - - /* Get vpd keys for instance calculation */ - Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_GENERAL); - } - - /* Retrieve values */ - SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); - for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { - - InstanceNo = IdTable[TableIndex].InstanceNo; - for (InstanceCnt = 1; InstanceCnt <= InstanceNo; - InstanceCnt ++) { - - DstOffset = IdTable[TableIndex].Offset + - (InstanceCnt - 1) * - IdTable[TableIndex].StructSize; - - /* - * For the VPD the instance is not an index number - * but the key itself. Determin with the instance - * counter the VPD key to be used. - */ - if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY || - IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE || - IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS || - IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) { - - SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4); - } - else { - Instance = (SK_U32)InstanceCnt; - } - - TmpLen = *pLen - DstOffset; - Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET, - IdTable[TableIndex].Id, (char *)pBuf + - DstOffset, &TmpLen, Instance, TableIndex, NetIndex); - - /* - * An unknown instance error means that we reached - * the last instance of that variable. Proceed with - * the next OID in the table and ignore the return - * code. - */ - if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { - - break; - } - - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, Ret, DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - } - } - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - *pLen = SK_PNMI_STRUCT_SIZE; - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Calls a general sub-function for all this set stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is useful to check if a set might be successfull. - * The sub-function runs through the IdTable, checks which OIDs are able - * to set, and calls the handler function of the OID to perform the - * preset. The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - */ -int SkPnmiPreSetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer which contains the data to be set */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, - pLen, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Calls a general sub-function for all this set stuff. The return value - * of the function will also be stored in SK_PNMI_STRUCT_DATA if the - * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE. - * The sub-function runs through the IdTable, checks which OIDs are able - * to set, and calls the handler function of the OID to perform the - * set. The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - */ -int SkPnmiSetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer which contains the data to be set */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, - pLen, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiEvent - Event handler - * - * Description: - * Handles the following events: - * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an - * interrupt will be generated which is - * first handled by SIRQ which generates a - * this event. The event increments the - * upper 32 bit of the 64 bit counter. - * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module - * when a sensor reports a warning or - * error. The event will store a trap - * message in the trap buffer. - * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this - * module and is used to calculate the - * port switches per hour. - * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and - * timestamps. - * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver - * before a hard reset of the XMAC is - * performed. All counters will be saved - * and added to the hardware counter - * values after reset to grant continuous - * counter values. - * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port - * went logically up. A trap message will - * be stored to the trap buffer. - * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port - * went logically down. A trap message will - * be stored to the trap buffer. - * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two - * spanning tree root bridges were - * detected. A trap message will be stored - * to the trap buffer. - * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went - * down. PNMI will not further add the - * statistic values to the virtual port. - * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and - * is now an active port. PNMI will now - * add the statistic data of this port to - * the virtual port. - * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter - * contains the number of nets. 1 means single net, 2 means - * dual net. The second parameter is -1 - * - * Returns: - * Always 0 - */ -int SkPnmiEvent( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Event, /* Event-Id */ -SK_EVPARA Param) /* Event dependent parameter */ -{ - unsigned int PhysPortIndex; - unsigned int MaxNetNumber; - int CounterIndex; - int Ret; - SK_U16 MacStatus; - SK_U64 OverflowStatus; - SK_U64 Mask; - int MacType; - SK_U64 Value; - SK_U32 Val32; - SK_U16 Register; - SK_EVPARA EventParam; - SK_U64 NewestValue; - SK_U64 OldestValue; - SK_U64 Delta; - SK_PNMI_ESTIMATE *pEst; - SK_U32 NetIndex; - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctBackupData; - SK_U32 RetCode; - int i; - SK_U32 CableLength; - - -#ifdef DEBUG - if (Event != SK_PNMI_EVT_XMAC_RESET) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", - (unsigned int)Event, (unsigned int)Param.Para64)); - } -#endif /* DEBUG */ - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); - - MacType = pAC->GIni.GIMacType; - - switch (Event) { - - case SK_PNMI_EVT_SIRQ_OVERFLOW: - PhysPortIndex = (int)Param.Para32[0]; - MacStatus = (SK_U16)Param.Para32[1]; -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter" - " wrong, PhysPortIndex=0x%x\n", - PhysPortIndex)); - return (0); - } -#endif /* DEBUG */ - OverflowStatus = 0; - - /* - * Check which source caused an overflow interrupt. - */ - if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, - MacStatus, &OverflowStatus) != 0) || - (OverflowStatus == 0)) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - - /* - * Check the overflow status register and increment - * the upper dword of corresponding counter. - */ - for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8; - CounterIndex ++) { - - Mask = (SK_U64)1 << CounterIndex; - if ((OverflowStatus & Mask) == 0) { - - continue; - } - - switch (StatOvrflwBit[CounterIndex][MacType]) { - - case SK_PNMI_HTX_UTILUNDER: - case SK_PNMI_HTX_UTILOVER: - if (MacType == SK_MAC_XMAC) { - XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register); - Register |= XM_TX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register); - } - break; - - case SK_PNMI_HRX_UTILUNDER: - case SK_PNMI_HRX_UTILOVER: - if (MacType == SK_MAC_XMAC) { - XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register); - Register |= XM_RX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register); - } - break; - - case SK_PNMI_HTX_OCTETHIGH: - case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HTX_RESERVED: - case SK_PNMI_HRX_OCTETHIGH: - case SK_PNMI_HRX_OCTETLOW: - case SK_PNMI_HRX_IRLENGTH: - case SK_PNMI_HRX_RESERVED: - - /* - * the following counters aren't be handled (id > 63) - */ - case SK_PNMI_HTX_SYNC: - case SK_PNMI_HTX_SYNC_OCTET: - break; - - case SK_PNMI_HRX_LONGFRAMES: - if (MacType == SK_MAC_GMAC) { - pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[CounterIndex] ++; - } - break; - - default: - pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[CounterIndex] ++; - } - } - break; - - case SK_PNMI_EVT_SEN_WAR_LOW: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_WAR_UPP: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_ERR_LOW: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_ERR_UPP: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_CHG_EST_TIMER: - /* - * Calculate port switch average on a per hour basis - * Time interval for check : 28125 ms - * Number of values for average : 8 - * - * Be careful in changing these values, on change check - * - typedef of SK_PNMI_ESTIMATE (Size of EstValue - * array one less than value number) - * - Timer initialization SkTimerStart() in SkPnmiInit - * - Delta value below must be multiplicated with - * power of 2 - * - */ - pEst = &pAC->Pnmi.RlmtChangeEstimate; - CounterIndex = pEst->EstValueIndex + 1; - if (CounterIndex == 7) { - - CounterIndex = 0; - } - pEst->EstValueIndex = CounterIndex; - - NewestValue = pAC->Pnmi.RlmtChangeCts; - OldestValue = pEst->EstValue[CounterIndex]; - pEst->EstValue[CounterIndex] = NewestValue; - - /* - * Calculate average. Delta stores the number of - * port switches per 28125 * 8 = 225000 ms - */ - if (NewestValue >= OldestValue) { - - Delta = NewestValue - OldestValue; - } - else { - /* Overflow situation */ - Delta = (SK_U64)(0 - OldestValue) + NewestValue; - } - - /* - * Extrapolate delta to port switches per hour. - * Estimate = Delta * (3600000 / 225000) - * = Delta * 16 - * = Delta << 4 - */ - pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4; - - /* - * Check if threshold is exceeded. If the threshold is - * permanently exceeded every 28125 ms an event will be - * generated to remind the user of this condition. - */ - if ((pAC->Pnmi.RlmtChangeThreshold != 0) && - (pAC->Pnmi.RlmtChangeEstimate.Estimate >= - pAC->Pnmi.RlmtChangeThreshold)) { - - QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - } - - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, - 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, - EventParam); - break; - - case SK_PNMI_EVT_CLEAR_COUNTER: - /* - * Param.Para32[0] contains the NetIndex (0 ..1). - * Param.Para32[1] is reserved, contains -1. - */ - NetIndex = (SK_U32)Param.Para32[0]; - -#ifdef DEBUG - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n", - NetIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Set all counters and timestamps to zero. - * The according NetIndex is required as a - * parameter of the event. - */ - ResetCounter(pAC, IoC, NetIndex); - break; - - case SK_PNMI_EVT_XMAC_RESET: - /* - * To grant continuous counter values store the current - * XMAC statistic values to the entries 1..n of the - * CounterOffset array. XMAC Errata #2 - */ -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif - PhysPortIndex = (unsigned int)Param.Para64; - - /* - * Update XMAC statistic to get fresh values - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - /* - * Increment semaphore to indicate that an update was - * already done - */ - pAC->Pnmi.MacUpdatedFlag ++; - - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] = - GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0; - } - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_PORT_UP: - PhysPortIndex = (unsigned int)Param.Para32[0]; -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" - " wrong, PhysPortIndex=%d\n", PhysPortIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* Bugfix for XMAC errata (#10620)*/ - if (MacType == SK_MAC_XMAC) { - /* Add incremental difference to offset (#10620)*/ - (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, - XM_RXE_SHT_ERR, &Val32); - - Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); - pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += - Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; - } - - /* Tell VctStatus() that a link was up meanwhile. */ - pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; - break; - - case SK_PNMI_EVT_RLMT_PORT_DOWN: - PhysPortIndex = (unsigned int)Param.Para32[0]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" - " wrong, PhysPortIndex=%d\n", PhysPortIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* Bugfix #10620 - get zero level for incremental difference */ - if (MacType == SK_MAC_XMAC) { - - (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, - XM_RXE_SHT_ERR, &Val32); - - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = - (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); - } - break; - - case SK_PNMI_EVT_RLMT_ACTIVE_DOWN: - PhysPortIndex = (unsigned int)Param.Para32[0]; - NetIndex = (SK_U32)Param.Para32[1]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n", - PhysPortIndex)); - } - - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n", - NetIndex)); - } -#endif /* DEBUG */ - - /* - * For now, ignore event if NetIndex != 0. - */ - if (Param.Para32[1] != 0) { - - return (0); - } - - /* - * Nothing to do if port is already inactive - */ - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - return (0); - } - - /* - * Update statistic counters to calculate new offset for the virtual - * port and increment semaphore to indicate that an update was already - * done. - */ - if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != - SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Calculate new counter offset for virtual port to grant continous - * counting on port switches. The virtual port consists of all currently - * active ports. The port down event indicates that a port is removed - * from the virtual port. Therefore add the counter value of the removed - * port to the CounterOffset for the virtual port to grant the same - * counter value. - */ - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; - } - - /* - * Set port to inactive - */ - pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_ACTIVE_UP: - PhysPortIndex = (unsigned int)Param.Para32[0]; - NetIndex = (SK_U32)Param.Para32[1]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n", - PhysPortIndex)); - } - - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n", - NetIndex)); - } -#endif /* DEBUG */ - - /* - * For now, ignore event if NetIndex != 0. - */ - if (Param.Para32[1] != 0) { - - return (0); - } - - /* - * Nothing to do if port is already active - */ - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - return (0); - } - - /* - * Statistic maintenance - */ - pAC->Pnmi.RlmtChangeCts ++; - pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtNewMacTrap(pAC, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* - * Update statistic counters to calculate new offset for the virtual - * port and increment semaphore to indicate that an update was - * already done. - */ - if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != - SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Calculate new counter offset for virtual port to grant continous - * counting on port switches. A new port is added to the virtual port. - * Therefore substract the counter value of the new port from the - * CounterOffset for the virtual port to grant the same value. - */ - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; - } - - /* Set port to active */ - pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_SEGMENTATION: - /* - * Para.Para32[0] contains the NetIndex. - */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_RLMT_SET_NETS: - /* - * Param.Para32[0] contains the number of Nets. - * Param.Para32[1] is reserved, contains -1. - */ - /* - * Check number of nets - */ - MaxNetNumber = pAC->GIni.GIMacsFound; - if (((unsigned int)Param.Para32[0] < 1) - || ((unsigned int)Param.Para32[0] > MaxNetNumber)) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */ - pAC->Pnmi.DualNetActiveFlag = SK_FALSE; - } - else { /* dual net mode */ - pAC->Pnmi.DualNetActiveFlag = SK_TRUE; - } - break; - - case SK_PNMI_EVT_VCT_RESET: - PhysPortIndex = Param.Para32[0]; - pPrt = &pAC->GIni.GP[PhysPortIndex]; - pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 2) { - /* - * VCT test is still running. - * Start VCT timer counter again. - */ - SK_MEMSET((char *) &Param, 0, sizeof(Param)); - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkTimerStart(pAC, IoC, - &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, - 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); - break; - } - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] |= - (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); - - /* Copy results for later use to PNMI struct. */ - for (i = 0; i < 4; i++) { - if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { - if ((pPrt->PMdiPairLen[i] > 35) && - (pPrt->PMdiPairLen[i] < 0xff)) { - pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; - } - } - if ((pPrt->PMdiPairLen[i] > 35) && - (pPrt->PMdiPairLen[i] != 0xff)) { - CableLength = 1000 * - (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); - } - else { - CableLength = 0; - } - pVctBackupData->PMdiPairLen[i] = CableLength; - pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; - } - - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); - SkEventDispatcher(pAC, IoC); - } - - break; - - default: - break; - } - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); -} - - -/****************************************************************************** - * - * Private functions - * - */ - -/***************************************************************************** - * - * PnmiVar - Gets, presets, and sets single OIDs - * - * Description: - * Looks up the requested OID, calls the corresponding handler - * function, and passes the parameters with the get, preset, or - * set command. The function is called by SkGePnmiGetVar, - * SkGePnmiPreSetVar, or SkGePnmiSetVar. - * - * Returns: - * SK_PNMI_ERR_XXX. For details have a look at the description of the - * calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -PNMI_STATIC int PnmiVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Total length of pBuf management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int TableIndex; - int Ret; - - - if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_OID); - } - - /* Check NetIndex */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - SK_PNMI_CHECKFLAGS("PnmiVar: On call"); - - Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen, - Instance, TableIndex, NetIndex); - - SK_PNMI_CHECKFLAGS("PnmiVar: On return"); - - return (Ret); -} - -/***************************************************************************** - * - * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA - * - * Description: - * The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable, - * checks which OIDs are able to set, and calls the handler function of - * the OID to perform the set. The return value of the function will - * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the - * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called - * by SkGePnmiPreSetStruct and SkGePnmiSetStruct. - * - * Returns: - * SK_PNMI_ERR_XXX. The codes are described in the calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -PNMI_STATIC int PnmiStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* PRESET/SET action to be performed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Length of pBuf management data buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int TableIndex; - unsigned int DstOffset; - unsigned int Len; - unsigned int InstanceNo; - unsigned int InstanceCnt; - SK_U32 Instance; - SK_U32 Id; - - - /* Check if the passed buffer has the right size */ - if (*pLen < SK_PNMI_STRUCT_SIZE) { - - /* Check if we can return the error within the buffer */ - if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { - - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, - (SK_U32)(-1)); - } - - *pLen = SK_PNMI_STRUCT_SIZE; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Check NetIndex */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - SK_PNMI_CHECKFLAGS("PnmiStruct: On call"); - - /* - * Update the values of RLMT and SIRQ and increment semaphores to - * indicate that an update was already done. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - pAC->Pnmi.RlmtUpdatedFlag ++; - pAC->Pnmi.SirqUpdatedFlag ++; - - /* Preset/Set values */ - for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { - - if ((IdTable[TableIndex].Access != SK_PNMI_RW) && - (IdTable[TableIndex].Access != SK_PNMI_WO)) { - - continue; - } - - InstanceNo = IdTable[TableIndex].InstanceNo; - Id = IdTable[TableIndex].Id; - - for (InstanceCnt = 1; InstanceCnt <= InstanceNo; - InstanceCnt ++) { - - DstOffset = IdTable[TableIndex].Offset + - (InstanceCnt - 1) * - IdTable[TableIndex].StructSize; - - /* - * Because VPD multiple instance variables are - * not setable we do not need to evaluate VPD - * instances. Have a look to VPD instance - * calculation in SkPnmiGetStruct(). - */ - Instance = (SK_U32)InstanceCnt; - - /* - * Evaluate needed buffer length - */ - Len = 0; - Ret = IdTable[TableIndex].Func(pAC, IoC, - SK_PNMI_GET, IdTable[TableIndex].Id, - NULL, &Len, Instance, TableIndex, NetIndex); - - if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { - - break; - } - if (Ret != SK_PNMI_ERR_TOO_SHORT) { - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, - SK_PNMI_ERR_GENERAL, DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_GENERAL); - } - if (Id == OID_SKGE_VPD_ACTION) { - - switch (*(pBuf + DstOffset)) { - - case SK_PNMI_VPD_CREATE: - Len = 3 + *(pBuf + DstOffset + 3); - break; - - case SK_PNMI_VPD_DELETE: - Len = 3; - break; - - default: - Len = 1; - break; - } - } - - /* Call the OID handler function */ - Ret = IdTable[TableIndex].Func(pAC, IoC, Action, - IdTable[TableIndex].Id, pBuf + DstOffset, - &Len, Instance, TableIndex, NetIndex); - - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, - DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - } - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * LookupId - Lookup an OID in the IdTable - * - * Description: - * Scans the IdTable to find the table entry of an OID. - * - * Returns: - * The table index or -1 if not found. - */ -PNMI_STATIC int LookupId( -SK_U32 Id) /* Object identifier to be searched */ -{ - int i; - - for (i = 0; i < ID_TABLE_SIZE; i++) { - - if (IdTable[i].Id == Id) { - - return i; - } - } - - return (-1); -} - -/***************************************************************************** - * - * OidStruct - Handler of OID_SKGE_ALL_DATA - * - * Description: - * This OID performs a Get/Preset/SetStruct call and returns all data - * in a SK_PNMI_STRUCT_DATA structure. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int OidStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - if (Id != OID_SKGE_ALL_DATA) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, - SK_PNMI_ERR003MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - switch (Action) { - - case SK_PNMI_GET: - return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - - case SK_PNMI_PRESET: - return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - - case SK_PNMI_SET: - return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - } - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); -} - -/***************************************************************************** - * - * Perform - OID handler of OID_SKGE_ACTION - * - * Description: - * None. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Perform( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - SK_U32 ActionOp; - - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Check if a get should be performed */ - if (Action == SK_PNMI_GET) { - - /* A get is easy. We always return the same value */ - ActionOp = (SK_U32)SK_PNMI_ACT_IDLE; - SK_PNMI_STORE_U32(pBuf, ActionOp); - *pLen = sizeof(SK_U32); - - return (SK_PNMI_ERR_OK); - } - - /* Continue with PRESET/SET action */ - if (*pLen > sizeof(SK_U32)) { - - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* Check if the command is a known one */ - SK_PNMI_READ_U32(pBuf, ActionOp); - if (*pLen > sizeof(SK_U32) || - (ActionOp != SK_PNMI_ACT_IDLE && - ActionOp != SK_PNMI_ACT_RESET && - ActionOp != SK_PNMI_ACT_SELFTEST && - ActionOp != SK_PNMI_ACT_RESETCNT)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - switch (ActionOp) { - - case SK_PNMI_ACT_IDLE: - /* Nothing to do */ - break; - - case SK_PNMI_ACT_RESET: - /* - * Perform a driver reset or something that comes near - * to this. - */ - Ret = SK_DRIVER_RESET(pAC, IoC); - if (Ret != 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, - SK_PNMI_ERR005MSG); - - return (SK_PNMI_ERR_GENERAL); - } - break; - - case SK_PNMI_ACT_SELFTEST: - /* - * Perform a driver selftest or something similar to this. - * Currently this feature is not used and will probably - * implemented in another way. - */ - Ret = SK_DRIVER_SELFTEST(pAC, IoC); - pAC->Pnmi.TestResult = Ret; - break; - - case SK_PNMI_ACT_RESETCNT: - /* Set all counters and timestamps to zero */ - ResetCounter(pAC, IoC, NetIndex); - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, - SK_PNMI_ERR006MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX - * - * Description: - * Retrieves the statistic values of the virtual port (logical - * index 0). Only special OIDs of NDIS are handled which consist - * of a 32 bit instead of a 64 bit value. The OIDs are public - * because perhaps some other platform can use them too. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Mac8023Stat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - SK_U64 StatVal; - SK_U32 StatVal32; - SK_BOOL Is64BitReq = SK_FALSE; - - /* - * Only the active Mac is returned - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check action type - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - switch (Id) { - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - if (*pLen < sizeof(SK_MAC_ADDR)) { - - *pLen = sizeof(SK_MAC_ADDR); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: -#ifndef SK_NDIS_64BIT_CTR - if (*pLen < sizeof(SK_U32)) { - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - -#else /* SK_NDIS_64BIT_CTR */ - - /* for compatibility, at least 32bit are required for OID */ - if (*pLen < sizeof(SK_U32)) { - /* - * but indicate handling for 64bit values, - * if insufficient space is provided - */ - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; -#endif /* SK_NDIS_64BIT_CTR */ - break; - } - - /* - * Update all statistics, because we retrieve virtual MAC, which - * consists of multiple physical statistics and increment semaphore - * to indicate that an update was already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if ( Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Get value (MAC Index 0 identifies the virtual MAC) - */ - switch (Id) { - - case OID_802_3_PERMANENT_ADDRESS: - CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress); - *pLen = sizeof(SK_MAC_ADDR); - break; - - case OID_802_3_CURRENT_ADDRESS: - CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress); - *pLen = sizeof(SK_MAC_ADDR); - break; - - default: - StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); - - /* by default 32bit values are evaluated */ - if (!Is64BitReq) { - StatVal32 = (SK_U32)StatVal; - SK_PNMI_STORE_U32(pBuf, StatVal32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, StatVal); - *pLen = sizeof(SK_U64); - } - break; - } - - pAC->Pnmi.MacUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX - * - * Description: - * Retrieves the MAC statistic data. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int MacPrivateStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int LogPortMax; - unsigned int LogPortIndex; - unsigned int PhysPortMax; - unsigned int Limit; - unsigned int Offset; - int MacType; - int Ret; - SK_U64 StatVal; - - - - /* Calculate instance if wished. MAC index 0 is the virtual MAC */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - MacType = pAC->GIni.GIMacType; - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* Check action */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Update MAC statistic and increment semaphore to indicate that - * an update was already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* Get value */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - -/* XXX not yet implemented due to XMAC problems - case OID_SKGE_STAT_TX_UTIL: - return (SK_PNMI_ERR_GENERAL); -*/ -/* XXX not yet implemented due to XMAC problems - case OID_SKGE_STAT_RX_UTIL: - return (SK_PNMI_ERR_GENERAL); -*/ - case OID_SKGE_STAT_RX: - if (MacType == SK_MAC_GMAC) { - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNDERSIZE, NetIndex); - } - else { - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - break; - - case OID_SKGE_STAT_TX: - if (MacType == SK_MAC_GMAC) { - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_UNICAST, NetIndex); - } - else { - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - break; - - default: - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); - - Offset += sizeof(SK_U64); - } - *pLen = Offset; - - pAC->Pnmi.MacUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR - * - * Description: - * Get/Presets/Sets the current and factory MAC address. The MAC - * address of the virtual port, which is reported to the OS, may - * not be changed, but the physical ones. A set to the virtual port - * will be ignored. No error should be reported because otherwise - * a multiple instance set (-1) would always fail. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Addr( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int LogPortMax; - unsigned int PhysPortMax; - unsigned int LogPortIndex; - unsigned int PhysPortIndex; - unsigned int Limit; - unsigned int Offset = 0; - - /* - * Calculate instance if wished. MAC index 0 is the virtual - * MAC. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* - * Perform Action - */ - if (Action == SK_PNMI_GET) { - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * 6) { - - *pLen = (Limit - LogPortIndex) * 6; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get value - */ - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - - case OID_SKGE_PHYS_CUR_ADDR: - if (LogPortIndex == 0) { - CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress); - } - else { - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - CopyMac(pBuf + Offset, - &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress); - } - Offset += 6; - break; - - case OID_SKGE_PHYS_FAC_ADDR: - if (LogPortIndex == 0) { - CopyMac(pBuf + Offset, - &pAC->Addr.Net[NetIndex].PermanentMacAddress); - } - else { - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - CopyMac(pBuf + Offset, - &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress); - } - Offset += 6; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, - SK_PNMI_ERR008MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - *pLen = Offset; - } - else { - /* - * The logical MAC address may not be changed only - * the physical ones - */ - if (Id == OID_SKGE_PHYS_FAC_ADDR) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Only the current address may be changed - */ - if (Id != OID_SKGE_PHYS_CUR_ADDR) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, - SK_PNMI_ERR009MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * 6) { - - *pLen = (Limit - LogPortIndex) * 6; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen > (Limit - LogPortIndex) * 6) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* - * Check Action - */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - - /* - * Set OID_SKGE_MAC_CUR_ADDR - */ - for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) { - - /* - * A set to virtual port and set of broadcast - * address will be ignored - */ - if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset, - "\xff\xff\xff\xff\xff\xff", 6) == 0) { - - continue; - } - - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, - LogPortIndex); - - Ret = SkAddrOverride(pAC, IoC, PhysPortIndex, - (SK_MAC_ADDR *)(pBuf + Offset), - (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS : - SK_ADDR_PHYSICAL_ADDRESS)); - if (Ret != SK_ADDR_OVERRIDE_SUCCESS) { - - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX - * - * Description: - * Retrieves the statistic values of the CSUM module. The CSUM data - * structure must be available in the SK_AC even if the CSUM module - * is not included, because PNMI reads the statistic data from the - * CSUM part of SK_AC directly. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int CsumStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int Index; - unsigned int Limit; - unsigned int Offset = 0; - SK_U64 StatVal; - - - /* - * Calculate instance if wished - */ - if (Instance != (SK_U32)(-1)) { - - if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - Index = (unsigned int)Instance - 1; - Limit = Index + 1; - } - else { - Index = 0; - Limit = SKCS_NUM_PROTOCOLS; - } - - /* - * Check action - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - if (*pLen < (Limit - Index) * sizeof(SK_U64)) { - - *pLen = (Limit - Index) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get value - */ - for (; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_CHKSM_RX_OK_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts; - break; - - case OID_SKGE_CHKSM_RX_UNABLE_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts; - break; - - case OID_SKGE_CHKSM_RX_ERR_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts; - break; - - case OID_SKGE_CHKSM_TX_OK_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts; - break; - - case OID_SKGE_CHKSM_TX_UNABLE_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, - SK_PNMI_ERR010MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); - Offset += sizeof(SK_U64); - } - - /* - * Store used buffer space - */ - *pLen = Offset; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX - * - * Description: - * Retrieves the statistic values of the I2C module, which handles - * the temperature and voltage sensors. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int SensorStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int i; - unsigned int Index; - unsigned int Limit; - unsigned int Offset; - unsigned int Len; - SK_U32 Val32; - SK_U64 Val64; - - - /* - * Calculate instance if wished - */ - if ((Instance != (SK_U32)(-1))) { - - if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - Index = (unsigned int)Instance -1; - Limit = (unsigned int)Instance; - } - else { - Index = 0; - Limit = (unsigned int) pAC->I2c.MaxSens; - } - - /* - * Check action - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - switch (Id) { - - case OID_SKGE_SENSOR_VALUE: - case OID_SKGE_SENSOR_WAR_THRES_LOW: - case OID_SKGE_SENSOR_WAR_THRES_UPP: - case OID_SKGE_SENSOR_ERR_THRES_LOW: - case OID_SKGE_SENSOR_ERR_THRES_UPP: - if (*pLen < (Limit - Index) * sizeof(SK_U32)) { - - *pLen = (Limit - Index) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_DESCR: - for (Offset = 0, i = Index; i < Limit; i ++) { - - Len = (unsigned int) - SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1; - if (Len >= SK_PNMI_STRINGLEN2) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, - SK_PNMI_ERR011MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - Offset += Len; - } - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_INDEX: - case OID_SKGE_SENSOR_TYPE: - case OID_SKGE_SENSOR_STATUS: - if (*pLen < Limit - Index) { - - *pLen = Limit - Index; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_WAR_CTS: - case OID_SKGE_SENSOR_WAR_TIME: - case OID_SKGE_SENSOR_ERR_CTS: - case OID_SKGE_SENSOR_ERR_TIME: - if (*pLen < (Limit - Index) * sizeof(SK_U64)) { - - *pLen = (Limit - Index) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, - SK_PNMI_ERR012MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - - } - - /* - * Get value - */ - for (Offset = 0; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_SENSOR_INDEX: - *(pBuf + Offset) = (char)Index; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_DESCR: - Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc); - SK_MEMCPY(pBuf + Offset + 1, - pAC->I2c.SenTable[Index].SenDesc, Len); - *(pBuf + Offset) = (char)Len; - Offset += Len + 1; - break; - - case OID_SKGE_SENSOR_TYPE: - *(pBuf + Offset) = - (char)pAC->I2c.SenTable[Index].SenType; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_VALUE: - Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_WAR_THRES_LOW: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreWarnLow; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_WAR_THRES_UPP: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreWarnHigh; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_ERR_THRES_LOW: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreErrLow; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_ERR_THRES_UPP: - Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_STATUS: - *(pBuf + Offset) = - (char)pAC->I2c.SenTable[Index].SenErrFlag; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_WAR_CTS: - Val64 = pAC->I2c.SenTable[Index].SenWarnCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_ERR_CTS: - Val64 = pAC->I2c.SenTable[Index].SenErrCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_WAR_TIME: - Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. - SenBegWarnTS); - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_ERR_TIME: - Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. - SenBegErrTS); - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("SensorStat: Unknown OID should be handled before")); - - return (SK_PNMI_ERR_GENERAL); - } - } - - /* - * Store used buffer space - */ - *pLen = Offset; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Vpd - OID handler function of OID_SKGE_VPD_XXX - * - * Description: - * Get/preset/set of VPD data. As instance the name of a VPD key - * can be passed. The Instance parameter is a SK_U32 and can be - * used as a string buffer for the VPD key, because their maximum - * length is 4 byte. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Vpd( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_VPD_STATUS *pVpdStatus; - unsigned int BufLen; - char Buf[256]; - char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; - char KeyStr[SK_PNMI_VPD_KEY_SIZE]; - unsigned int KeyNo; - unsigned int Offset; - unsigned int Index; - unsigned int FirstIndex; - unsigned int LastIndex; - unsigned int Len; - int Ret; - SK_U32 Val32; - - /* - * Get array of all currently stored VPD keys - */ - Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); - if (Ret != SK_PNMI_ERR_OK) { - *pLen = 0; - return (Ret); - } - - /* - * If instance is not -1, try to find the requested VPD key for - * the multiple instance variables. The other OIDs as for example - * OID VPD_ACTION are single instance variables and must be - * handled separatly. - */ - FirstIndex = 0; - LastIndex = KeyNo; - - if ((Instance != (SK_U32)(-1))) { - - if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE || - Id == OID_SKGE_VPD_ACCESS) { - - SK_STRNCPY(KeyStr, (char *)&Instance, 4); - KeyStr[4] = 0; - - for (Index = 0; Index < KeyNo; Index ++) { - - if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { - FirstIndex = Index; - LastIndex = Index+1; - break; - } - } - if (Index == KeyNo) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - } - else if (Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - } - - /* - * Get value, if a query should be performed - */ - if (Action == SK_PNMI_GET) { - - switch (Id) { - - case OID_SKGE_VPD_FREE_BYTES: - /* Check length of buffer */ - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Get number of free bytes */ - pVpdStatus = VpdStat(pAC, IoC); - if (pVpdStatus == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017, - SK_PNMI_ERR017MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - if ((pVpdStatus->vpd_status & VPD_VALID) == 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018, - SK_PNMI_ERR018MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Val32 = (SK_U32)pVpdStatus->vpd_free_rw; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VPD_ENTRIES_LIST: - /* Check length */ - for (Len = 0, Index = 0; Index < KeyNo; Index ++) { - - Len += SK_STRLEN(KeyArr[Index]) + 1; - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Get value */ - *(pBuf) = (char)Len - 1; - for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { - - Len = SK_STRLEN(KeyArr[Index]); - SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len); - - Offset += Len; - - if (Index < KeyNo - 1) { - - *(pBuf + Offset) = ' '; - Offset ++; - } - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ENTRIES_NUMBER: - /* Check length */ - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Val32 = (SK_U32)KeyNo; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VPD_KEY: - /* Check buffer length, if it is large enough */ - for (Len = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - Len += SK_STRLEN(KeyArr[Index]) + 1; - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get the key to an intermediate buffer, because - * we have to prepend a length byte. - */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - Len = SK_STRLEN(KeyArr[Index]); - - *(pBuf + Offset) = (char)Len; - SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], - Len); - Offset += Len + 1; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_VALUE: - /* Check the buffer length if it is large enough */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - BufLen = 256; - if (VpdRead(pAC, IoC, KeyArr[Index], Buf, - (int *)&BufLen) > 0 || - BufLen >= SK_PNMI_VPD_DATALEN) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR021, - SK_PNMI_ERR021MSG); - - return (SK_PNMI_ERR_GENERAL); - } - Offset += BufLen + 1; - } - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get the value to an intermediate buffer, because - * we have to prepend a length byte. - */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - BufLen = 256; - if (VpdRead(pAC, IoC, KeyArr[Index], Buf, - (int *)&BufLen) > 0 || - BufLen >= SK_PNMI_VPD_DATALEN) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR022, - SK_PNMI_ERR022MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - *(pBuf + Offset) = (char)BufLen; - SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen); - Offset += BufLen + 1; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ACCESS: - if (*pLen < LastIndex - FirstIndex) { - - *pLen = LastIndex - FirstIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - if (VpdMayWrite(KeyArr[Index])) { - - *(pBuf + Offset) = SK_PNMI_VPD_RW; - } - else { - *(pBuf + Offset) = SK_PNMI_VPD_RO; - } - Offset ++; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ACTION: - Offset = LastIndex - FirstIndex; - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - SK_MEMSET(pBuf, 0, Offset); - *pLen = Offset; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, - SK_PNMI_ERR023MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - else { - /* The only OID which can be set is VPD_ACTION */ - if (Id != OID_SKGE_VPD_ACTION) { - - if (Id == OID_SKGE_VPD_FREE_BYTES || - Id == OID_SKGE_VPD_ENTRIES_LIST || - Id == OID_SKGE_VPD_ENTRIES_NUMBER || - Id == OID_SKGE_VPD_KEY || - Id == OID_SKGE_VPD_VALUE || - Id == OID_SKGE_VPD_ACCESS) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, - SK_PNMI_ERR024MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * From this point we handle VPD_ACTION. Check the buffer - * length. It should at least have the size of one byte. - */ - if (*pLen < 1) { - - *pLen = 1; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * The first byte contains the VPD action type we should - * perform. - */ - switch (*pBuf) { - - case SK_PNMI_VPD_IGNORE: - /* Nothing to do */ - break; - - case SK_PNMI_VPD_CREATE: - /* - * We have to create a new VPD entry or we modify - * an existing one. Check first the buffer length. - */ - if (*pLen < 4) { - - *pLen = 4; - return (SK_PNMI_ERR_TOO_SHORT); - } - KeyStr[0] = pBuf[1]; - KeyStr[1] = pBuf[2]; - KeyStr[2] = 0; - - /* - * Is the entry writable or does it belong to the - * read-only area? - */ - if (!VpdMayWrite(KeyStr)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - Offset = (int)pBuf[3] & 0xFF; - - SK_MEMCPY(Buf, pBuf + 4, Offset); - Buf[Offset] = 0; - - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - /* Write the new entry or modify an existing one */ - Ret = VpdWrite(pAC, IoC, KeyStr, Buf); - if (Ret == SK_PNMI_VPD_NOWRITE ) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - else if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025, - SK_PNMI_ERR025MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform an update of the VPD data. This is - * not mandantory, but just to be sure. - */ - Ret = VpdUpdate(pAC, IoC); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026, - SK_PNMI_ERR026MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case SK_PNMI_VPD_DELETE: - /* Check if the buffer size is plausible */ - if (*pLen < 3) { - - *pLen = 3; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen > 3) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - KeyStr[0] = pBuf[1]; - KeyStr[1] = pBuf[2]; - KeyStr[2] = 0; - - /* Find the passed key in the array */ - for (Index = 0; Index < KeyNo; Index ++) { - - if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { - - break; - } - } - /* - * If we cannot find the key it is wrong, so we - * return an appropriate error value. - */ - if (Index == KeyNo) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - /* Ok, you wanted it and you will get it */ - Ret = VpdDelete(pAC, IoC, KeyStr); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027, - SK_PNMI_ERR027MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform an update of the VPD data. This is - * not mandantory, but just to be sure. - */ - Ret = VpdUpdate(pAC, IoC); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028, - SK_PNMI_ERR028MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * General - OID handler function of various single instance OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int General( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int Index; - unsigned int Len; - unsigned int Offset; - unsigned int Val; - SK_U8 Val8; - SK_U16 Val16; - SK_U32 Val32; - SK_U64 Val64; - SK_U64 Val64RxHwErrs = 0; - SK_U64 Val64TxHwErrs = 0; - SK_BOOL Is64BitReq = SK_FALSE; - char Buf[256]; - int MacType; - - /* - * Check instance. We only handle single instance variables. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check action. We only allow get requests. - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - MacType = pAC->GIni.GIMacType; - - /* - * Check length for the various supported OIDs - */ - switch (Id) { - - case OID_GEN_XMIT_ERROR: - case OID_GEN_RCV_ERROR: - case OID_GEN_RCV_NO_BUFFER: -#ifndef SK_NDIS_64BIT_CTR - if (*pLen < sizeof(SK_U32)) { - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - -#else /* SK_NDIS_64BIT_CTR */ - - /* - * for compatibility, at least 32bit are required for oid - */ - if (*pLen < sizeof(SK_U32)) { - /* - * but indicate handling for 64bit values, - * if insufficient space is provided - */ - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; -#endif /* SK_NDIS_64BIT_CTR */ - break; - - case OID_SKGE_PORT_NUMBER: - case OID_SKGE_DEVICE_TYPE: - case OID_SKGE_RESULT: - case OID_SKGE_RLMT_MONITOR_NUMBER: - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - case OID_SKGE_TRAP_NUMBER: - case OID_SKGE_MDB_VERSION: - case OID_SKGE_BOARDLEVEL: - case OID_SKGE_CHIPID: - case OID_SKGE_RAMSIZE: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_CHIPSET: - if (*pLen < sizeof(SK_U16)) { - - *pLen = sizeof(SK_U16); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_BUS_TYPE: - case OID_SKGE_BUS_SPEED: - case OID_SKGE_BUS_WIDTH: - case OID_SKGE_SENSOR_NUMBER: - case OID_SKGE_CHKSM_NUMBER: - case OID_SKGE_VAUXAVAIL: - if (*pLen < sizeof(SK_U8)) { - - *pLen = sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_TX_SW_QUEUE_LEN: - case OID_SKGE_TX_SW_QUEUE_MAX: - case OID_SKGE_TX_RETRY: - case OID_SKGE_RX_INTR_CTS: - case OID_SKGE_TX_INTR_CTS: - case OID_SKGE_RX_NO_BUF_CTS: - case OID_SKGE_TX_NO_BUF_CTS: - case OID_SKGE_TX_USED_DESCR_NO: - case OID_SKGE_RX_DELIVERED_CTS: - case OID_SKGE_RX_OCTETS_DELIV_CTS: - case OID_SKGE_RX_HW_ERROR_CTS: - case OID_SKGE_TX_HW_ERROR_CTS: - case OID_SKGE_IN_ERRORS_CTS: - case OID_SKGE_OUT_ERROR_CTS: - case OID_SKGE_ERR_RECOVERY_CTS: - case OID_SKGE_SYSUPTIME: - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - /* Checked later */ - break; - } - - /* Update statistic */ - if (Id == OID_SKGE_RX_HW_ERROR_CTS || - Id == OID_SKGE_TX_HW_ERROR_CTS || - Id == OID_SKGE_IN_ERRORS_CTS || - Id == OID_SKGE_OUT_ERROR_CTS || - Id == OID_GEN_XMIT_ERROR || - Id == OID_GEN_RCV_ERROR) { - - /* Force the XMAC to update its statistic counters and - * Increment semaphore to indicate that an update was - * already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Some OIDs consist of multiple hardware counters. Those - * values which are contained in all of them will be added - * now. - */ - switch (Id) { - - case OID_SKGE_RX_HW_ERROR_CTS: - case OID_SKGE_IN_ERRORS_CTS: - case OID_GEN_RCV_ERROR: - Val64RxHwErrs = - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); - break; - - case OID_SKGE_TX_HW_ERROR_CTS: - case OID_SKGE_OUT_ERROR_CTS: - case OID_GEN_XMIT_ERROR: - Val64TxHwErrs = - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); - break; - } - } - - /* - * Retrieve value - */ - switch (Id) { - - case OID_SKGE_SUPPORTED_LIST: - Len = ID_TABLE_SIZE * sizeof(SK_U32); - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - for (Offset = 0, Index = 0; Offset < Len; - Offset += sizeof(SK_U32), Index ++) { - - Val32 = (SK_U32)IdTable[Index].Id; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - } - *pLen = Len; - break; - - case OID_SKGE_BOARDLEVEL: - Val32 = (SK_U32)pAC->GIni.GILevel; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_PORT_NUMBER: - Val32 = (SK_U32)pAC->GIni.GIMacsFound; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_DEVICE_TYPE: - Val32 = (SK_U32)pAC->Pnmi.DeviceType; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_DRIVER_DESCR: - if (pAC->Pnmi.pDriverDescription == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, - SK_PNMI_ERR007MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, - SK_PNMI_ERR029MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_VERSION: - if (pAC->Pnmi.pDriverVersion == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR030MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR031MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_RELDATE: - if (pAC->Pnmi.pDriverReleaseDate == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR053MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR054MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_FILENAME: - if (pAC->Pnmi.pDriverFileName == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR055MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR056MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_HW_DESCR: - /* - * The hardware description is located in the VPD. This - * query may move to the initialisation routine. But - * the VPD data is cached and therefore a call here - * will not make much difference. - */ - Len = 256; - if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, - SK_PNMI_ERR032MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - Len ++; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, - SK_PNMI_ERR033MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, Buf, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_HW_VERSION: - /* Oh, I love to do some string manipulation */ - if (*pLen < 5) { - - *pLen = 5; - return (SK_PNMI_ERR_TOO_SHORT); - } - Val8 = (SK_U8)pAC->GIni.GIPciHwRev; - pBuf[0] = 4; - pBuf[1] = 'v'; - pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); - pBuf[3] = '.'; - pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); - *pLen = 5; - break; - - case OID_SKGE_CHIPSET: - Val16 = pAC->Pnmi.Chipset; - SK_PNMI_STORE_U16(pBuf, Val16); - *pLen = sizeof(SK_U16); - break; - - case OID_SKGE_CHIPID: - Val32 = pAC->GIni.GIChipId; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_RAMSIZE: - Val32 = pAC->GIni.GIRamSize; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VAUXAVAIL: - *pBuf = (char) pAC->GIni.GIVauxAvail; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_TYPE: - *pBuf = (char) SK_PNMI_BUS_PCI; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_SPEED: - *pBuf = pAC->Pnmi.PciBusSpeed; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_WIDTH: - *pBuf = pAC->Pnmi.PciBusWidth; - *pLen = sizeof(char); - break; - - case OID_SKGE_RESULT: - Val32 = pAC->Pnmi.TestResult; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_NUMBER: - *pBuf = (char)pAC->I2c.MaxSens; - *pLen = sizeof(char); - break; - - case OID_SKGE_CHKSM_NUMBER: - *pBuf = SKCS_NUM_PROTOCOLS; - *pLen = sizeof(char); - break; - - case OID_SKGE_TRAP_NUMBER: - GetTrapQueueLen(pAC, &Len, &Val); - Val32 = (SK_U32)Val; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_TRAP: - GetTrapQueueLen(pAC, &Len, &Val); - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - CopyTrapQueue(pAC, pBuf); - *pLen = Len; - break; - - case OID_SKGE_RLMT_MONITOR_NUMBER: -/* XXX Not yet implemented by RLMT therefore we return zero elements */ - Val32 = 0; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_TX_SW_QUEUE_LEN: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + - pAC->Pnmi.BufPort[1].TxSwQueueLen; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + - pAC->Pnmi.Port[1].TxSwQueueLen; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - - case OID_SKGE_TX_SW_QUEUE_MAX: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + - pAC->Pnmi.BufPort[1].TxSwQueueMax; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + - pAC->Pnmi.Port[1].TxSwQueueMax; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_RETRY: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + - pAC->Pnmi.BufPort[1].TxRetryCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxRetryCts + - pAC->Pnmi.Port[1].TxRetryCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + - pAC->Pnmi.BufPort[1].RxIntrCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxIntrCts + - pAC->Pnmi.Port[1].RxIntrCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + - pAC->Pnmi.BufPort[1].TxIntrCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxIntrCts + - pAC->Pnmi.Port[1].TxIntrCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + - pAC->Pnmi.BufPort[1].RxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + - pAC->Pnmi.BufPort[1].TxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_USED_DESCR_NO: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + - pAC->Pnmi.BufPort[1].TxUsedDescrNo; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + - pAC->Pnmi.Port[1].TxUsedDescrNo; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_DELIVERED_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + - pAC->Pnmi.BufPort[1].RxDeliveredCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + - pAC->Pnmi.Port[1].RxDeliveredCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_OCTETS_DELIV_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + - pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + - pAC->Pnmi.Port[1].RxOctetsDeliveredCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_HW_ERROR_CTS: - SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_HW_ERROR_CTS: - SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_IN_ERRORS_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64RxHwErrs + - pAC->Pnmi.BufPort[0].RxNoBufCts + - pAC->Pnmi.BufPort[1].RxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64RxHwErrs + - pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_OUT_ERROR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64TxHwErrs + - pAC->Pnmi.BufPort[0].TxNoBufCts + - pAC->Pnmi.BufPort[1].TxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64TxHwErrs + - pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_ERR_RECOVERY_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + - pAC->Pnmi.BufPort[1].ErrRecoveryCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + - pAC->Pnmi.Port[1].ErrRecoveryCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_SYSUPTIME: - Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - Val64 -= pAC->Pnmi.StartUpTime; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_MDB_VERSION: - Val32 = SK_PNMI_MDB_VERSION; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_GEN_RCV_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - else { - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_XMIT_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - else { - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_RCV_NO_BUFFER: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - else { - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, - SK_PNMI_ERR034MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (Id == OID_SKGE_RX_HW_ERROR_CTS || - Id == OID_SKGE_TX_HW_ERROR_CTS || - Id == OID_SKGE_IN_ERRORS_CTS || - Id == OID_SKGE_OUT_ERROR_CTS || - Id == OID_GEN_XMIT_ERROR || - Id == OID_GEN_RCV_ERROR) { - - pAC->Pnmi.MacUpdatedFlag --; - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance. - * - * Description: - * Get/Presets/Sets the RLMT OIDs. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Rlmt( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int PhysPortIndex; - unsigned int PhysPortMax; - SK_EVPARA EventParam; - SK_U32 Val32; - SK_U64 Val64; - - - /* - * Check instance. Only single instance OIDs are allowed here. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Perform the requested action. - */ - if (Action == SK_PNMI_GET) { - - /* - * Check if the buffer length is large enough. - */ - - switch (Id) { - - case OID_SKGE_RLMT_MODE: - case OID_SKGE_RLMT_PORT_ACTIVE: - case OID_SKGE_RLMT_PORT_PREFERRED: - if (*pLen < sizeof(SK_U8)) { - - *pLen = sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_PORT_NUMBER: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_CHANGE_CTS: - case OID_SKGE_RLMT_CHANGE_TIME: - case OID_SKGE_RLMT_CHANGE_ESTIM: - case OID_SKGE_RLMT_CHANGE_THRES: - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, - SK_PNMI_ERR035MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Update RLMT statistic and increment semaphores to indicate - * that an update was already done. Maybe RLMT will hold its - * statistic always up to date some time. Then we can - * remove this type of call. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.RlmtUpdatedFlag ++; - - /* - * Retrieve Value - */ - switch (Id) { - - case OID_SKGE_RLMT_MODE: - *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode; - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_PORT_NUMBER: - Val32 = (SK_U32)pAC->GIni.GIMacsFound; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_PORT_ACTIVE: - *pBuf = 0; - /* - * If multiple ports may become active this OID - * doesn't make sense any more. A new variable in - * the port structure should be created. However, - * for this variable the first active port is - * returned. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex); - break; - } - } - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_PORT_PREFERRED: - *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference); - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_CHANGE_CTS: - Val64 = pAC->Pnmi.RlmtChangeCts; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_TIME: - Val64 = pAC->Pnmi.RlmtChangeTime; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_ESTIM: - Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_THRES: - Val64 = pAC->Pnmi.RlmtChangeThreshold; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("Rlmt: Unknown OID should be handled before")); - - pAC->Pnmi.RlmtUpdatedFlag --; - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - pAC->Pnmi.RlmtUpdatedFlag --; - } - else { - /* Perform a preset or set */ - switch (Id) { - - case OID_SKGE_RLMT_MODE: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(char)) { - - *pLen = sizeof(char); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Check if the value range is correct */ - if (*pLen != sizeof(char) || - (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 || - *(SK_U8 *)pBuf > 15) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - /* Send an event to RLMT to change the mode */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] |= (SK_U32)(*pBuf); - EventParam.Para32[1] = 0; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, - SK_PNMI_ERR037MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case OID_SKGE_RLMT_PORT_PREFERRED: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(char)) { - - *pLen = sizeof(char); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Check if the value range is correct */ - if (*pLen != sizeof(char) || *(SK_U8 *)pBuf > - (SK_U8)pAC->GIni.GIMacsFound) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - - /* - * Send an event to RLMT change the preferred port. - * A param of -1 means automatic mode. RLMT will - * make the decision which is the preferred port. - */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = (SK_U32)(*pBuf) - 1; - EventParam.Para32[1] = NetIndex; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, - SK_PNMI_ERR038MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case OID_SKGE_RLMT_CHANGE_THRES: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* - * There are not many restrictions to the - * value range. - */ - if (*pLen != sizeof(SK_U64)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - /* - * Store the new threshold, which will be taken - * on the next timer event. - */ - SK_PNMI_READ_U64(pBuf, Val64); - pAC->Pnmi.RlmtChangeThreshold = Val64; - break; - - default: - /* The other OIDs are not be able for set */ - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance. - * - * Description: - * Performs get requests on multiple instance variables. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int RlmtStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - unsigned int Limit; - unsigned int Offset; - int Ret; - SK_U32 Val32; - SK_U64 Val64; - - /* - * Calculate the port indexes from the instance. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - - if ((Instance != (SK_U32)(-1))) { - /* Check instance range */ - if ((Instance < 1) || (Instance > PhysPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* Single net mode */ - PhysPortIndex = Instance - 1; - - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - } - - /* Both net modes */ - Limit = PhysPortIndex + 1; - } - else { - /* Single net mode */ - PhysPortIndex = 0; - Limit = PhysPortMax; - - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - Limit = PhysPortIndex + 1; - } - } - - /* - * Currently only get requests are allowed. - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Check if the buffer length is large enough. - */ - switch (Id) { - - case OID_SKGE_RLMT_PORT_INDEX: - case OID_SKGE_RLMT_STATUS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { - - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_TX_HELLO_CTS: - case OID_SKGE_RLMT_RX_HELLO_CTS: - case OID_SKGE_RLMT_TX_SP_REQ_CTS: - case OID_SKGE_RLMT_RX_SP_CTS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) { - - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, - SK_PNMI_ERR039MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - - } - - /* - * Update statistic and increment semaphores to indicate that - * an update was already done. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.RlmtUpdatedFlag ++; - - /* - * Get value - */ - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex ++) { - - switch (Id) { - - case OID_SKGE_RLMT_PORT_INDEX: - Val32 = PhysPortIndex; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_STATUS: - if (pAC->Rlmt.Port[PhysPortIndex].PortState == - SK_RLMT_PS_INIT || - pAC->Rlmt.Port[PhysPortIndex].PortState == - SK_RLMT_PS_DOWN) { - - Val32 = SK_PNMI_RLMT_STATUS_ERROR; - } - else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - Val32 = SK_PNMI_RLMT_STATUS_ACTIVE; - } - else { - Val32 = SK_PNMI_RLMT_STATUS_STANDBY; - } - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_TX_HELLO_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_RX_HELLO_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_TX_SP_REQ_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_RX_SP_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("RlmtStat: Unknown OID should be errored before")); - - pAC->Pnmi.RlmtUpdatedFlag --; - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - - pAC->Pnmi.RlmtUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacPrivateConf - OID handler function of OIDs concerning the configuration - * - * Description: - * Get/Presets/Sets the OIDs concerning the configuration. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int MacPrivateConf( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - unsigned int LogPortMax; - unsigned int LogPortIndex; - unsigned int Limit; - unsigned int Offset; - char Val8; - char *pBufPtr; - int Ret; - SK_EVPARA EventParam; - SK_U32 Val32; - - /* - * Calculate instance if wished. MAC index 0 is the virtual MAC. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* - * Perform action - */ - if (Action == SK_PNMI_GET) { - - /* Check length */ - switch (Id) { - - case OID_SKGE_PMD: - case OID_SKGE_CONNECTOR: - case OID_SKGE_LINK_CAP: - case OID_SKGE_LINK_MODE: - case OID_SKGE_LINK_MODE_STATUS: - case OID_SKGE_LINK_STATUS: - case OID_SKGE_FLOWCTRL_CAP: - case OID_SKGE_FLOWCTRL_MODE: - case OID_SKGE_FLOWCTRL_STATUS: - case OID_SKGE_PHY_OPERATION_CAP: - case OID_SKGE_PHY_OPERATION_MODE: - case OID_SKGE_PHY_OPERATION_STATUS: - case OID_SKGE_SPEED_CAP: - case OID_SKGE_SPEED_MODE: - case OID_SKGE_SPEED_STATUS: - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_MTU: - case OID_SKGE_PHY_TYPE: - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, - SK_PNMI_ERR041MSG); - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Update statistic and increment semaphore to indicate - * that an update was already done. - */ - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.SirqUpdatedFlag ++; - - /* - * Get value - */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - pBufPtr = pBuf + Offset; - - switch (Id) { - - case OID_SKGE_PMD: - *pBufPtr = pAC->Pnmi.PMD; - Offset += sizeof(char); - break; - - case OID_SKGE_CONNECTOR: - *pBufPtr = pAC->Pnmi.Connector; - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_TYPE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - continue; - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; - SK_PNMI_STORE_U32(pBufPtr, Val32); - } - } - else { /* DualNetMode */ - - Val32 = pAC->GIni.GP[NetIndex].PhyType; - SK_PNMI_STORE_U32(pBufPtr, Val32); - } - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_LINK_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_MODE_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = - CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); - } - } - else { /* DualNetMode */ - - *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); - } - } - else { /* DualNetMode */ - - *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; - } - } - else { - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; - } - Offset += sizeof(char); - break; - - case OID_SKGE_MTU: - Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); - SK_PNMI_STORE_U32(pBufPtr, Val32); - Offset += sizeof(SK_U32); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("MacPrivateConf: Unknown OID should be handled before")); - - pAC->Pnmi.SirqUpdatedFlag --; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - pAC->Pnmi.SirqUpdatedFlag --; - - return (SK_PNMI_ERR_OK); - } - - /* - * From here SET or PRESET action. Check if the passed - * buffer length is plausible. - */ - switch (Id) { - - case OID_SKGE_LINK_MODE: - case OID_SKGE_FLOWCTRL_MODE: - case OID_SKGE_PHY_OPERATION_MODE: - case OID_SKGE_SPEED_MODE: - if (*pLen < Limit - LogPortIndex) { - - *pLen = Limit - LogPortIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen != Limit - LogPortIndex) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - - case OID_SKGE_MTU: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen != sizeof(SK_U32)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Perform preset or set - */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - - case OID_SKGE_LINK_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < SK_LMODE_HALF || - (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) || - (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new link mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_LMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR043, - SK_PNMI_ERR043MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new link mode to - * the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR043, - SK_PNMI_ERR043MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < SK_FLOW_MODE_NONE || - (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) || - (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new flow control mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_FLOWMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR044, - SK_PNMI_ERR044MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new flow control - * mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_FLOWMODE, EventParam) - > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR044, - SK_PNMI_ERR044MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_MODE : - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - /* mode of this port remains unchanged */ - Offset += sizeof(char); - break; - } - if (Val8 < SK_MS_MODE_AUTO || - (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) || - (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with new master/slave (role) mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_ROLE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR042, - SK_PNMI_ERR042MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new master/slave - * (role) mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_ROLE, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR042, - SK_PNMI_ERR042MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < (SK_LSPEED_AUTO) || - (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) || - (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new flow control mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_SPEED, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR045, - SK_PNMI_ERR045MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new flow control - * mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_SPEED, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR045, - SK_PNMI_ERR045MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_MTU : - /* Check the value range */ - Val32 = *(SK_U32*)(pBuf + Offset); - if (Val32 == 0) { - /* mtu of this port remains unchanged */ - Offset += sizeof(SK_U32); - break; - } - if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) { - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) { - return (SK_PNMI_ERR_GENERAL); - } - - Offset += sizeof(SK_U32); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("MacPrivateConf: Unknown OID should be handled before set")); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Monitor - OID handler function for RLMT_MONITOR_XXX - * - * Description: - * Because RLMT currently does not support the monitoring of - * remote adapter cards, we return always an empty table. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Monitor( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int Index; - unsigned int Limit; - unsigned int Offset; - unsigned int Entries; - - - /* - * Calculate instance if wished. - */ - /* XXX Not yet implemented. Return always an empty table. */ - Entries = 0; - - if ((Instance != (SK_U32)(-1))) { - - if ((Instance < 1) || (Instance > Entries)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - Index = (unsigned int)Instance - 1; - Limit = (unsigned int)Instance; - } - else { - Index = 0; - Limit = Entries; - } - - /* - * Get/Set value - */ - if (Action == SK_PNMI_GET) { - - for (Offset=0; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_RLMT_MONITOR_INDEX: - case OID_SKGE_RLMT_MONITOR_ADDR: - case OID_SKGE_RLMT_MONITOR_ERRS: - case OID_SKGE_RLMT_MONITOR_TIMESTAMP: - case OID_SKGE_RLMT_MONITOR_ADMIN: - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, - SK_PNMI_ERR046MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - } - else { - /* Only MONITOR_ADMIN can be set */ - if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check if the length is plausible */ - if (*pLen < (Limit - Index)) { - - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Okay, we have a wide value range */ - if (*pLen != (Limit - Index)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } -/* - for (Offset=0; Index < Limit; Index ++) { - } -*/ -/* - * XXX Not yet implemented. Return always BAD_VALUE, because the table - * is empty. - */ - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * VirtualConf - Calculates the values of configuration OIDs for virtual port - * - * Description: - * We handle here the get of the configuration group OIDs, which are - * a little bit complicated. The virtual port consists of all currently - * active physical ports. If multiple ports are active and configured - * differently we get in some trouble to return a single value. So we - * get the value of the first active port and compare it with that of - * the other active ports. If they are not the same, we return a value - * that indicates that the state is indeterminated. - * - * Returns: - * Nothing - */ -PNMI_STATIC void VirtualConf( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf) /* Buffer used for the management data transfer */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - SK_U8 Val8; - SK_U32 Val32; - SK_BOOL PortActiveFlag; - SK_GEPORT *pPrt; - - *pBuf = 0; - PortActiveFlag = SK_FALSE; - PhysPortMax = pAC->GIni.GIMacsFound; - - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - /* Check if the physical port is active */ - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - continue; - } - - PortActiveFlag = SK_TRUE; - - switch (Id) { - - case OID_SKGE_PHY_TYPE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - Val32 = pPrt->PhyType; - SK_PNMI_STORE_U32(pBuf, Val32); - continue; - } - - case OID_SKGE_LINK_CAP: - - /* - * Different capabilities should not happen, but - * in the case of the cases OR them all together. - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PLinkCap; - break; - - case OID_SKGE_LINK_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkModeConf; - continue; - } - - /* - * If we find an active port with a different link - * mode than the first one we return a value that - * indicates that the link mode is indeterminated. - */ - if (*pBuf != pPrt->PLinkModeConf) { - - *pBuf = SK_LMODE_INDETERMINATED; - } - break; - - case OID_SKGE_LINK_MODE_STATUS: - /* Get the link mode of the physical port */ - Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); - - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = Val8; - continue; - } - - /* - * If we find an active port with a different link - * mode status than the first one we return a value - * that indicates that the link mode status is - * indeterminated. - */ - if (*pBuf != Val8) { - - *pBuf = SK_LMODE_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_LINK_STATUS: - /* Get the link status of the physical port */ - Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex); - - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = Val8; - continue; - } - - /* - * If we find an active port with a different link - * status than the first one, we return a value - * that indicates that the link status is - * indeterminated. - */ - if (*pBuf != Val8) { - - *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; - } - break; - - case OID_SKGE_FLOWCTRL_CAP: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlCap; - continue; - } - - /* - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PFlowCtrlCap; - break; - - case OID_SKGE_FLOWCTRL_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlMode; - continue; - } - - /* - * If we find an active port with a different flow - * control mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PFlowCtrlMode) { - - *pBuf = SK_FLOW_MODE_INDETERMINATED; - } - break; - - case OID_SKGE_FLOWCTRL_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlStatus; - continue; - } - - /* - * If we find an active port with a different flow - * control status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PFlowCtrlStatus) { - - *pBuf = SK_FLOW_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_PHY_OPERATION_CAP: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSCap; - continue; - } - - /* - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PMSCap; - break; - - case OID_SKGE_PHY_OPERATION_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSMode; - continue; - } - - /* - * If we find an active port with a different master/ - * slave mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PMSMode) { - - *pBuf = SK_MS_MODE_INDETERMINATED; - } - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSStatus; - continue; - } - - /* - * If we find an active port with a different master/ - * slave status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PMSStatus) { - - *pBuf = SK_MS_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_SPEED_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkSpeed; - continue; - } - - /* - * If we find an active port with a different flow - * control mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PLinkSpeed) { - - *pBuf = SK_LSPEED_INDETERMINATED; - } - break; - - case OID_SKGE_SPEED_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkSpeedUsed; - continue; - } - - /* - * If we find an active port with a different flow - * control status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PLinkSpeedUsed) { - - *pBuf = SK_LSPEED_STAT_INDETERMINATED; - } - break; - } - } - - /* - * If no port is active return an indeterminated answer - */ - if (!PortActiveFlag) { - - switch (Id) { - - case OID_SKGE_LINK_CAP: - *pBuf = SK_LMODE_CAP_INDETERMINATED; - break; - - case OID_SKGE_LINK_MODE: - *pBuf = SK_LMODE_INDETERMINATED; - break; - - case OID_SKGE_LINK_MODE_STATUS: - *pBuf = SK_LMODE_STAT_INDETERMINATED; - break; - - case OID_SKGE_LINK_STATUS: - *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; - break; - - case OID_SKGE_FLOWCTRL_CAP: - case OID_SKGE_FLOWCTRL_MODE: - *pBuf = SK_FLOW_MODE_INDETERMINATED; - break; - - case OID_SKGE_FLOWCTRL_STATUS: - *pBuf = SK_FLOW_STAT_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_CAP: - *pBuf = SK_MS_CAP_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_MODE: - *pBuf = SK_MS_MODE_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - *pBuf = SK_MS_STAT_INDETERMINATED; - break; - case OID_SKGE_SPEED_CAP: - *pBuf = SK_LSPEED_CAP_INDETERMINATED; - break; - - case OID_SKGE_SPEED_MODE: - *pBuf = SK_LSPEED_INDETERMINATED; - break; - - case OID_SKGE_SPEED_STATUS: - *pBuf = SK_LSPEED_STAT_INDETERMINATED; - break; - } - } -} - -/***************************************************************************** - * - * CalculateLinkStatus - Determins the link status of a physical port - * - * Description: - * Determins the link status the following way: - * LSTAT_PHY_DOWN: Link is down - * LSTAT_AUTONEG: Auto-negotiation failed - * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port - * logically up. - * LSTAT_LOG_UP: RLMT marked the port as up - * - * Returns: - * Link status of physical port - */ -PNMI_STATIC SK_U8 CalculateLinkStatus( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex) /* Physical port index */ -{ - SK_U8 Result; - - if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) { - - Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN; - } - else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) { - - Result = SK_PNMI_RLMT_LSTAT_AUTONEG; - } - else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) { - - Result = SK_PNMI_RLMT_LSTAT_LOG_UP; - } - else { - Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN; - } - - return (Result); -} - -/***************************************************************************** - * - * CalculateLinkModeStatus - Determins the link mode status of a phys. port - * - * Description: - * The COMMON module only tells us if the mode is half or full duplex. - * But in the decade of auto sensing it is useful for the user to - * know if the mode was negotiated or forced. Therefore we have a - * look to the mode, which was last used by the negotiation process. - * - * Returns: - * The link mode status - */ -PNMI_STATIC SK_U8 CalculateLinkModeStatus( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex) /* Physical port index */ -{ - SK_U8 Result; - - /* Get the current mode, which can be full or half duplex */ - Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; - - /* Check if no valid mode could be found (link is down) */ - if (Result < SK_LMODE_STAT_HALF) { - - Result = SK_LMODE_STAT_UNKNOWN; - } - else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { - - /* - * Auto-negotiation was used to bring up the link. Change - * the already found duplex status that it indicates - * auto-negotiation was involved. - */ - if (Result == SK_LMODE_STAT_HALF) { - - Result = SK_LMODE_STAT_AUTOHALF; - } - else if (Result == SK_LMODE_STAT_FULL) { - - Result = SK_LMODE_STAT_AUTOFULL; - } - } - - return (Result); -} - -/***************************************************************************** - * - * GetVpdKeyArr - Obtain an array of VPD keys - * - * Description: - * Read the VPD keys and build an array of VPD keys, which are - * easy to access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int GetVpdKeyArr( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -char *pKeyArr, /* Ptr KeyArray */ -unsigned int KeyArrLen, /* Length of array in bytes */ -unsigned int *pKeyNo) /* Number of keys */ -{ - unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE; - char BufKeys[SK_PNMI_VPD_BUFSIZE]; - unsigned int StartOffset; - unsigned int Offset; - int Index; - int Ret; - - - SK_MEMSET(pKeyArr, 0, KeyArrLen); - - /* - * Get VPD key list - */ - Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen, - (int *)pKeyNo); - if (Ret > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, - SK_PNMI_ERR014MSG); - - return (SK_PNMI_ERR_GENERAL); - } - /* If no keys are available return now */ - if (*pKeyNo == 0 || BufKeysLen == 0) { - - return (SK_PNMI_ERR_OK); - } - /* - * If the key list is too long for us trunc it and give a - * errorlog notification. This case should not happen because - * the maximum number of keys is limited due to RAM limitations - */ - if (*pKeyNo > SK_PNMI_VPD_ENTRIES) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, - SK_PNMI_ERR015MSG); - - *pKeyNo = SK_PNMI_VPD_ENTRIES; - } - - /* - * Now build an array of fixed string length size and copy - * the keys together. - */ - for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen; - Offset ++) { - - if (BufKeys[Offset] != 0) { - - continue; - } - - if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, - SK_PNMI_ERR016MSG); - return (SK_PNMI_ERR_GENERAL); - } - - SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, - &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); - - Index ++; - StartOffset = Offset + 1; - } - - /* Last key not zero terminated? Get it anyway */ - if (StartOffset < Offset) { - - SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, - &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SirqUpdate - Let the SIRQ update its internal values - * - * Description: - * Just to be sure that the SIRQ module holds its internal data - * structures up to date, we send an update event before we make - * any access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int SirqUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC) /* IO context handle */ -{ - SK_EVPARA EventParam; - - - /* Was the module already updated during the current PNMI call? */ - if (pAC->Pnmi.SirqUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an synchronuous update event to the module */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, - SK_PNMI_ERR047MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * RlmtUpdate - Let the RLMT update its internal values - * - * Description: - * Just to be sure that the RLMT module holds its internal data - * structures up to date, we send an update event before we make - * any access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int RlmtUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - SK_EVPARA EventParam; - - - /* Was the module already updated during the current PNMI call? */ - if (pAC->Pnmi.RlmtUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an synchronuous update event to the module */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, - SK_PNMI_ERR048MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacUpdate - Force the XMAC to output the current statistic - * - * Description: - * The XMAC holds its statistic internally. To obtain the current - * values we must send a command so that the statistic data will - * be written to a predefined memory area on the adapter. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int MacUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int FirstMac, /* Index of the first Mac to be updated */ -unsigned int LastMac) /* Index of the last Mac to be updated */ -{ - unsigned int MacIndex; - - /* - * Were the statistics already updated during the - * current PNMI call? - */ - if (pAC->Pnmi.MacUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an update command to all MACs specified */ - for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { - - /* - * 2002-09-13 pweber: Freeze the current SW counters. - * (That should be done as close as - * possible to the update of the - * HW counters) - */ - if (pAC->GIni.GIMacType == SK_MAC_XMAC) { - pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; - } - - /* 2002-09-13 pweber: Update the HW counter */ - if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { - - return (SK_PNMI_ERR_GENERAL); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * GetStatVal - Retrieve an XMAC statistic counter - * - * Description: - * Retrieves the statistic counter of a virtual or physical port. The - * virtual port is identified by the index 0. It consists of all - * currently active ports. To obtain the counter value for this port - * we must add the statistic counter of all active ports. To grant - * continuous counter values for the virtual port even when port - * switches occur we must additionally add a delta value, which was - * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event. - * - * Returns: - * Requested statistic value - */ -PNMI_STATIC SK_U64 GetStatVal( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int LogPortIndex, /* Index of the logical Port to be processed */ -unsigned int StatIndex, /* Index to statistic value */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - unsigned int PhysPortIndex; - unsigned int PhysPortMax; - SK_U64 Val = 0; - - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - - PhysPortIndex = NetIndex; - - Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - else { /* Single Net mode */ - - if (LogPortIndex == 0) { - - PhysPortMax = pAC->GIni.GIMacsFound; - - /* Add counter of all active ports */ - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - } - - /* Correct value because of port switches */ - Val += pAC->Pnmi.VirtualCounterOffset[StatIndex]; - } - else { - /* Get counter value of physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - } - return (Val); -} - -/***************************************************************************** - * - * GetPhysStatVal - Get counter value for physical port - * - * Description: - * Builds a 64bit counter value. Except for the octet counters - * the lower 32bit are counted in hardware and the upper 32bit - * in software by monitoring counter overflow interrupts in the - * event handler. To grant continous counter values during XMAC - * resets (caused by a workaround) we must add a delta value. - * The delta was calculated in the event handler when a - * SK_PNMI_EVT_XMAC_RESET was received. - * - * Returns: - * Counter value - */ -PNMI_STATIC SK_U64 GetPhysStatVal( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ -unsigned int StatIndex) /* Index to statistic value */ -{ - SK_U64 Val = 0; - SK_U32 LowVal = 0; - SK_U32 HighVal = 0; - SK_U16 Word; - int MacType; - unsigned int HelpIndex; - SK_GEPORT *pPrt; - - SK_PNMI_PORT *pPnmiPrt; - SK_GEMACFUNC *pFnMac; - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - MacType = pAC->GIni.GIMacType; - - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; - } - else { - pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; - } - - pFnMac = &pAC->GIni.GIFunc; - - switch (StatIndex) { - case SK_PNMI_HTX: - if (MacType == SK_MAC_GMAC) { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg, - &LowVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX: - if (MacType == SK_MAC_GMAC) { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg, - &LowVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_OCTET: - case SK_PNMI_HRX_OCTET: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &HighVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex + 1][MacType].Reg, - &LowVal); - break; - - case SK_PNMI_HTX_BURST: - case SK_PNMI_HTX_EXCESS_DEF: - case SK_PNMI_HTX_CARRIER: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_MACC: - /* GMAC only supports PAUSE MAC control frames */ - if (MacType == SK_MAC_GMAC) { - HelpIndex = SK_PNMI_HTX_PMACC; - } - else { - HelpIndex = StatIndex; - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[HelpIndex][MacType].Reg, - &LowVal); - - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_COL: - case SK_PNMI_HRX_UNDERSIZE: - /* Not supported by XMAC */ - if (MacType == SK_MAC_XMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_DEFFERAL: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - /* - * XMAC counts frames with deferred transmission - * even in full-duplex mode. - * - * In full-duplex mode the counter remains constant! - */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || - (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) { - - LowVal = 0; - HighVal = 0; - } - else { - /* Otherwise get contents of hardware register */ - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - break; - - case SK_PNMI_HRX_BADOCTET: - /* Not supported by XMAC */ - if (MacType == SK_MAC_XMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &HighVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex + 1][MacType].Reg, - &LowVal); - break; - - case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HRX_OCTETLOW: - case SK_PNMI_HRX_BADOCTETLOW: - return (Val); - - case SK_PNMI_HRX_LONGFRAMES: - /* For XMAC the SW counter is managed by PNMI */ - if (MacType == SK_MAC_XMAC) { - return (pPnmiPrt->StatRxLongFrameCts); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX_TOO_LONG: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - - if (MacType == SK_MAC_GMAC) { - /* For GMAC the SW counter is additionally managed by PNMI */ - Val += pPnmiPrt->StatRxFrameTooLongCts; - } - else { - /* - * Frames longer than IEEE 802.3 frame max size are counted - * by XMAC in frame_too_long counter even reception of long - * frames was enabled and the frame was correct. - * So correct the value by subtracting RxLongFrame counter. - */ - Val -= pPnmiPrt->StatRxLongFrameCts; - } - - LowVal = (SK_U32)Val; - HighVal = (SK_U32)(Val >> 32); - break; - - case SK_PNMI_HRX_SHORTS: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - /* GM_RXE_FRAG?? */ - return (Val); - } - - /* - * XMAC counts short frame errors even if link down (#10620) - * - * If link-down the counter remains constant - */ - if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { - - /* Otherwise get incremental difference */ - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - Val -= pPnmiPrt->RxShortZeroMark; - - LowVal = (SK_U32)Val; - HighVal = (SK_U32)(Val >> 32); - } - break; - - case SK_PNMI_HRX_MACC: - case SK_PNMI_HRX_MACC_UNKWN: - case SK_PNMI_HRX_BURST: - case SK_PNMI_HRX_MISSED: - case SK_PNMI_HRX_FRAMING: - case SK_PNMI_HRX_CARRIER: - case SK_PNMI_HRX_IRLENGTH: - case SK_PNMI_HRX_SYMBOL: - case SK_PNMI_HRX_CEXT: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX_PMACC_ERR: - /* For GMAC the SW counter is managed by PNMI */ - if (MacType == SK_MAC_GMAC) { - return (pPnmiPrt->StatRxPMaccErr); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - /* SW counter managed by PNMI */ - case SK_PNMI_HTX_SYNC: - LowVal = (SK_U32)pPnmiPrt->StatSyncCts; - HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); - break; - - /* SW counter managed by PNMI */ - case SK_PNMI_HTX_SYNC_OCTET: - LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; - HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); - break; - - case SK_PNMI_HRX_FCS: - /* - * Broadcom filters FCS errors and counts it in - * Receive Error Counter register - */ - if (pPrt->PhyType == SK_PHY_BCOM) { - /* do not read while not initialized (PHY_READ hangs!)*/ - if (pPrt->PState != SK_PRT_RESET) { - SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); - - LowVal = Word; - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - break; - - default: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - } - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - - /* Correct value because of possible XMAC reset. XMAC Errata #2 */ - Val += pPnmiPrt->CounterOffset[StatIndex]; - - return (Val); -} - -/***************************************************************************** - * - * ResetCounter - Set all counters and timestamps to zero - * - * Description: - * Notifies other common modules which store statistic data to - * reset their counters and finally reset our own counters. - * - * Returns: - * Nothing - */ -PNMI_STATIC void ResetCounter( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 NetIndex) -{ - unsigned int PhysPortIndex; - SK_EVPARA EventParam; - - - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - - /* Notify sensor module */ - SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam); - - /* Notify RLMT module */ - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam); - EventParam.Para32[1] = 0; - - /* Notify SIRQ module */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam); - - /* Notify CSUM module */ -#ifdef SK_USE_CSUM - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, - EventParam); -#endif /* SK_USE_CSUM */ - - /* Clear XMAC statistic */ - for (PhysPortIndex = 0; PhysPortIndex < - (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { - - (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex); - - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, - 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - CounterOffset, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].CounterOffset)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts, - 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatSyncOctetsCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxLongFrameCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxFrameTooLongCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxPMaccErr)); - } - - /* - * Clear local statistics - */ - SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0, - sizeof(pAC->Pnmi.VirtualCounterOffset)); - pAC->Pnmi.RlmtChangeCts = 0; - pAC->Pnmi.RlmtChangeTime = 0; - SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0, - sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue)); - pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0; - pAC->Pnmi.RlmtChangeEstimate.Estimate = 0; - pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0; - pAC->Pnmi.Port[NetIndex].TxRetryCts = 0; - pAC->Pnmi.Port[NetIndex].RxIntrCts = 0; - pAC->Pnmi.Port[NetIndex].TxIntrCts = 0; - pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0; - pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0; - pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0; - pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0; - pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0; - pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0; -} - -/***************************************************************************** - * - * GetTrapEntry - Get an entry in the trap buffer - * - * Description: - * The trap buffer stores various events. A user application somehow - * gets notified that an event occured and retrieves the trap buffer - * contens (or simply polls the buffer). The buffer is organized as - * a ring which stores the newest traps at the beginning. The oldest - * traps are overwritten by the newest ones. Each trap entry has a - * unique number, so that applications may detect new trap entries. - * - * Returns: - * A pointer to the trap entry - */ -PNMI_STATIC char* GetTrapEntry( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* SNMP ID of the trap */ -unsigned int Size) /* Space needed for trap entry */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int BufFree = pAC->Pnmi.TrapBufFree; - unsigned int Beg = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - int Wrap; - unsigned int NeededSpace; - unsigned int EntrySize; - SK_U32 Val32; - SK_U64 Val64; - - - /* Last byte of entry will get a copy of the entry length */ - Size ++; - - /* - * Calculate needed buffer space */ - if (Beg >= Size) { - - NeededSpace = Size; - Wrap = SK_FALSE; - } - else { - NeededSpace = Beg + Size; - Wrap = SK_TRUE; - } - - /* - * Check if enough buffer space is provided. Otherwise - * free some entries. Leave one byte space between begin - * and end of buffer to make it possible to detect whether - * the buffer is full or empty - */ - while (BufFree < NeededSpace + 1) { - - if (End == 0) { - - End = SK_PNMI_TRAP_QUEUE_LEN; - } - - EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1); - BufFree += EntrySize; - End -= EntrySize; -#ifdef DEBUG - SK_MEMSET(pBuf + End, (char)(-1), EntrySize); -#endif /* DEBUG */ - if (End == BufPad) { -#ifdef DEBUG - SK_MEMSET(pBuf, (char)(-1), End); -#endif /* DEBUG */ - BufFree += End; - End = 0; - BufPad = 0; - } - } - - /* - * Insert new entry as first entry. Newest entries are - * stored at the beginning of the queue. - */ - if (Wrap) { - - BufPad = Beg; - Beg = SK_PNMI_TRAP_QUEUE_LEN - Size; - } - else { - Beg = Beg - Size; - } - BufFree -= NeededSpace; - - /* Save the current offsets */ - pAC->Pnmi.TrapQueueBeg = Beg; - pAC->Pnmi.TrapQueueEnd = End; - pAC->Pnmi.TrapBufPad = BufPad; - pAC->Pnmi.TrapBufFree = BufFree; - - /* Initialize the trap entry */ - *(pBuf + Beg + Size - 1) = (char)Size; - *(pBuf + Beg) = (char)Size; - Val32 = (pAC->Pnmi.TrapUnique) ++; - SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32); - SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId); - Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64); - - return (pBuf + Beg); -} - -/***************************************************************************** - * - * CopyTrapQueue - Copies the trap buffer for the TRAP OID - * - * Description: - * On a query of the TRAP OID the trap buffer contents will be - * copied continuously to the request buffer, which must be large - * enough. No length check is performed. - * - * Returns: - * Nothing - */ -PNMI_STATIC void CopyTrapQueue( -SK_AC *pAC, /* Pointer to adapter context */ -char *pDstBuf) /* Buffer to which the queued traps will be copied */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int Trap = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - unsigned int Len; - unsigned int DstOff = 0; - - - while (Trap != End) { - - Len = (unsigned int)*(pBuf + Trap); - - /* - * Last byte containing a copy of the length will - * not be copied. - */ - *(pDstBuf + DstOff) = (char)(Len - 1); - SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2); - DstOff += Len - 1; - - Trap += Len; - if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { - - Trap = BufPad; - } - } -} - -/***************************************************************************** - * - * GetTrapQueueLen - Get the length of the trap buffer - * - * Description: - * Evaluates the number of currently stored traps and the needed - * buffer size to retrieve them. - * - * Returns: - * Nothing - */ -PNMI_STATIC void GetTrapQueueLen( -SK_AC *pAC, /* Pointer to adapter context */ -unsigned int *pLen, /* Length in Bytes of all queued traps */ -unsigned int *pEntries) /* Returns number of trapes stored in queue */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int Trap = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - unsigned int Len; - unsigned int Entries = 0; - unsigned int TotalLen = 0; - - - while (Trap != End) { - - Len = (unsigned int)*(pBuf + Trap); - TotalLen += Len - 1; - Entries ++; - - Trap += Len; - if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { - - Trap = BufPad; - } - } - - *pEntries = Entries; - *pLen = TotalLen; -} - -/***************************************************************************** - * - * QueueSimpleTrap - Store a simple trap to the trap buffer - * - * Description: - * A simple trap is a trap with now additional data. It consists - * simply of a trap code. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueSimpleTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId) /* Type of sensor trap */ -{ - GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN); -} - -/***************************************************************************** - * - * QueueSensorTrap - Stores a sensor trap in the trap buffer - * - * Description: - * Gets an entry in the trap buffer and fills it with sensor related - * data. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueSensorTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* Type of sensor trap */ -unsigned int SensorIndex) /* Index of sensor which caused the trap */ -{ - char *pBuf; - unsigned int Offset; - unsigned int DescrLen; - SK_U32 Val32; - - - /* Get trap buffer entry */ - DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc); - pBuf = GetTrapEntry(pAC, TrapId, - SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen); - Offset = SK_PNMI_TRAP_SIMPLE_LEN; - - /* Store additionally sensor trap related data */ - Val32 = OID_SKGE_SENSOR_INDEX; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 4; - Val32 = (SK_U32)SensorIndex; - SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); - Offset += 9; - - Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = (char)DescrLen; - SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc, - DescrLen); - Offset += DescrLen + 5; - - Val32 = OID_SKGE_SENSOR_TYPE; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 1; - *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType; - Offset += 6; - - Val32 = OID_SKGE_SENSOR_VALUE; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 4; - Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue; - SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); -} - -/***************************************************************************** - * - * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueRlmtNewMacTrap( -SK_AC *pAC, /* Pointer to adapter context */ -unsigned int ActiveMac) /* Index (0..n) of the currently active port */ -{ - char *pBuf; - SK_U32 Val32; - - - pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, - SK_PNMI_TRAP_RLMT_CHANGE_LEN); - - Val32 = OID_SKGE_RLMT_PORT_ACTIVE; - SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac; -} - -/***************************************************************************** - * - * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueRlmtPortTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* Type of RLMT port trap */ -unsigned int PortIndex) /* Index of the port, which changed its state */ -{ - char *pBuf; - SK_U32 Val32; - - - pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); - - Val32 = OID_SKGE_RLMT_PORT_INDEX; - SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex; -} - -/***************************************************************************** - * - * CopyMac - Copies a MAC address - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void CopyMac( -char *pDst, /* Pointer to destination buffer */ -SK_MAC_ADDR *pMac) /* Pointer of Source */ -{ - int i; - - - for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) { - - *(pDst + i) = pMac->a[i]; - } -} - -#ifdef SK_POWER_MGMT -/***************************************************************************** - * - * PowerManagement - OID handler function of PowerManagement OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ - -PNMI_STATIC int PowerManagement( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - - /* Check length */ - switch (Id) { - - case OID_PNP_CAPABILITIES: - if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { - - *pLen = sizeof(SK_PNP_CAPABILITIES); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_SET_POWER: - case OID_PNP_QUERY_POWER: - if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) - { - *pLen = sizeof(SK_DEVICE_POWER_STATE); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { - - *pLen = sizeof(SK_PM_PACKET_PATTERN); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_ENABLE_WAKE_UP: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - } - - /* - * Perform action - */ - if (Action == SK_PNMI_GET) { - - /* - * Get value - */ - switch (Id) { - - case OID_PNP_CAPABILITIES: - RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_QUERY_POWER: - /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests - the miniport to indicate whether it can transition its NIC - to the low-power state. - A miniport driver must always return NDIS_STATUS_SUCCESS - to a query of OID_PNP_QUERY_POWER. */ - *pLen = sizeof(SK_DEVICE_POWER_STATE); - RetCode = SK_PNMI_ERR_OK; - break; - - /* NDIS handles these OIDs as write-only. - * So in case of get action the buffer with written length = 0 - * is returned - */ - case OID_PNP_SET_POWER: - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - *pLen = 0; - RetCode = SK_PNMI_ERR_NOT_SUPPORTED; - break; - - case OID_PNP_ENABLE_WAKE_UP: - RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen); - break; - - default: - RetCode = SK_PNMI_ERR_GENERAL; - break; - } - - return (RetCode); - } - - - /* - * Perform preset or set - */ - - /* POWER module does not support PRESET action */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - switch (Id) { - case OID_PNP_SET_POWER: - RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_ADD_WAKE_UP_PATTERN: - RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_ENABLE_WAKE_UP: - RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen); - break; - - default: - RetCode = SK_PNMI_ERR_READ_ONLY; - } - - return (RetCode); -} -#endif /* SK_POWER_MGMT */ - -#ifdef SK_DIAG_SUPPORT -/***************************************************************************** - * - * DiagActions - OID handler function of Diagnostic driver - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ - -PNMI_STATIC int DiagActions( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - - SK_U32 DiagStatus; - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - - /* - * Check instance. We only handle single instance variables. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check length. - */ - switch (Id) { - - case OID_SKGE_DIAG_MODE: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG); - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Perform action. */ - - /* GET value. */ - if (Action == SK_PNMI_GET) { - - switch (Id) { - - case OID_SKGE_DIAG_MODE: - DiagStatus = pAC->Pnmi.DiagAttached; - SK_PNMI_STORE_U32(pBuf, DiagStatus); - *pLen = sizeof(SK_U32); - RetCode = SK_PNMI_ERR_OK; - break; - - default: - *pLen = 0; - RetCode = SK_PNMI_ERR_GENERAL; - break; - } - return (RetCode); - } - - /* From here SET or PRESET value. */ - - /* PRESET value is not supported. */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - /* SET value. */ - switch (Id) { - case OID_SKGE_DIAG_MODE: - - /* Handle the SET. */ - switch (*pBuf) { - - /* Attach the DIAG to this adapter. */ - case SK_DIAG_ATTACHED: - /* Check if we come from running */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { - - RetCode = SkDrvLeaveDiagMode(pAC); - - } - else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { - - RetCode = SK_PNMI_ERR_OK; - } - - else { - - RetCode = SK_PNMI_ERR_GENERAL; - - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; - } - break; - - /* Enter the DIAG mode in the driver. */ - case SK_DIAG_RUNNING: - RetCode = SK_PNMI_ERR_OK; - - /* - * If DiagAttached is set, we can tell the driver - * to enter the DIAG mode. - */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { - /* If DiagMode is not active, we can enter it. */ - if (!pAC->DiagModeActive) { - - RetCode = SkDrvEnterDiagMode(pAC); - } - else { - - RetCode = SK_PNMI_ERR_GENERAL; - } - } - else { - - RetCode = SK_PNMI_ERR_GENERAL; - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; - } - break; - - case SK_DIAG_IDLE: - /* Check if we come from running */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { - - RetCode = SkDrvLeaveDiagMode(pAC); - - } - else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { - - RetCode = SK_PNMI_ERR_OK; - } - - else { - - RetCode = SK_PNMI_ERR_GENERAL; - - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; - } - break; - - default: - RetCode = SK_PNMI_ERR_BAD_VALUE; - break; - } - break; - - default: - RetCode = SK_PNMI_ERR_GENERAL; - } - - if (RetCode == SK_PNMI_ERR_OK) { - *pLen = sizeof(SK_U32); - } - else { - - *pLen = 0; - } - return (RetCode); -} -#endif /* SK_DIAG_SUPPORT */ - -/***************************************************************************** - * - * Vct - OID handler function of OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was performed successfully. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter). - * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. - * - */ - -PNMI_STATIC int Vct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctBackupData; - SK_U32 LogPortMax; - SK_U32 PhysPortMax; - SK_U32 PhysPortIndex; - SK_U32 Limit; - SK_U32 Offset; - SK_BOOL Link; - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - int i; - SK_EVPARA Para; - SK_U32 CableLength; - - /* - * Calculate the port indexes from the instance. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - /* Dual net mode? */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - LogPortMax--; - } - - if ((Instance != (SK_U32) (-1))) { - /* Check instance range. */ - if ((Instance < 2) || (Instance > LogPortMax)) { - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - } - else { - PhysPortIndex = Instance - 2; - } - Limit = PhysPortIndex + 1; - } - else { - /* - * Instance == (SK_U32) (-1), get all Instances of that OID. - * - * Not implemented yet. May be used in future releases. - */ - PhysPortIndex = 0; - Limit = PhysPortMax; - } - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - if (pPrt->PHWLinkUp) { - Link = SK_TRUE; - } - else { - Link = SK_FALSE; - } - - /* Check MAC type */ - if (pPrt->PhyType != SK_PHY_MARV_COPPER) { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Initialize backup data pointer. */ - pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - - /* Check action type */ - if (Action == SK_PNMI_GET) { - /* Check length */ - switch (Id) { - - case OID_SKGE_VCT_GET: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_VCT_STATUS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Get value */ - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex++) { - switch (Id) { - - case OID_SKGE_VCT_GET: - if ((Link == SK_FALSE) && - (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 0) { - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] |= - (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); - - /* Copy results for later use to PNMI struct. */ - for (i = 0; i < 4; i++) { - if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { - if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) { - pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; - } - } - if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) { - CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); - } - else { - CableLength = 0; - } - pVctBackupData->PMdiPairLen[i] = CableLength; - pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; - } - - Para.Para32[0] = PhysPortIndex; - Para.Para32[1] = -1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); - SkEventDispatcher(pAC, IoC); - } - else { - ; /* VCT test is running. */ - } - } - - /* Get all results. */ - CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); - Offset += sizeof(SK_U8); - *(pBuf + Offset) = pPrt->PCableLen; - Offset += sizeof(SK_U8); - for (i = 0; i < 4; i++) { - SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]); - Offset += sizeof(SK_U32); - } - for (i = 0; i < 4; i++) { - *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i]; - Offset += sizeof(SK_U8); - } - - RetCode = SK_PNMI_ERR_OK; - break; - - case OID_SKGE_VCT_STATUS: - CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); - Offset += sizeof(SK_U8); - RetCode = SK_PNMI_ERR_OK; - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } /* for */ - *pLen = Offset; - return (RetCode); - - } /* if SK_PNMI_GET */ - - /* - * From here SET or PRESET action. Check if the passed - * buffer length is plausible. - */ - - /* Check length */ - switch (Id) { - case OID_SKGE_VCT_SET: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform preset or set. - */ - - /* VCT does not support PRESET action. */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex++) { - switch (Id) { - case OID_SKGE_VCT_SET: /* Start VCT test. */ - if (Link == SK_FALSE) { - SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); - - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); - if (RetCode == 0) { /* RetCode: 0 => Start! */ - pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA; - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK; - - /* - * Start VCT timer counter. - */ - SK_MEMSET((char *) &Para, 0, sizeof(Para)); - Para.Para32[0] = PhysPortIndex; - Para.Para32[1] = -1; - SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, - 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - else { /* RetCode: 2 => Running! */ - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - } - else { /* RetCode: 4 => Link! */ - RetCode = 4; - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - Offset += sizeof(SK_U32); - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } /* for */ - *pLen = Offset; - return (RetCode); - -} /* Vct */ - - -PNMI_STATIC void CheckVctStatus( -SK_AC *pAC, -SK_IOC IoC, -char *pBuf, -SK_U32 Offset, -SK_U32 PhysPortIndex) -{ - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctData; - SK_U32 RetCode; - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - pVctData = (SK_PNMI_VCT *) (pBuf + Offset); - pVctData->VctStatus = SK_PNMI_VCT_NONE; - - if (!pPrt->PHWLinkUp) { - - /* Was a VCT test ever made before? */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { - if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) { - pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; - } - else { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; - } - } - - /* Check VCT test status. */ - RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 2) { /* VCT test is running. */ - pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; - } - else { /* VCT data was copied to pAC here. Check PENDING state. */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; - } - } - - if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ - pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; - } - } - else { - - /* Was a VCT test ever made before? */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { - pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; - pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; - } - - /* DSP only valid in 100/1000 modes. */ - if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed != - SK_LSPEED_STAT_10MBPS) { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; - } - } -} /* CheckVctStatus */ - - -/***************************************************************************** - * - * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed - * PNMI function depending on the subcommand and - * returns all data belonging to the complete database - * or OID request. - * - * Description: - * Looks up the requested subcommand, calls the corresponding handler - * function and passes all required parameters to it. - * The function is called by the driver. It is needed to handle the new - * generic PNMI IOCTL. This IOCTL is given to the driver and contains both - * the OID and a subcommand to decide what kind of request has to be done. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiGenIoctl( -SK_AC *pAC, /* Pointer to adapter context struct */ -SK_IOC IoC, /* I/O context */ -void *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ -SK_I32 Mode; /* Store value of subcommand. */ -SK_U32 Oid; /* Store value of OID. */ -int ReturnCode; /* Store return value to show status of PNMI action. */ -int HeaderLength; /* Length of desired action plus OID. */ - - ReturnCode = SK_PNMI_ERR_GENERAL; - - SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); - SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32)); - HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); - *pLen = *pLen - HeaderLength; - SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen); - - switch(Mode) { - case SK_GET_SINGLE_VAR: - ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_PRESET_SINGLE_VAR: - ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_SET_SINGLE_VAR: - ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_GET_FULL_MIB: - ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - case SK_PRESET_FULL_MIB: - ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - case SK_SET_FULL_MIB: - ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - default: - break; - } - - return (ReturnCode); - -} /* SkGeIocGen */ diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c deleted file mode 100644 index 3e7aa49afd00..000000000000 --- a/drivers/net/sk98lin/skgesirq.c +++ /dev/null @@ -1,2229 +0,0 @@ -/****************************************************************************** - * - * Name: skgesirq.c - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.92 $ - * Date: $Date: 2003/09/16 14:37:07 $ - * Purpose: Special IRQ module - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * Special Interrupt handler - * - * The following abstract should show how this module is included - * in the driver path: - * - * In the ISR of the driver the bits for frame transmission complete and - * for receive complete are checked and handled by the driver itself. - * The bits of the slow path mask are checked after that and then the - * entry into the so-called "slow path" is prepared. It is an implementors - * decision whether this is executed directly or just scheduled by - * disabling the mask. In the interrupt service routine some events may be - * generated, so it would be a good idea to call the EventDispatcher - * right after this ISR. - * - * The Interrupt source register of the adapter is NOT read by this module. - * SO if the drivers implementor needs a while loop around the - * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for - * each loop entered. - * - * However, the MAC Interrupt status registers are read in a while loop. - * - */ - -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell."; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#ifndef SK_SLIM -#include "h/skgepnmi.h" /* PNMI Definitions */ -#include "h/skrlmt.h" /* RLMT Definitions */ -#endif -#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */ - -/* local function prototypes */ -#ifdef GENESIS -static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); -static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16); -#endif /* GENESIS */ -#ifdef YUKON -static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16); -#endif /* YUKON */ -#ifdef OTHER_PHY -static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL); -static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16); -#endif /* OTHER_PHY */ - -#ifdef GENESIS -/* - * array of Rx counter from XMAC which are checked - * in AutoSense mode to check whether a link is not able to auto-negotiate. - */ -static const SK_U16 SkGeRxRegs[]= { - XM_RXF_64B, - XM_RXF_127B, - XM_RXF_255B, - XM_RXF_511B, - XM_RXF_1023B, - XM_RXF_MAX_SZ -} ; -#endif /* GENESIS */ - -#ifdef __C2MAN__ -/* - * Special IRQ function - * - * General Description: - * - */ -intro() -{} -#endif - -/****************************************************************************** - * - * SkHWInitDefSense() - Default Autosensing mode initialization - * - * Description: sets the PLinkMode for HWInit - * - * Returns: N/A - */ -static void SkHWInitDefSense( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - pPrt = &pAC->GIni.GP[Port]; - - pPrt->PAutoNegTimeOut = 0; - - if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { - pPrt->PLinkMode = pPrt->PLinkModeConf; - return; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("AutoSensing: First mode %d on Port %d\n", - (int)SK_LMODE_AUTOFULL, Port)); - - pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL; - - return; -} /* SkHWInitDefSense */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkHWSenseGetNext() - Get Next Autosensing Mode - * - * Description: gets the appropriate next mode - * - * Note: - * - */ -static SK_U8 SkHWSenseGetNext( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - pPrt = &pAC->GIni.GP[Port]; - - pPrt->PAutoNegTimeOut = 0; - - if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { - /* Leave all as configured */ - return(pPrt->PLinkModeConf); - } - - if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { - /* Return next mode AUTOBOTH */ - return ((SK_U8)SK_LMODE_AUTOBOTH); - } - - /* Return default autofull */ - return ((SK_U8)SK_LMODE_AUTOFULL); -} /* SkHWSenseGetNext */ - - -/****************************************************************************** - * - * SkHWSenseSetNext() - Autosensing Set next mode - * - * Description: sets the appropriate next mode - * - * Returns: N/A - */ -static void SkHWSenseSetNext( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U8 NewMode) /* New Mode to be written in sense mode */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - pPrt = &pAC->GIni.GP[Port]; - - pPrt->PAutoNegTimeOut = 0; - - if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { - return; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("AutoSensing: next mode %d on Port %d\n", - (int)NewMode, Port)); - - pPrt->PLinkMode = NewMode; - - return; -} /* SkHWSenseSetNext */ -#endif /* GENESIS */ - - -/****************************************************************************** - * - * SkHWLinkDown() - Link Down handling - * - * Description: handles the hardware link down signal - * - * Returns: N/A - */ -void SkHWLinkDown( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - pPrt = &pAC->GIni.GP[Port]; - - /* Disable all MAC interrupts */ - SkMacIrqDisable(pAC, IoC, Port); - - /* Disable Receiver and Transmitter */ - SkMacRxTxDisable(pAC, IoC, Port); - - /* Init default sense mode */ - SkHWInitDefSense(pAC, IoC, Port); - - if (pPrt->PHWLinkUp == SK_FALSE) { - return; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link down Port %d\n", Port)); - - /* Set Link to DOWN */ - pPrt->PHWLinkUp = SK_FALSE; - - /* Reset Port stati */ - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED; - - /* Re-init Phy especially when the AutoSense default is set now */ - SkMacInitPhy(pAC, IoC, Port, SK_FALSE); - - /* GP0: used for workaround of Rev. C Errata 2 */ - - /* Do NOT signal to RLMT */ - - /* Do NOT start the timer here */ -} /* SkHWLinkDown */ - - -/****************************************************************************** - * - * SkHWLinkUp() - Link Up handling - * - * Description: handles the hardware link up signal - * - * Returns: N/A - */ -static void SkHWLinkUp( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PHWLinkUp) { - /* We do NOT need to proceed on active link */ - return; - } - - pPrt->PHWLinkUp = SK_TRUE; - pPrt->PAutoNegFail = SK_FALSE; - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - - if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && - pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && - pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { - /* Link is up and no Auto-negotiation should be done */ - - /* Link speed should be the configured one */ - switch (pPrt->PLinkSpeed) { - case SK_LSPEED_AUTO: - /* default is 1000 Mbps */ - case SK_LSPEED_1000MBPS: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; - break; - case SK_LSPEED_100MBPS: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; - break; - case SK_LSPEED_10MBPS: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; - break; - } - - /* Set Link Mode Status */ - if (pPrt->PLinkMode == SK_LMODE_FULL) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL; - } - else { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; - } - - /* No flow control without auto-negotiation */ - pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; - - /* enable Rx/Tx */ - (void)SkMacRxTxEnable(pAC, IoC, Port); - } -} /* SkHWLinkUp */ - - -/****************************************************************************** - * - * SkMacParity() - MAC parity workaround - * - * Description: handles MAC parity errors correctly - * - * Returns: N/A - */ -static void SkMacParity( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index of the port failed */ -{ - SK_EVPARA Para; - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U32 TxMax; /* Tx Max Size Counter */ - - pPrt = &pAC->GIni.GP[Port]; - - /* Clear IRQ Tx Parity Error */ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ - SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), - (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON && - pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); - } -#endif /* YUKON */ - - if (pPrt->PCheckPar) { - - if (Port == MAC_1) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG); - } - Para.Para64 = Port; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - - Para.Para32[0] = Port; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - - return; - } - - /* Check whether frames with a size of 1k were sent */ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* Snap statistic counters */ - (void)SkXmUpdateStats(pAC, IoC, Port); - - (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax); - } -#endif /* YUKON */ - - if (TxMax > 0) { - /* From now on check the parity */ - pPrt->PCheckPar = SK_TRUE; - } -} /* SkMacParity */ - - -/****************************************************************************** - * - * SkGeHwErr() - Hardware Error service routine - * - * Description: handles all HW Error interrupts - * - * Returns: N/A - */ -static void SkGeHwErr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -SK_U32 HwStatus) /* Interrupt status word */ -{ - SK_EVPARA Para; - SK_U16 Word; - - if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) { - /* PCI Errors occured */ - if ((HwStatus & IS_IRQ_STAT) != 0) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG); - } - - /* Reset all bits in the PCI STATUS register */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - Para.Para64 = 0; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); - } - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - if ((HwStatus & IS_NO_STAT_M1) != 0) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT); - } - - if ((HwStatus & IS_NO_STAT_M2) != 0) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT); - } - - if ((HwStatus & IS_NO_TIST_M1) != 0) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST); - } - - if ((HwStatus & IS_NO_TIST_M2) != 0) { - /* Ignore it */ - /* This situation is also indicated in the descriptor */ - SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST); - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* This is necessary only for Rx timing measurements */ - if ((HwStatus & IS_IRQ_TIST_OV) != 0) { - /* increment Time Stamp Timer counter (high) */ - pAC->GIni.GITimeStampCnt++; - - /* Clear Time Stamp Timer IRQ */ - SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ); - } - - if ((HwStatus & IS_IRQ_SENSOR) != 0) { - /* no sensors on 32-bit Yukon */ - if (pAC->GIni.GIYukon32Bit) { - /* disable HW Error IRQ */ - pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; - } - } - } -#endif /* YUKON */ - - if ((HwStatus & IS_RAM_RD_PAR) != 0) { - SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR); - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG); - Para.Para64 = 0; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); - } - - if ((HwStatus & IS_RAM_WR_PAR) != 0) { - SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR); - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG); - Para.Para64 = 0; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); - } - - if ((HwStatus & IS_M1_PAR_ERR) != 0) { - SkMacParity(pAC, IoC, MAC_1); - } - - if ((HwStatus & IS_M2_PAR_ERR) != 0) { - SkMacParity(pAC, IoC, MAC_2); - } - - if ((HwStatus & IS_R1_PAR_ERR) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P); - - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); - Para.Para64 = MAC_1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - - Para.Para32[0] = MAC_1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((HwStatus & IS_R2_PAR_ERR) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P); - - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); - Para.Para64 = MAC_2; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - - Para.Para32[0] = MAC_2; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } -} /* SkGeHwErr */ - - -/****************************************************************************** - * - * SkGeSirqIsr() - Special Interrupt Service Routine - * - * Description: handles all non data transfer specific interrupts (slow path) - * - * Returns: N/A - */ -void SkGeSirqIsr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -SK_U32 Istatus) /* Interrupt status word */ -{ - SK_EVPARA Para; - SK_U32 RegVal32; /* Read register value */ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U16 PhyInt; - int i; - - if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { - /* read the HW Error Interrupt source */ - SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); - - SkGeHwErr(pAC, IoC, RegVal32); - } - - /* - * Packet Timeout interrupts - */ - /* Check whether MACs are correctly initialized */ - if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) && - pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) { - /* MAC 1 was not initialized but Packet timeout occured */ - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004, - SKERR_SIRQ_E004MSG); - } - - if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) && - pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { - /* MAC 2 was not initialized but Packet timeout occured */ - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005, - SKERR_SIRQ_E005MSG); - } - - if ((Istatus & IS_PA_TO_RX1) != 0) { - /* Means network is filling us up */ - SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002, - SKERR_SIRQ_E002MSG); - SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1); - } - - if ((Istatus & IS_PA_TO_RX2) != 0) { - /* Means network is filling us up */ - SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003, - SKERR_SIRQ_E003MSG); - SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2); - } - - if ((Istatus & IS_PA_TO_TX1) != 0) { - - pPrt = &pAC->GIni.GP[0]; - - /* May be a normal situation in a server with a slow network */ - SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1); - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* - * workaround: if in half duplex mode, check for Tx hangup. - * Read number of TX'ed bytes, wait for 10 ms, then compare - * the number with current value. If nothing changed, we assume - * that Tx is hanging and do a FIFO flush (see event routine). - */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && - !pPrt->HalfDupTimerActive) { - /* - * many more pack. arb. timeouts may come in between, - * we ignore those - */ - pPrt->HalfDupTimerActive = SK_TRUE; - /* Snap statistic counters */ - (void)SkXmUpdateStats(pAC, IoC, 0); - - (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32); - - pPrt->LastOctets = (SK_U64)RegVal32 << 32; - - (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32); - - pPrt->LastOctets += RegVal32; - - Para.Para32[0] = 0; - SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, - SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); - } - } -#endif /* GENESIS */ - } - - if ((Istatus & IS_PA_TO_TX2) != 0) { - - pPrt = &pAC->GIni.GP[1]; - - /* May be a normal situation in a server with a slow network */ - SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* workaround: see above */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && - !pPrt->HalfDupTimerActive) { - pPrt->HalfDupTimerActive = SK_TRUE; - /* Snap statistic counters */ - (void)SkXmUpdateStats(pAC, IoC, 1); - - (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32); - - pPrt->LastOctets = (SK_U64)RegVal32 << 32; - - (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32); - - pPrt->LastOctets += RegVal32; - - Para.Para32[0] = 1; - SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, - SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); - } - } -#endif /* GENESIS */ - } - - /* Check interrupts of the particular queues */ - if ((Istatus & IS_R1_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006, - SKERR_SIRQ_E006MSG); - Para.Para64 = MAC_1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((Istatus & IS_R2_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007, - SKERR_SIRQ_E007MSG); - Para.Para64 = MAC_2; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_2; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((Istatus & IS_XS1_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008, - SKERR_SIRQ_E008MSG); - Para.Para64 = MAC_1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((Istatus & IS_XA1_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009, - SKERR_SIRQ_E009MSG); - Para.Para64 = MAC_1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((Istatus & IS_XS2_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010, - SKERR_SIRQ_E010MSG); - Para.Para64 = MAC_2; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_2; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((Istatus & IS_XA2_C) != 0) { - /* Clear IRQ */ - SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C); - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011, - SKERR_SIRQ_E011MSG); - Para.Para64 = MAC_2; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - Para.Para32[0] = MAC_2; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - /* External reg interrupt */ - if ((Istatus & IS_EXT_REG) != 0) { - /* Test IRQs from PHY */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - - pPrt = &pAC->GIni.GP[i]; - - if (pPrt->PState == SK_PRT_RESET) { - continue; - } - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - switch (pPrt->PhyType) { - - case SK_PHY_XMAC: - break; - - case SK_PHY_BCOM: - SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); - - if ((PhyInt & ~PHY_B_DEF_MSK) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Bcom Int: 0x%04X\n", - i, PhyInt)); - SkPhyIsrBcom(pAC, IoC, i, PhyInt); - } - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); - - if ((PhyInt & PHY_L_DEF_MSK) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Lone Int: %x\n", - i, PhyInt)); - SkPhyIsrLone(pAC, IoC, i, PhyInt); - } - break; -#endif /* OTHER_PHY */ - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* Read PHY Interrupt Status */ - SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); - - if ((PhyInt & PHY_M_DEF_MSK) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Marv Int: 0x%04X\n", - i, PhyInt)); - SkPhyIsrGmac(pAC, IoC, i, PhyInt); - } - } -#endif /* YUKON */ - } - } - - /* I2C Ready interrupt */ - if ((Istatus & IS_I2C_READY) != 0) { -#ifdef SK_SLIM - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); -#else - SkI2cIsr(pAC, IoC); -#endif - } - - /* SW forced interrupt */ - if ((Istatus & IS_IRQ_SW) != 0) { - /* clear the software IRQ */ - SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ); - } - - if ((Istatus & IS_LNK_SYNC_M1) != 0) { - /* - * We do NOT need the Link Sync interrupt, because it shows - * us only a link going down. - */ - /* clear interrupt */ - SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ); - } - - /* Check MAC after link sync counter */ - if ((Istatus & IS_MAC1) != 0) { - /* IRQ from MAC 1 */ - SkMacIrq(pAC, IoC, MAC_1); - } - - if ((Istatus & IS_LNK_SYNC_M2) != 0) { - /* - * We do NOT need the Link Sync interrupt, because it shows - * us only a link going down. - */ - /* clear interrupt */ - SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ); - } - - /* Check MAC after link sync counter */ - if ((Istatus & IS_MAC2) != 0) { - /* IRQ from MAC 2 */ - SkMacIrq(pAC, IoC, MAC_2); - } - - /* Timer interrupt (served last) */ - if ((Istatus & IS_TIMINT) != 0) { - /* check for HW Errors */ - if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { - /* read the HW Error Interrupt source */ - SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); - - SkGeHwErr(pAC, IoC, RegVal32); - } - - SkHwtIsr(pAC, IoC); - } - -} /* SkGeSirqIsr */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2 - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - */ -static int SkGePortCheckShorts( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ -{ - SK_U32 Shorts; /* Short Event Counter */ - SK_U32 CheckShorts; /* Check value for Short Event Counter */ - SK_U64 RxCts; /* Rx Counter (packets on network) */ - SK_U32 RxTmp; /* Rx temp. Counter */ - SK_U32 FcsErrCts; /* FCS Error Counter */ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Rtv; /* Return value */ - int i; - - pPrt = &pAC->GIni.GP[Port]; - - /* Default: no action */ - Rtv = SK_HW_PS_NONE; - - (void)SkXmUpdateStats(pAC, IoC, Port); - - /* Extra precaution: check for short Event counter */ - (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); - - /* - * Read Rx counters (packets seen on the network and not necessarily - * really received. - */ - RxCts = 0; - - for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { - - (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); - - RxCts += (SK_U64)RxTmp; - } - - /* On default: check shorts against zero */ - CheckShorts = 0; - - /* Extra precaution on active links */ - if (pPrt->PHWLinkUp) { - /* Reset Link Restart counter */ - pPrt->PLinkResCt = 0; - pPrt->PAutoNegTOCt = 0; - - /* If link is up check for 2 */ - CheckShorts = 2; - - (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts); - - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN && - (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL)) { - /* - * This is autosensing and we are in the fallback - * manual full/half duplex mode. - */ - if (RxCts == pPrt->PPrevRx) { - /* Nothing received, restart link */ - pPrt->PPrevFcs = FcsErrCts; - pPrt->PPrevShorts = Shorts; - - return(SK_HW_PS_RESTART); - } - else { - pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; - } - } - - if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) || - (!(FcsErrCts - pPrt->PPrevFcs))) { - /* - * Note: The compare with zero above has to be done the way shown, - * otherwise the Linux driver will have a problem. - */ - /* - * We received a bunch of frames or no CRC error occured on the - * network -> ok. - */ - pPrt->PPrevRx = RxCts; - pPrt->PPrevFcs = FcsErrCts; - pPrt->PPrevShorts = Shorts; - - return(SK_HW_PS_NONE); - } - - pPrt->PPrevFcs = FcsErrCts; - } - - - if ((Shorts - pPrt->PPrevShorts) > CheckShorts) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Short Event Count Restart Port %d \n", Port)); - Rtv = SK_HW_PS_RESTART; - } - - pPrt->PPrevShorts = Shorts; - pPrt->PPrevRx = RxCts; - - return(Rtv); -} /* SkGePortCheckShorts */ -#endif /* GENESIS */ - - -/****************************************************************************** - * - * SkGePortCheckUp() - Check if the link is up - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUp( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ - int Rtv; /* Return value */ - - Rtv = SK_HW_PS_NONE; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - switch (pPrt->PhyType) { - - case SK_PHY_XMAC: - Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); - break; - case SK_PHY_BCOM: - Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg); - break; - case SK_PHY_NAT: - Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg); - break; -#endif /* OTHER_PHY */ - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); - } -#endif /* YUKON */ - - return(Rtv); -} /* SkGePortCheckUp */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2 - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUpXmac( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ -SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ -{ - SK_U32 Shorts; /* Short Event Counter */ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Done; - SK_U32 GpReg; /* General Purpose register value */ - SK_U16 Isrc; /* Interrupt source register */ - SK_U16 IsrcSum; /* Interrupt source register sum */ - SK_U16 LpAb; /* Link Partner Ability */ - SK_U16 ResAb; /* Resolved Ability */ - SK_U16 ExtStat; /* Extended Status Register */ - SK_U8 NextMode; /* Next AutoSensing Mode */ - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PHWLinkUp) { - if (pPrt->PhyType != SK_PHY_XMAC) { - return(SK_HW_PS_NONE); - } - else { - return(SkGePortCheckShorts(pAC, IoC, Port)); - } - } - - IsrcSum = pPrt->PIsave; - pPrt->PIsave = 0; - - /* Now wait for each port's link */ - if (pPrt->PLinkBroken) { - /* Link was broken */ - XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); - - if ((GpReg & XM_GP_INP_ASS) == 0) { - /* The Link is in sync */ - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - IsrcSum |= Isrc; - SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); - - if ((Isrc & XM_IS_INP_ASS) == 0) { - /* It has been in sync since last time */ - /* Restart the PORT */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link in sync Restart Port %d\n", Port)); - - (void)SkXmUpdateStats(pAC, IoC, Port); - - /* We now need to reinitialize the PrevShorts counter */ - (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts); - pPrt->PPrevShorts = Shorts; - - pPrt->PLinkBroken = SK_FALSE; - - /* - * Link Restart Workaround: - * it may be possible that the other Link side - * restarts its link as well an we detect - * another LinkBroken. To prevent this - * happening we check for a maximum number - * of consecutive restart. If those happens, - * we do NOT restart the active link and - * check whether the link is now o.k. - */ - pPrt->PLinkResCt++; - - pPrt->PAutoNegTimeOut = 0; - - if (pPrt->PLinkResCt < SK_MAX_LRESTART) { - return(SK_HW_PS_RESTART); - } - - pPrt->PLinkResCt = 0; - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); - } - else { - pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); - - /* Do nothing more if link is broken */ - return(SK_HW_PS_NONE); - } - } - else { - /* Do nothing more if link is broken */ - return(SK_HW_PS_NONE); - } - - } - else { - /* Link was not broken, check if it is */ - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) != 0) { - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) != 0) { - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - IsrcSum |= Isrc; - if ((Isrc & XM_IS_INP_ASS) != 0) { - pPrt->PLinkBroken = SK_TRUE; - /* Re-Init Link partner Autoneg flag */ - pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link broken Port %d\n", Port)); - - /* Cable removed-> reinit sense mode */ - SkHWInitDefSense(pAC, IoC, Port); - - return(SK_HW_PS_RESTART); - } - } - } - else { - SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); - - if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { - return(SK_HW_PS_RESTART); - } - } - } - - /* - * here we usually can check whether the link is in sync and - * auto-negotiation is done. - */ - XM_IN32(IoC, Port, XM_GP_PORT, &GpReg); - XM_IN16(IoC, Port, XM_ISRC, &Isrc); - IsrcSum |= Isrc; - - SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); - - if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { - if ((GpReg & XM_GP_INP_ASS) == 0) { - /* Save Auto-negotiation Done interrupt only if link is in sync */ - pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); - } -#ifdef DEBUG - if ((pPrt->PIsave & XM_IS_AND) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done rescheduled Port %d\n", Port)); - } -#endif /* DEBUG */ - return(SK_HW_PS_NONE); - } - - if (AutoNeg) { - if ((IsrcSum & XM_IS_AND) != 0) { - SkHWLinkUp(pAC, IoC, Port); - Done = SkMacAutoNegDone(pAC, IoC, Port); - if (Done != SK_AND_OK) { - /* Get PHY parameters, for debugging only */ - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", - Port, LpAb, ResAb)); - - /* Try next possible mode */ - NextMode = SkHWSenseGetNext(pAC, IoC, Port); - SkHWLinkDown(pAC, IoC, Port); - if (Done == SK_AND_DUP_CAP) { - /* GoTo next mode */ - SkHWSenseSetNext(pAC, IoC, Port, NextMode); - } - - return(SK_HW_PS_RESTART); - } - /* - * Dummy Read extended status to prevent extra link down/ups - * (clear Page Received bit if set) - */ - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); - - return(SK_HW_PS_LINK); - } - - /* AutoNeg not done, but HW link is up. Check for timeouts */ - pPrt->PAutoNegTimeOut++; - if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { - /* Increase the Timeout counter */ - pPrt->PAutoNegTOCt++; - - /* Timeout occured */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("AutoNeg timeout Port %d\n", Port)); - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { - /* Set Link manually up */ - SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Set manual full duplex Port %d\n", Port)); - } - - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg == SK_LIPA_AUTO && - pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) { - /* - * This is rather complicated. - * we need to check here whether the LIPA_AUTO - * we saw before is false alert. We saw at one - * switch ( SR8800) that on boot time it sends - * just one auto-neg packet and does no further - * auto-negotiation. - * Solution: we restart the autosensing after - * a few timeouts. - */ - pPrt->PAutoNegTOCt = 0; - pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; - SkHWInitDefSense(pAC, IoC, Port); - } - - /* Do the restart */ - return(SK_HW_PS_RESTART); - } - } - else { - /* Link is up and we don't need more */ -#ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("ERROR: Lipa auto detected on port %d\n", Port)); - } -#endif /* DEBUG */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link sync(GP), Port %d\n", Port)); - SkHWLinkUp(pAC, IoC, Port); - - /* - * Link sync (GP) and so assume a good connection. But if not received - * a bunch of frames received in a time slot (maybe broken tx cable) - * the port is restart. - */ - return(SK_HW_PS_LINK); - } - - return(SK_HW_PS_NONE); -} /* SkGePortCheckUpXmac */ - - -/****************************************************************************** - * - * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUpBcom( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ -SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Done; - SK_U16 Isrc; /* Interrupt source register */ - SK_U16 PhyStat; /* Phy Status Register */ - SK_U16 ResAb; /* Master/Slave resolution */ - SK_U16 Ctrl; /* Broadcom control flags */ -#ifdef DEBUG - SK_U16 LpAb; - SK_U16 ExtStat; -#endif /* DEBUG */ - - pPrt = &pAC->GIni.GP[Port]; - - /* Check for No HCD Link events (#10523) */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); - -#ifdef xDEBUG - if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) == - (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { - - SK_U32 Stat1, Stat2, Stat3; - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp1 - Stat: %x, Mask: %x", - (void *)Isrc, - (void *)Stat1); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "Ctrl/Stat: %x, AN Adv/LP: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - } -#endif /* DEBUG */ - - if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { - /* - * Workaround BCom Errata: - * enable and disable loopback mode if "NO HCD" occurs. - */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, - (SK_U16)(Ctrl | PHY_CT_LOOP)); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, - (SK_U16)(Ctrl & ~PHY_CT_LOOP)); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("No HCD Link event, Port %d\n", Port)); -#ifdef xDEBUG - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "No HCD link event, port %d.", - (void *)Port, - (void *)NULL); -#endif /* DEBUG */ - } - - /* Not obsolete: link status bit is latched to 0 and autoclearing! */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); - - if (pPrt->PHWLinkUp) { - return(SK_HW_PS_NONE); - } - -#ifdef xDEBUG - { - SK_U32 Stat1, Stat2, Stat3; - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp1a - Stat: %x, Mask: %x", - (void *)Isrc, - (void *)Stat1); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); - Stat1 = Stat1 << 16 | PhyStat; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "Ctrl/Stat: %x, AN Adv/LP: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); - Stat2 = Stat2 << 16 | ResAb; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - } -#endif /* DEBUG */ - - /* - * Here we usually can check whether the link is in sync and - * auto-negotiation is done. - */ - - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); - - SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); - - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); - - if ((ResAb & PHY_B_1000S_MSF) != 0) { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); - - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - - return(SK_HW_PS_RESTART); - } - - if ((PhyStat & PHY_ST_LSYNC) == 0) { - return(SK_HW_PS_NONE); - } - - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Port %d, ResAb: 0x%04X\n", Port, ResAb)); - - if (AutoNeg) { - if ((PhyStat & PHY_ST_AN_OVER) != 0) { - - SkHWLinkUp(pAC, IoC, Port); - - Done = SkMacAutoNegDone(pAC, IoC, Port); - - if (Done != SK_AND_OK) { -#ifdef DEBUG - /* Get PHY parameters, for debugging only */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", - Port, LpAb, ExtStat)); -#endif /* DEBUG */ - return(SK_HW_PS_RESTART); - } - else { -#ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - - if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp2 - Stat: %x", - (void *)ExtStat, - (void *)NULL); - } -#endif /* DEBUG */ - return(SK_HW_PS_LINK); - } - } - } - else { /* !AutoNeg */ - /* Link is up and we don't need more. */ -#ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("ERROR: Lipa auto detected on port %d\n", Port)); - } -#endif /* DEBUG */ - -#ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - - if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp3 - Stat: %x", - (void *)ExtStat, - (void *)NULL); - } -#endif /* DEBUG */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link sync(GP), Port %d\n", Port)); - SkHWLinkUp(pAC, IoC, Port); - - return(SK_HW_PS_LINK); - } - - return(SK_HW_PS_NONE); -} /* SkGePortCheckUpBcom */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUpGmac( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ -SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Done; - SK_U16 PhyIsrc; /* PHY Interrupt source */ - SK_U16 PhyStat; /* PPY Status */ - SK_U16 PhySpecStat;/* PHY Specific Status */ - SK_U16 ResAb; /* Master/Slave resolution */ - SK_EVPARA Para; -#ifdef DEBUG - SK_U16 Word; /* I/O helper */ -#endif /* DEBUG */ - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PHWLinkUp) { - return(SK_HW_PS_NONE); - } - - /* Read PHY Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); - - /* Read PHY Interrupt Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); - - if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc)); - } - - if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); - } - - SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); - - if ((ResAb & PHY_B_1000S_MSF) != 0) { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); - - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - - return(SK_HW_PS_RESTART); - } - - /* Read PHY Specific Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); - -#ifdef DEBUG - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); - - if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || - (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { - /* Read PHY Next Page Link Partner */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Page Received, NextPage: 0x%04X\n", Word)); - } -#endif /* DEBUG */ - - if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { - return(SK_HW_PS_NONE); - } - - if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 || - (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) { - /* Downshift detected */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG); - - Para.Para64 = Port; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); - } - - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; - - pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); - - if (AutoNeg) { - /* Auto-Negotiation Over ? */ - if ((PhyStat & PHY_ST_AN_OVER) != 0) { - - SkHWLinkUp(pAC, IoC, Port); - - Done = SkMacAutoNegDone(pAC, IoC, Port); - - if (Done != SK_AND_OK) { - return(SK_HW_PS_RESTART); - } - - return(SK_HW_PS_LINK); - } - } - else { /* !AutoNeg */ - /* Link is up and we don't need more */ -#ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("ERROR: Lipa auto detected on port %d\n", Port)); - } -#endif /* DEBUG */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link sync, Port %d\n", Port)); - SkHWLinkUp(pAC, IoC, Port); - - return(SK_HW_PS_LINK); - } - - return(SK_HW_PS_NONE); -} /* SkGePortCheckUpGmac */ -#endif /* YUKON */ - - -#ifdef OTHER_PHY -/****************************************************************************** - * - * SkGePortCheckUpLone() - Check if the link is up on Level One PHY - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUpLone( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ -SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - int Done; - SK_U16 Isrc; /* Interrupt source register */ - SK_U16 LpAb; /* Link Partner Ability */ - SK_U16 ExtStat; /* Extended Status Register */ - SK_U16 PhyStat; /* Phy Status Register */ - SK_U16 StatSum; - SK_U8 NextMode; /* Next AutoSensing Mode */ - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PHWLinkUp) { - return(SK_HW_PS_NONE); - } - - StatSum = pPrt->PIsave; - pPrt->PIsave = 0; - - /* - * here we usually can check whether the link is in sync and - * auto-negotiation is done. - */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat); - StatSum |= PhyStat; - - SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - - if ((PhyStat & PHY_ST_LSYNC) == 0) { - /* Save Auto-negotiation Done bit */ - pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER); -#ifdef DEBUG - if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done rescheduled Port %d\n", Port)); - } -#endif /* DEBUG */ - return(SK_HW_PS_NONE); - } - - if (AutoNeg) { - if ((StatSum & PHY_ST_AN_OVER) != 0) { - SkHWLinkUp(pAC, IoC, Port); - Done = SkMacAutoNegDone(pAC, IoC, Port); - if (Done != SK_AND_OK) { - /* Get PHY parameters, for debugging only */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb); - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", - Port, LpAb, ExtStat)); - - /* Try next possible mode */ - NextMode = SkHWSenseGetNext(pAC, IoC, Port); - SkHWLinkDown(pAC, IoC, Port); - if (Done == SK_AND_DUP_CAP) { - /* GoTo next mode */ - SkHWSenseSetNext(pAC, IoC, Port, NextMode); - } - - return(SK_HW_PS_RESTART); - - } - else { - /* - * Dummy Read interrupt status to prevent - * extra link down/ups - */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); - return(SK_HW_PS_LINK); - } - } - - /* AutoNeg not done, but HW link is up. Check for timeouts */ - pPrt->PAutoNegTimeOut++; - if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { - /* Timeout occured */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("AutoNeg timeout Port %d\n", Port)); - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { - /* Set Link manually up */ - SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Set manual full duplex Port %d\n", Port)); - } - - /* Do the restart */ - return(SK_HW_PS_RESTART); - } - } - else { - /* Link is up and we don't need more */ -#ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("ERROR: Lipa auto detected on port %d\n", Port)); - } -#endif /* DEBUG */ - - /* - * Dummy Read interrupt status to prevent - * extra link down/ups - */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Link sync(GP), Port %d\n", Port)); - SkHWLinkUp(pAC, IoC, Port); - - return(SK_HW_PS_LINK); - } - - return(SK_HW_PS_NONE); -} /* SkGePortCheckUpLone */ - - -/****************************************************************************** - * - * SkGePortCheckUpNat() - Check if the link is up on National PHY - * - * return: - * 0 o.k. nothing needed - * 1 Restart needed on this port - * 2 Link came up - */ -static int SkGePortCheckUpNat( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ -SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ -{ - /* todo: National */ - return(SK_HW_PS_NONE); -} /* SkGePortCheckUpNat */ -#endif /* OTHER_PHY */ - - -/****************************************************************************** - * - * SkGeSirqEvent() - Event Service Routine - * - * Description: - * - * Notes: - */ -int SkGeSirqEvent( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -SK_U32 Event, /* Module specific Event */ -SK_EVPARA Para) /* Event specific Parameter */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U32 Port; - SK_U32 Val32; - int PortStat; - SK_U8 Val8; -#ifdef GENESIS - SK_U64 Octets; -#endif /* GENESIS */ - - Port = Para.Para32[0]; - pPrt = &pAC->GIni.GP[Port]; - - switch (Event) { - case SK_HWEV_WATIM: - if (pPrt->PState == SK_PRT_RESET) { - - PortStat = SK_HW_PS_NONE; - } - else { - /* Check whether port came up */ - PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); - } - - switch (PortStat) { - case SK_HW_PS_RESTART: - if (pPrt->PHWLinkUp) { - /* Set Link to down */ - SkHWLinkDown(pAC, IoC, (int)Port); - - /* - * Signal directly to RLMT to ensure correct - * sequence of SWITCH and RESET event. - */ - SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); - } - - /* Restart needed */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); - break; - - case SK_HW_PS_LINK: - /* Signal to RLMT */ - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para); - break; - } - - /* Start again the check Timer */ - if (pPrt->PHWLinkUp) { - Val32 = SK_WA_ACT_TIME; - } - else { - Val32 = SK_WA_INA_TIME; - } - - /* Todo: still needed for non-XMAC PHYs??? */ - /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32, - SKGE_HWAC, SK_HWEV_WATIM, Para); - break; - - case SK_HWEV_PORT_START: - if (pPrt->PHWLinkUp) { - /* - * Signal directly to RLMT to ensure correct - * sequence of SWITCH and RESET event. - */ - SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); - } - - SkHWLinkDown(pAC, IoC, (int)Port); - - /* Schedule Port RESET */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); - - /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, - SKGE_HWAC, SK_HWEV_WATIM, Para); - break; - - case SK_HWEV_PORT_STOP: - if (pPrt->PHWLinkUp) { - /* - * Signal directly to RLMT to ensure correct - * sequence of SWITCH and RESET event. - */ - SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); - } - - /* Stop Workaround Timer */ - SkTimerStop(pAC, IoC, &pPrt->PWaTimer); - - SkHWLinkDown(pAC, IoC, (int)Port); - break; - - case SK_HWEV_UPDATE_STAT: - /* We do NOT need to update any statistics */ - break; - - case SK_HWEV_CLEAR_STAT: - /* We do NOT need to clear any statistics */ - for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) { - pPrt->PPrevRx = 0; - pPrt->PPrevFcs = 0; - pPrt->PPrevShorts = 0; - } - break; - - case SK_HWEV_SET_LMODE: - Val8 = (SK_U8)Para.Para32[1]; - if (pPrt->PLinkModeConf != Val8) { - /* Set New link mode */ - pPrt->PLinkModeConf = Val8; - - /* Restart Port */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); - } - break; - - case SK_HWEV_SET_FLOWMODE: - Val8 = (SK_U8)Para.Para32[1]; - if (pPrt->PFlowCtrlMode != Val8) { - /* Set New Flow Control mode */ - pPrt->PFlowCtrlMode = Val8; - - /* Restart Port */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); - } - break; - - case SK_HWEV_SET_ROLE: - /* not possible for fiber */ - if (!pAC->GIni.GICopperType) { - break; - } - Val8 = (SK_U8)Para.Para32[1]; - if (pPrt->PMSMode != Val8) { - /* Set New Role (Master/Slave) mode */ - pPrt->PMSMode = Val8; - - /* Restart Port */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); - } - break; - - case SK_HWEV_SET_SPEED: - if (pPrt->PhyType != SK_PHY_MARV_COPPER) { - break; - } - Val8 = (SK_U8)Para.Para32[1]; - if (pPrt->PLinkSpeed != Val8) { - /* Set New Speed parameter */ - pPrt->PLinkSpeed = Val8; - - /* Restart Port */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para); - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); - } - break; - -#ifdef GENESIS - case SK_HWEV_HALFDUP_CHK: - if (pAC->GIni.GIGenesis) { - /* - * half duplex hangup workaround. - * See packet arbiter timeout interrupt for description - */ - pPrt->HalfDupTimerActive = SK_FALSE; - if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { - /* Snap statistic counters */ - (void)SkXmUpdateStats(pAC, IoC, Port); - - (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32); - - Octets = (SK_U64)Val32 << 32; - - (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32); - - Octets += Val32; - - if (pPrt->LastOctets == Octets) { - /* Tx hanging, a FIFO flush restarts it */ - SkMacFlushTxFifo(pAC, IoC, Port); - } - } - } - break; -#endif /* GENESIS */ - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); - break; - } - - return(0); -} /* SkGeSirqEvent */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkPhyIsrBcom() - PHY interrupt service routine - * - * Description: handles all interrupts from BCom PHY - * - * Returns: N/A - */ -static void SkPhyIsrBcom( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ -SK_U16 IStatus) /* Interrupt Status */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_EVPARA Para; - - pPrt = &pAC->GIni.GP[Port]; - - if ((IStatus & PHY_B_IS_PSE) != 0) { - /* Incorrectable pair swap error */ - SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022, - SKERR_SIRQ_E022MSG); - } - - if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { - - SkHWLinkDown(pAC, IoC, Port); - - Para.Para32[0] = (SK_U32)Port; - /* Signal to RLMT */ - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - - /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, - SKGE_HWAC, SK_HWEV_WATIM, Para); - } - -} /* SkPhyIsrBcom */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkPhyIsrGmac() - PHY interrupt service routine - * - * Description: handles all interrupts from Marvell PHY - * - * Returns: N/A - */ -static void SkPhyIsrGmac( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ -SK_U16 IStatus) /* Interrupt Status */ -{ - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_EVPARA Para; - SK_U16 Word; - - pPrt = &pAC->GIni.GP[Port]; - - if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { - - SkHWLinkDown(pAC, IoC, Port); - - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg.Adv: 0x%04X\n", Word)); - - /* Set Auto-negotiation advertisement */ - if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { - /* restore Asymmetric Pause bit */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, - (SK_U16)(Word | PHY_M_AN_ASP)); - } - - Para.Para32[0] = (SK_U32)Port; - /* Signal to RLMT */ - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - - if ((IStatus & PHY_M_IS_AN_ERROR) != 0) { - /* Auto-Negotiation Error */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); - } - - if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { - /* FIFO Overflow/Underrun Error */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); - } - -} /* SkPhyIsrGmac */ -#endif /* YUKON */ - - -#ifdef OTHER_PHY -/****************************************************************************** - * - * SkPhyIsrLone() - PHY interrupt service routine - * - * Description: handles all interrupts from LONE PHY - * - * Returns: N/A - */ -static void SkPhyIsrLone( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ -SK_U16 IStatus) /* Interrupt Status */ -{ - SK_EVPARA Para; - - if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { - - SkHWLinkDown(pAC, IoC, Port); - - Para.Para32[0] = (SK_U32)Port; - /* Signal to RLMT */ - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - } - -} /* SkPhyIsrLone */ -#endif /* OTHER_PHY */ - -/* End of File */ diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c deleted file mode 100644 index 79bf57cb5326..000000000000 --- a/drivers/net/sk98lin/ski2c.c +++ /dev/null @@ -1,1296 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.c - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Version: $Revision: 1.59 $ - * Date: $Date: 2003/10/20 09:07:25 $ - * Purpose: Functions to access Voltage and Temperature Sensor - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * I2C Protocol - */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. "; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/lm80.h" -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#ifdef __C2MAN__ -/* - I2C protocol implementation. - - General Description: - - The I2C protocol is used for the temperature sensors and for - the serial EEPROM which hold the configuration. - - This file covers functions that allow to read write and do - some bulk requests a specified I2C address. - - The Genesis has 2 I2C buses. One for the EEPROM which holds - the VPD Data and one for temperature and voltage sensor. - The following picture shows the I2C buses, I2C devices and - their control registers. - - Note: The VPD functions are in skvpd.c -. -. PCI Config I2C Bus for VPD Data: -. -. +------------+ -. | VPD EEPROM | -. +------------+ -. | -. | <-- I2C -. | -. +-----------+-----------+ -. | | -. +-----------------+ +-----------------+ -. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG | -. +-----------------+ +-----------------+ -. -. -. I2C Bus for LM80 sensor: -. -. +-----------------+ -. | Temperature and | -. | Voltage Sensor | -. | LM80 | -. +-----------------+ -. | -. | -. I2C --> | -. | -. +----+ -. +-------------->| OR |<--+ -. | +----+ | -. +------+------+ | -. | | | -. +--------+ +--------+ +----------+ -. | B2_I2C | | B2_I2C | | B2_I2C | -. | _CTRL | | _DATA | | _SW | -. +--------+ +--------+ +----------+ -. - The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL - and B2_I2C_DATA registers. - For driver software it is recommended to use the I2C control and - data register, because I2C bus timing is done by the ASIC and - an interrupt may be received when the I2C request is completed. - - Clock Rate Timing: MIN MAX generated by - VPD EEPROM: 50 kHz 100 kHz HW - LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW - LM80 over B2_I2C_SW register 0 400 kHz SW - - Note: The clock generated by the hardware is dependend on the - PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD - clock is 50 kHz. - */ -intro() -{} -#endif - -#ifdef SK_DIAG -/* - * I2C Fast Mode timing values used by the LM80. - * If new devices are added to the I2C bus the timing values have to be checked. - */ -#ifndef I2C_SLOW_TIMING -#define T_CLK_LOW 1300L /* clock low time in ns */ -#define T_CLK_HIGH 600L /* clock high time in ns */ -#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ -#define T_START_HOLD 600L /* start condition hold time */ -#define T_START_SETUP 600L /* start condition Set-up time */ -#define T_STOP_SETUP 600L /* stop condition Set-up time */ -#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ -#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ -#else /* I2C_SLOW_TIMING */ -/* I2C Standard Mode Timing */ -#define T_CLK_LOW 4700L /* clock low time in ns */ -#define T_CLK_HIGH 4000L /* clock high time in ns */ -#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ -#define T_START_HOLD 4000L /* start condition hold time */ -#define T_START_SETUP 4700L /* start condition Set-up time */ -#define T_STOP_SETUP 4000L /* stop condition Set-up time */ -#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ -#endif /* !I2C_SLOW_TIMING */ - -#define NS2BCLK(x) (((x)*125)/10000) - -/* - * I2C Wire Operations - * - * About I2C_CLK_LOW(): - * - * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting - * clock to low, to prevent the ASIC and the I2C data client from driving the - * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client - * send an 'ACK'). See also Concentrator Bugreport No. 10192. - */ -#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) -#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) -#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) -#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) -#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) -#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) -#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) - -#define NS2CLKT(x) ((x*125L)/10000) - -/*--------------- I2C Interface Register Functions --------------- */ - -/* - * sending one bit - */ -void SkI2cSndBit( -SK_IOC IoC, /* I/O Context */ -SK_U8 Bit) /* Bit to send */ -{ - I2C_DATA_OUT(IoC); - if (Bit) { - I2C_DATA_HIGH(IoC); - } - else { - I2C_DATA_LOW(IoC); - } - SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); - I2C_CLK_HIGH(IoC); - SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); - I2C_CLK_LOW(IoC); -} /* SkI2cSndBit*/ - - -/* - * Signal a start to the I2C Bus. - * - * A start is signaled when data goes to low in a high clock cycle. - * - * Ends with Clock Low. - * - * Status: not tested - */ -void SkI2cStart( -SK_IOC IoC) /* I/O Context */ -{ - /* Init data and Clock to output lines */ - /* Set Data high */ - I2C_DATA_OUT(IoC); - I2C_DATA_HIGH(IoC); - /* Set Clock high */ - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP)); - - /* Set Data Low */ - I2C_DATA_LOW(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD)); - - /* Clock low without Data to Input */ - I2C_START_COND(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW)); -} /* SkI2cStart */ - - -void SkI2cStop( -SK_IOC IoC) /* I/O Context */ -{ - /* Init data and Clock to output lines */ - /* Set Data low */ - I2C_DATA_OUT(IoC); - I2C_DATA_LOW(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); - - /* Set Clock high */ - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP)); - - /* - * Set Data High: Do it by setting the Data Line to Input. - * Because of a pull up resistor the Data Line - * floods to high. - */ - I2C_DATA_IN(IoC); - - /* - * When I2C activity is stopped - * o DATA should be set to input and - * o CLOCK should be set to high! - */ - SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE)); -} /* SkI2cStop */ - - -/* - * Receive just one bit via the I2C bus. - * - * Note: Clock must be set to LOW before calling this function. - * - * Returns The received bit. - */ -int SkI2cRcvBit( -SK_IOC IoC) /* I/O Context */ -{ - int Bit; - SK_U8 I2cSwCtrl; - - /* Init data as input line */ - I2C_DATA_IN(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); - - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); - - SK_I2C_GET_SW(IoC, &I2cSwCtrl); - - Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; - - I2C_CLK_LOW(IoC); - SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); - - return(Bit); -} /* SkI2cRcvBit */ - - -/* - * Receive an ACK. - * - * returns 0 If acknowledged - * 1 in case of an error - */ -int SkI2cRcvAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - return(SkI2cRcvBit(IoC) != 0); -} /* SkI2cRcvAck */ - - -/* - * Send an NACK. - */ -void SkI2cSndNAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - SkI2cSndBit(IoC, 1); -} /* SkI2cSndNAck */ - - -/* - * Send an ACK. - */ -void SkI2cSndAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - SkI2cSndBit(IoC, 0); -} /* SkI2cSndAck */ - - -/* - * Send one byte to the I2C device and wait for ACK. - * - * Return acknowleged status. - */ -int SkI2cSndByte( -SK_IOC IoC, /* I/O Context */ -int Byte) /* byte to send */ -{ - int i; - - for (i = 0; i < 8; i++) { - if (Byte & (1<<(7-i))) { - SkI2cSndBit(IoC, 1); - } - else { - SkI2cSndBit(IoC, 0); - } - } - - return(SkI2cRcvAck(IoC)); -} /* SkI2cSndByte */ - - -/* - * Receive one byte and ack it. - * - * Return byte. - */ -int SkI2cRcvByte( -SK_IOC IoC, /* I/O Context */ -int Last) /* Last Byte Flag */ -{ - int i; - int Byte = 0; - - for (i = 0; i < 8; i++) { - Byte <<= 1; - Byte |= SkI2cRcvBit(IoC); - } - - if (Last) { - SkI2cSndNAck(IoC); - } - else { - SkI2cSndAck(IoC); - } - - return(Byte); -} /* SkI2cRcvByte */ - - -/* - * Start dialog and send device address - * - * Return 0 if acknowleged, 1 in case of an error - */ -int SkI2cSndDev( -SK_IOC IoC, /* I/O Context */ -int Addr, /* Device Address */ -int Rw) /* Read / Write Flag */ -{ - SkI2cStart(IoC); - Rw = ~Rw; - Rw &= I2C_WRITE; - return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); -} /* SkI2cSndDev */ - -#endif /* SK_DIAG */ - -/*----------------- I2C CTRL Register Functions ----------*/ - -/* - * waits for a completion of an I2C transfer - * - * returns 0: success, transfer completes - * 1: error, transfer does not complete, I2C transfer - * killed, wait loop terminated. - */ -static int SkI2cWait( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ -{ - SK_U64 StartTime; - SK_U64 CurrentTime; - SK_U32 I2cCtrl; - - StartTime = SkOsGetTime(pAC); - - do { - CurrentTime = SkOsGetTime(pAC); - - if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) { - - SK_I2C_STOP(IoC); -#ifndef SK_DIAG - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); -#endif /* !SK_DIAG */ - return(1); - } - - SK_I2C_GET_CTL(IoC, &I2cCtrl); - -#ifdef xYUKON_DBG - printf("StartTime=%lu, CurrentTime=%lu\n", - StartTime, CurrentTime); - if (kbhit()) { - return(1); - } -#endif /* YUKON_DBG */ - - } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); - - return(0); -} /* SkI2cWait */ - - -/* - * waits for a completion of an I2C transfer - * - * Returns - * Nothing - */ -void SkI2cWaitIrq( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - SK_SENSOR *pSen; - SK_U64 StartTime; - SK_U32 IrqSrc; - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - - if (pSen->SenState == SK_SEN_IDLE) { - return; - } - - StartTime = SkOsGetTime(pAC); - - do { - if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { - - SK_I2C_STOP(IoC); -#ifndef SK_DIAG - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); -#endif /* !SK_DIAG */ - return; - } - - SK_IN32(IoC, B0_ISRC, &IrqSrc); - - } while ((IrqSrc & IS_I2C_READY) == 0); - - pSen->SenState = SK_SEN_IDLE; - return; -} /* SkI2cWaitIrq */ - -/* - * writes a single byte or 4 bytes into the I2C device - * - * returns 0: success - * 1: error - */ -static int SkI2cWrite( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 I2cData, /* I2C Data to write */ -int I2cDev, /* I2C Device Address */ -int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ -int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag */ -{ - SK_OUT32(IoC, B2_I2C_DATA, I2cData); - - SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); - - return(SkI2cWait(pAC, IoC, I2C_WRITE)); -} /* SkI2cWrite*/ - - -#ifdef SK_DIAG -/* - * reads a single byte or 4 bytes from the I2C device - * - * returns the word read - */ -SK_U32 SkI2cRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int I2cDev, /* I2C Device Address */ -int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ -int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag */ -{ - SK_U32 Data; - - SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); - - if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { - w_print("%s\n", SKERR_I2C_E002MSG); - } - - SK_IN32(IoC, B2_I2C_DATA, &Data); - - return(Data); -} /* SkI2cRead */ -#endif /* SK_DIAG */ - - -/* - * read a sensor's value - * - * This function reads a sensor's value from the I2C sensor chip. The sensor - * is defined by its index into the sensors database in the struct pAC points - * to. - * Returns - * 1 if the read is completed - * 0 if the read must be continued (I2C Bus still allocated) - */ -static int SkI2cReadSensor( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_SENSOR *pSen) /* Sensor to be read */ -{ - if (pSen->SenRead != NULL) { - return((*pSen->SenRead)(pAC, IoC, pSen)); - } - else { - return(0); /* no success */ - } -} /* SkI2cReadSensor */ - -/* - * Do the Init state 0 initialization - */ -static int SkI2cInit0( -SK_AC *pAC) /* Adapter Context */ -{ - int i; - - /* Begin with first sensor */ - pAC->I2c.CurrSens = 0; - - /* Begin with timeout control for state machine */ - pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; - - /* Set sensor number to zero */ - pAC->I2c.MaxSens = 0; - -#ifndef SK_DIAG - /* Initialize Number of Dummy Reads */ - pAC->I2c.DummyReads = SK_MAX_SENSORS; -#endif - - for (i = 0; i < SK_MAX_SENSORS; i++) { - pAC->I2c.SenTable[i].SenDesc = "unknown"; - pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN; - pAC->I2c.SenTable[i].SenThreErrHigh = 0; - pAC->I2c.SenTable[i].SenThreErrLow = 0; - pAC->I2c.SenTable[i].SenThreWarnHigh = 0; - pAC->I2c.SenTable[i].SenThreWarnLow = 0; - pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; - pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE; - pAC->I2c.SenTable[i].SenValue = 0; - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; - pAC->I2c.SenTable[i].SenRead = NULL; - pAC->I2c.SenTable[i].SenDev = 0; - } - - /* Now we are "INIT data"ed */ - pAC->I2c.InitLevel = SK_INIT_DATA; - return(0); -} /* SkI2cInit0*/ - - -/* - * Do the init state 1 initialization - * - * initialize the following register of the LM80: - * Configuration register: - * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT - * - * Interrupt Mask Register 1: - * - all interrupts are Disabled (0xff) - * - * Interrupt Mask Register 2: - * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter. - * - * Fan Divisor/RST_OUT register: - * - Divisors set to 1 (bits 00), all others 0s. - * - * OS# Configuration/Temperature resolution Register: - * - all 0s - * - */ -static int SkI2cInit1( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - int i; - SK_U8 I2cSwCtrl; - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - if (pAC->I2c.InitLevel != SK_INIT_DATA) { - /* ReInit not needed in I2C module */ - return(0); - } - - /* Set the Direction of I2C-Data Pin to IN */ - SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); - /* Check for 32-Bit Yukon with Low at I2C-Data Pin */ - SK_I2C_GET_SW(IoC, &I2cSwCtrl); - - if ((I2cSwCtrl & I2C_DATA) == 0) { - /* this is a 32-Bit board */ - pAC->GIni.GIYukon32Bit = SK_TRUE; - return(0); - } - - /* Check for 64 Bit Yukon without sensors */ - if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { - return(0); - } - - (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); - - (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); - - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); - - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); - - (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, - LM80_CFG, 0); - - /* - * MaxSens has to be updated here, because PhyType is not - * set when performing Init Level 0 - */ - pAC->I2c.MaxSens = 5; - - pPrt = &pAC->GIni.GP[0]; - - if (pAC->GIni.GIGenesis) { - if (pPrt->PhyType == SK_PHY_BCOM) { - if (pAC->GIni.GIMacsFound == 1) { - pAC->I2c.MaxSens += 1; - } - else { - pAC->I2c.MaxSens += 3; - } - } - } - else { - pAC->I2c.MaxSens += 3; - } - - for (i = 0; i < pAC->I2c.MaxSens; i++) { - switch (i) { - case 0: - pAC->I2c.SenTable[i].SenDesc = "Temperature"; - pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN; - break; - case 1: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN; - break; - case 2: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN; - pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO; - break; - case 3: - pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; - break; - case 4: - if (pAC->GIni.GIGenesis) { - if (pPrt->PhyType == SK_PHY_BCOM) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - } - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; - if (pAC->GIni.GIVauxAvail) { - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR; - } - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; - break; - case 5: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; - break; - case 6: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; - break; - case 7: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; - pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; - } - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, - SKERR_I2C_E001, SKERR_I2C_E001MSG); - break; - } - - pAC->I2c.SenTable[i].SenValue = 0; - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; - pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; - pAC->I2c.SenTable[i].SenDev = LM80_ADDR; - } - -#ifndef SK_DIAG - pAC->I2c.DummyReads = pAC->I2c.MaxSens; -#endif /* !SK_DIAG */ - - /* Clear I2C IRQ */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); - - /* Now we are I/O initialized */ - pAC->I2c.InitLevel = SK_INIT_IO; - return(0); -} /* SkI2cInit1 */ - - -/* - * Init level 2: Start first sensor read. - */ -static int SkI2cInit2( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - int ReadComplete; - SK_SENSOR *pSen; - - if (pAC->I2c.InitLevel != SK_INIT_IO) { - /* ReInit not needed in I2C module */ - /* Init0 and Init2 not permitted */ - return(0); - } - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); - } - - /* Now we are correctly initialized */ - pAC->I2c.InitLevel = SK_INIT_RUN; - - return(0); -} /* SkI2cInit2*/ - - -/* - * Initialize I2C devices - * - * Get the first voltage value and discard it. - * Go into temperature read mode. A default pointer is not set. - * - * The things to be done depend on the init level in the parameter list: - * Level 0: - * Initialize only the data structures. Do NOT access hardware. - * Level 1: - * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. - * Level 2: - * Everything is possible. Interrupts may be used from now on. - * - * return: - * 0 = success - * other = error. - */ -int SkI2cInit( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ -int Level) /* Init Level */ -{ - - switch (Level) { - case SK_INIT_DATA: - return(SkI2cInit0(pAC)); - case SK_INIT_IO: - return(SkI2cInit1(pAC, IoC)); - case SK_INIT_RUN: - return(SkI2cInit2(pAC, IoC)); - default: - break; - } - - return(0); -} /* SkI2cInit */ - - -#ifndef SK_DIAG - -/* - * Interrupt service function for the I2C Interface - * - * Clears the Interrupt source - * - * Reads the register and check it for sending a trap. - * - * Starts the timer if necessary. - */ -void SkI2cIsr( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - SK_EVPARA Para; - - /* Clear I2C IRQ */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); - - Para.Para64 = 0; - SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para); -} /* SkI2cIsr */ - - -/* - * Check this sensors Value against the threshold and send events. - */ -static void SkI2cCheckSensor( -SK_AC *pAC, /* Adapter Context */ -SK_SENSOR *pSen) -{ - SK_EVPARA ParaLocal; - SK_BOOL TooHigh; /* Is sensor too high? */ - SK_BOOL TooLow; /* Is sensor too low? */ - SK_U64 CurrTime; /* Current Time */ - SK_BOOL DoTrapSend; /* We need to send a trap */ - SK_BOOL DoErrLog; /* We need to log the error */ - SK_BOOL IsError; /* We need to log the error */ - - /* Check Dummy Reads first */ - if (pAC->I2c.DummyReads > 0) { - pAC->I2c.DummyReads--; - return; - } - - /* Get the current time */ - CurrTime = SkOsGetTime(pAC); - - /* Set para to the most useful setting: The current sensor. */ - ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; - - /* Check the Value against the thresholds. First: Error Thresholds */ - TooHigh = (pSen->SenValue > pSen->SenThreErrHigh); - TooLow = (pSen->SenValue < pSen->SenThreErrLow); - - IsError = SK_FALSE; - if (TooHigh || TooLow) { - /* Error condition is satisfied */ - DoTrapSend = SK_TRUE; - DoErrLog = SK_TRUE; - - /* Now error condition is satisfied */ - IsError = SK_TRUE; - - if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { - /* This state is the former one */ - - /* So check first whether we have to send a trap */ - if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > - CurrTime) { - /* - * Do NOT send the Trap. The hold back time - * has to run out first. - */ - DoTrapSend = SK_FALSE; - } - - /* Check now whether we have to log an Error */ - if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > - CurrTime) { - /* - * Do NOT log the error. The hold back time - * has to run out first. - */ - DoErrLog = SK_FALSE; - } - } - else { - /* We came from a different state -> Set Begin Time Stamp */ - pSen->SenBegErrTS = CurrTime; - pSen->SenErrFlag = SK_SEN_ERR_ERR; - } - - if (DoTrapSend) { - /* Set current Time */ - pSen->SenLastErrTrapTS = CurrTime; - pSen->SenErrCts++; - - /* Queue PNMI Event */ - SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? - SK_PNMI_EVT_SEN_ERR_UPP : - SK_PNMI_EVT_SEN_ERR_LOW), - ParaLocal); - } - - if (DoErrLog) { - /* Set current Time */ - pSen->SenLastErrLogTS = CurrTime; - - if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); - } - else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); - } - } - } - - /* Check the Value against the thresholds */ - /* 2nd: Warning thresholds */ - TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh); - TooLow = (pSen->SenValue < pSen->SenThreWarnLow); - - if (!IsError && (TooHigh || TooLow)) { - /* Error condition is satisfied */ - DoTrapSend = SK_TRUE; - DoErrLog = SK_TRUE; - - if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { - /* This state is the former one */ - - /* So check first whether we have to send a trap */ - if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { - /* - * Do NOT send the Trap. The hold back time - * has to run out first. - */ - DoTrapSend = SK_FALSE; - } - - /* Check now whether we have to log an Error */ - if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { - /* - * Do NOT log the error. The hold back time - * has to run out first. - */ - DoErrLog = SK_FALSE; - } - } - else { - /* We came from a different state -> Set Begin Time Stamp */ - pSen->SenBegWarnTS = CurrTime; - pSen->SenErrFlag = SK_SEN_ERR_WARN; - } - - if (DoTrapSend) { - /* Set current Time */ - pSen->SenLastWarnTrapTS = CurrTime; - pSen->SenWarnCts++; - - /* Queue PNMI Event */ - SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? - SK_PNMI_EVT_SEN_WAR_UPP : - SK_PNMI_EVT_SEN_WAR_LOW), - ParaLocal); - } - - if (DoErrLog) { - /* Set current Time */ - pSen->SenLastWarnLogTS = CurrTime; - - if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); - } - else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); - } - } - } - - /* Check for NO error at all */ - if (!IsError && !TooHigh && !TooLow) { - /* Set o.k. Status if no error and no warning condition */ - pSen->SenErrFlag = SK_SEN_ERR_OK; - } - - /* End of check against the thresholds */ - - /* Bug fix AF: 16.Aug.2001: Correct the init base - * of LM80 sensor. - */ - if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { - - pSen->SenInit = SK_SEN_DYN_INIT_NONE; - - if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { - /* 5V PCI-IO Voltage */ - pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; - pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; - } - else { - /* 3.3V PCI-IO Voltage */ - pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; - pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; - } - } - -#ifdef TEST_ONLY - /* Dynamic thresholds also for VAUX of LM80 sensor */ - if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { - - pSen->SenInit = SK_SEN_DYN_INIT_NONE; - - /* 3.3V VAUX Voltage */ - if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { - pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; - pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; - } - /* 0V VAUX Voltage */ - else { - pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; - pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; - } - } - - /* - * Check initialization state: - * The VIO Thresholds need adaption - */ - if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && - pSen->SenValue > SK_SEN_WARNLOW2C && - pSen->SenValue < SK_SEN_WARNHIGH2) { - pSen->SenThreErrLow = SK_SEN_ERRLOW2C; - pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; - pSen->SenInit = SK_TRUE; - } - - if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && - pSen->SenValue > SK_SEN_WARNLOW2 && - pSen->SenValue < SK_SEN_WARNHIGH2C) { - pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; - pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; - pSen->SenInit = SK_TRUE; - } -#endif - - if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); - } -} /* SkI2cCheckSensor */ - - -/* - * The only Event to be served is the timeout event - * - */ -int SkI2cEvent( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Event, /* Module specific Event */ -SK_EVPARA Para) /* Event specific Parameter */ -{ - int ReadComplete; - SK_SENSOR *pSen; - SK_U32 Time; - SK_EVPARA ParaLocal; - int i; - - /* New case: no sensors */ - if (pAC->I2c.MaxSens == 0) { - return(0); - } - - switch (Event) { - case SK_I2CEV_IRQ: - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - /* Check sensor against defined thresholds */ - SkI2cCheckSensor(pAC, pSen); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - else { - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - break; - case SK_I2CEV_TIM: - if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { - - ParaLocal.Para64 = (SK_U64)0; - SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - /* Check sensor against defined thresholds */ - SkI2cCheckSensor(pAC, pSen); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - } - else { - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - pSen->SenErrFlag = SK_SEN_ERR_FAULTY; - SK_I2C_STOP(IoC); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - break; - case SK_I2CEV_CLEAR: - for (i = 0; i < SK_MAX_SENSORS; i++) { - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenWarnCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenBegWarnTS = 0; - pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0; - } - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); - } - - return(0); -} /* SkI2cEvent*/ - -#endif /* !SK_DIAG */ diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c deleted file mode 100644 index a204f5bb55d4..000000000000 --- a/drivers/net/sk98lin/sklm80.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Name: sklm80.c - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Version: $Revision: 1.22 $ - * Date: $Date: 2003/10/20 09:08:21 $ - * Purpose: Functions to access Voltage and Temperature Sensor (LM80) - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - LM80 functions -*/ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. "; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/lm80.h" -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#define BREAK_OR_WAIT(pAC,IoC,Event) break - -/* - * read a sensors value (LM80 specific) - * - * This function reads a sensors value from the I2C sensor chip LM80. - * The sensor is defined by its index into the sensors database in the struct - * pAC points to. - * - * Returns 1 if the read is completed - * 0 if the read must be continued (I2C Bus still allocated) - */ -int SkLm80ReadSensor( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ -SK_SENSOR *pSen) /* Sensor to be read */ -{ - SK_I32 Value; - - switch (pSen->SenState) { - case SK_SEN_IDLE: - /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); - - pSen->SenState = SK_SEN_VALUE ; - BREAK_OR_WAIT(pAC, IoC, I2C_READ); - - case SK_SEN_VALUE: - /* Read value from data register */ - SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); - - Value &= 0xff; /* only least significant byte is valid */ - - /* Do NOT check the Value against the thresholds */ - /* Checking is done in the calling instance */ - - if (pSen->SenType == SK_SEN_VOLT) { - /* Voltage sensor */ - pSen->SenValue = Value * SK_LM80_VT_LSB; - pSen->SenState = SK_SEN_IDLE ; - return(1); - } - - if (pSen->SenType == SK_SEN_FAN) { - if (Value != 0 && Value != 0xff) { - /* Fan speed counter */ - pSen->SenValue = SK_LM80_FAN_FAKTOR/Value; - } - else { - /* Indicate Fan error */ - pSen->SenValue = 0; - } - pSen->SenState = SK_SEN_IDLE ; - return(1); - } - - /* First: correct the value: it might be negative */ - if ((Value & 0x80) != 0) { - /* Value is negative */ - Value = Value - 256; - } - - /* We have a temperature sensor and need to get the signed extension. - * For now we get the extension from the last reading, so in the normal - * case we won't see flickering temperatures. - */ - pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + - (pSen->SenValue % SK_LM80_TEMP_LSB); - - /* Send address to ADDR register */ - SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); - - pSen->SenState = SK_SEN_VALEXT ; - BREAK_OR_WAIT(pAC, IoC, I2C_READ); - - case SK_SEN_VALEXT: - /* Read value from data register */ - SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); - Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ - - /* cut the LSB bit */ - pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * - SK_LM80_TEMP_LSB); - - if (pSen->SenValue < 0) { - /* Value negative: The bit value must be subtracted */ - pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); - } - else { - /* Value positive: The bit value must be added */ - pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB); - } - - pSen->SenState = SK_SEN_IDLE ; - return(1); - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG); - return(1); - } - - /* Not completed */ - return(0); -} - diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c deleted file mode 100644 index 0275b4f71d9b..000000000000 --- a/drivers/net/sk98lin/skqueue.c +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************** - * - * Name: skqueue.c - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.20 $ - * Date: $Date: 2003/09/16 13:44:00 $ - * Purpose: Management of an event queue. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - - -/* - * Event queue and dispatcher - */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell."; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/skqueue.h" /* Queue Definitions */ -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#ifdef __C2MAN__ -/* - Event queue management. - - General Description: - - */ -intro() -{} -#endif - -#define PRINTF(a,b,c) - -/* - * init event queue management - * - * Must be called during init level 0. - */ -void SkEventInit( -SK_AC *pAC, /* Adapter context */ -SK_IOC Ioc, /* IO context */ -int Level) /* Init level */ -{ - switch (Level) { - case SK_INIT_DATA: - pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue; - break; - default: - break; - } -} - -/* - * add event to queue - */ -void SkEventQueue( -SK_AC *pAC, /* Adapters context */ -SK_U32 Class, /* Event Class */ -SK_U32 Event, /* Event to be queued */ -SK_EVPARA Para) /* Event parameter */ -{ - pAC->Event.EvPut->Class = Class; - pAC->Event.EvPut->Event = Event; - pAC->Event.EvPut->Para = Para; - - if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pAC->Event.EvPut = pAC->Event.EvQueue; - - if (pAC->Event.EvPut == pAC->Event.EvGet) { - SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); - } -} - -/* - * event dispatcher - * while event queue is not empty - * get event from queue - * send command to state machine - * end - * return error reported by individual Event function - * 0 if no error occured. - */ -int SkEventDispatcher( -SK_AC *pAC, /* Adapters Context */ -SK_IOC Ioc) /* Io context */ -{ - SK_EVENTELEM *pEv; /* pointer into queue */ - SK_U32 Class; - int Rtv; - - pEv = pAC->Event.EvGet; - - PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put); - - while (pEv != pAC->Event.EvPut) { - PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event); - - switch (Class = pEv->Class) { -#ifndef SK_USE_LAC_EV -#ifndef SK_SLIM - case SKGE_RLMT: /* RLMT Event */ - Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; - case SKGE_I2C: /* I2C Event */ - Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; - case SKGE_PNMI: /* PNMI Event */ - Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#endif /* not SK_SLIM */ -#endif /* not SK_USE_LAC_EV */ - case SKGE_DRV: /* Driver Event */ - Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#ifndef SK_USE_SW_TIMER - case SKGE_HWAC: - Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#else /* !SK_USE_SW_TIMER */ - case SKGE_SWT : - Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#endif /* !SK_USE_SW_TIMER */ -#ifdef SK_USE_LAC_EV - case SKGE_LACP : - Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; - case SKGE_RSF : - Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; - case SKGE_MARKER : - Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; - case SKGE_FD : - Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#endif /* SK_USE_LAC_EV */ -#ifdef SK_USE_CSUM - case SKGE_CSUM : - Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para); - break; -#endif /* SK_USE_CSUM */ - default : - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG); - Rtv = 0; - } - - if (Rtv != 0) { - return(Rtv); - } - - if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pEv = pAC->Event.EvQueue; - - /* Renew get: it is used in queue_events to detect overruns */ - pAC->Event.EvGet = pEv; - } - - return(0); -} - -/* End of file */ diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c deleted file mode 100644 index be8d1ccddf6d..000000000000 --- a/drivers/net/sk98lin/skrlmt.c +++ /dev/null @@ -1,3257 +0,0 @@ -/****************************************************************************** - * - * Name: skrlmt.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.69 $ - * Date: $Date: 2003/04/15 09:39:22 $ - * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters. - * It is mainly intended for adapters with more than one link. - * For such adapters, this module realizes Redundant Link ManagemenT (RLMT). - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * "skdrv2nd.h" - * - ******************************************************************************/ - -#ifndef lint -static const char SysKonnectFileId[] = - "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell."; -#endif /* !defined(lint) */ - -#define __SKRLMT_C - -#ifdef __cplusplus -extern "C" { -#endif /* cplusplus */ - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" - -/* defines ********************************************************************/ - -#ifndef SK_HWAC_LINK_LED -#define SK_HWAC_LINK_LED(a,b,c,d) -#endif /* !defined(SK_HWAC_LINK_LED) */ - -#ifndef DEBUG -#define RLMT_STATIC static -#else /* DEBUG */ -#define RLMT_STATIC - -#ifndef SK_LITTLE_ENDIAN -/* First 32 bits */ -#define OFFS_LO32 1 - -/* Second 32 bits */ -#define OFFS_HI32 0 -#else /* SK_LITTLE_ENDIAN */ -/* First 32 bits */ -#define OFFS_LO32 0 - -/* Second 32 bits */ -#define OFFS_HI32 1 -#endif /* SK_LITTLE_ENDIAN */ - -#endif /* DEBUG */ - -/* ----- Private timeout values ----- */ - -#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */ -#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */ -#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */ -#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */ -#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */ -#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */ - -/* Assume tick counter increment is 1 - may be set OS-dependent. */ -#ifndef SK_TICK_INCR -#define SK_TICK_INCR SK_CONSTU64(1) -#endif /* !defined(SK_TICK_INCR) */ - -/* - * Amount that a time stamp must be later to be recognized as "substantially - * later". This is about 1/128 sec, but above 1 tick counter increment. - */ -#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \ - (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR)) - -/* ----- Private RLMT defaults ----- */ - -#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */ -#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */ - -/* ----- Private RLMT checking states ----- */ - -#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */ -#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */ -#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */ -#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */ - -/* ----- Private PORT checking states ----- */ - -#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */ -#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */ - -/* ----- Private PORT events ----- */ - -/* Note: Update simulation when changing these. */ -#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */ -#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */ -#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */ -#define SK_RLMT_PORTDOWN 1103 /* Port went down. */ -#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */ - -/* ----- Private RLMT events ----- */ - -/* Note: Update simulation when changing these. */ -#define SK_RLMT_TIM 2100 /* RLMT timeout. */ -#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */ - -#define TO_SHORTEN(tim) ((tim) / 2) - -/* Error numbers and messages. */ -#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0) -#define SKERR_RLMT_E001_MSG "No Packet." -#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1) -#define SKERR_RLMT_E002_MSG "Short Packet." -#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1) -#define SKERR_RLMT_E003_MSG "Unknown RLMT event." -#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1) -#define SKERR_RLMT_E004_MSG "PortsUp incorrect." -#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1) -#define SKERR_RLMT_E005_MSG \ - "Net seems to be segmented (different root bridges are reported on the ports)." -#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1) -#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected." -#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1) -#define SKERR_RLMT_E007_MSG "LinksUp incorrect." -#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1) -#define SKERR_RLMT_E008_MSG "Port not started but link came up." -#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1) -#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port." -#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1) -#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port." - -/* LLC field values. */ -#define LLC_COMMAND_RESPONSE_BIT 1 -#define LLC_TEST_COMMAND 0xE3 -#define LLC_UI 0x03 - -/* RLMT Packet fields. */ -#define SK_RLMT_DSAP 0 -#define SK_RLMT_SSAP 0 -#define SK_RLMT_CTRL (LLC_TEST_COMMAND) -#define SK_RLMT_INDICATOR0 0x53 /* S */ -#define SK_RLMT_INDICATOR1 0x4B /* K */ -#define SK_RLMT_INDICATOR2 0x2D /* - */ -#define SK_RLMT_INDICATOR3 0x52 /* R */ -#define SK_RLMT_INDICATOR4 0x4C /* L */ -#define SK_RLMT_INDICATOR5 0x4D /* M */ -#define SK_RLMT_INDICATOR6 0x54 /* T */ -#define SK_RLMT_PACKET_VERSION 0 - -/* RLMT SPT Flag values. */ -#define SK_RLMT_SPT_FLAG_CHANGE 0x01 -#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80 - -/* RLMT SPT Packet fields. */ -#define SK_RLMT_SPT_DSAP 0x42 -#define SK_RLMT_SPT_SSAP 0x42 -#define SK_RLMT_SPT_CTRL (LLC_UI) -#define SK_RLMT_SPT_PROTOCOL_ID0 0x00 -#define SK_RLMT_SPT_PROTOCOL_ID1 0x00 -#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00 -#define SK_RLMT_SPT_BPDU_TYPE 0x00 -#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */ -#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */ -#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */ - -/* Remaining 6 bytes will be the current port address. */ -#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00 -#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00 -#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00 -#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00 -#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */ -#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */ - -/* Remaining 6 bytes will be the current port address. */ -#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */ -#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */ -#define SK_RLMT_SPT_MSG_AGE0 0x00 -#define SK_RLMT_SPT_MSG_AGE1 0x00 -#define SK_RLMT_SPT_MAX_AGE0 0x00 -#define SK_RLMT_SPT_MAX_AGE1 0xFF -#define SK_RLMT_SPT_HELLO_TIME0 0x00 -#define SK_RLMT_SPT_HELLO_TIME1 0xFF -#define SK_RLMT_SPT_FWD_DELAY0 0x00 -#define SK_RLMT_SPT_FWD_DELAY1 0x40 - -/* Size defines. */ -#define SK_RLMT_MIN_PACKET_SIZE 34 -#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE) -#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \ - SK_RLMT_MIN_PACKET_SIZE) - -/* ----- RLMT packet types ----- */ -#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */ -#define SK_PACKET_ALIVE 2 /* Alive packet to port. */ -#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */ -#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */ - -#ifdef SK_LITTLE_ENDIAN -#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \ - SK_U8 *_Addr = (SK_U8*)(Addr); \ - SK_U16 _Val = (SK_U16)(Val); \ - *_Addr++ = (SK_U8)(_Val >> 8); \ - *_Addr = (SK_U8)(_Val & 0xFF); \ -} -#endif /* SK_LITTLE_ENDIAN */ - -#ifdef SK_BIG_ENDIAN -#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val)) -#endif /* SK_BIG_ENDIAN */ - -#define AUTONEG_FAILED SK_FALSE -#define AUTONEG_SUCCESS SK_TRUE - - -/* typedefs *******************************************************************/ - -/* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */ -typedef struct s_RlmtPacket { - SK_U8 DstAddr[SK_MAC_ADDR_LEN]; - SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; - SK_U8 TypeLen[2]; - SK_U8 DSap; - SK_U8 SSap; - SK_U8 Ctrl; - SK_U8 Indicator[7]; - SK_U8 RlmtPacketType[2]; - SK_U8 Align1[2]; - SK_U8 Random[4]; /* Random value of requesting(!) station. */ - SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */ - SK_U8 Data[SK_PACKET_DATA_LEN]; -} SK_RLMT_PACKET; - -typedef struct s_SpTreeRlmtPacket { - SK_U8 DstAddr[SK_MAC_ADDR_LEN]; - SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; - SK_U8 TypeLen[2]; - SK_U8 DSap; - SK_U8 SSap; - SK_U8 Ctrl; - SK_U8 ProtocolId[2]; - SK_U8 ProtocolVersionId; - SK_U8 BpduType; - SK_U8 Flags; - SK_U8 RootId[8]; - SK_U8 RootPathCost[4]; - SK_U8 BridgeId[8]; - SK_U8 PortId[2]; - SK_U8 MessageAge[2]; - SK_U8 MaxAge[2]; - SK_U8 HelloTime[2]; - SK_U8 ForwardDelay[2]; -} SK_SPTREE_PACKET; - -/* global variables ***********************************************************/ - -SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; -SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; - -/* local variables ************************************************************/ - -/* None. */ - -/* functions ******************************************************************/ - -RLMT_STATIC void SkRlmtCheckSwitch( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 NetIdx); -RLMT_STATIC void SkRlmtCheckSeg( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 NetIdx); -RLMT_STATIC void SkRlmtEvtSetNets( - SK_AC *pAC, - SK_IOC IoC, - SK_EVPARA Para); - -/****************************************************************************** - * - * SkRlmtInit - initialize data, set state to init - * - * Description: - * - * SK_INIT_DATA - * ============ - * - * This routine initializes all RLMT-related variables to a known state. - * The initial state is SK_RLMT_RS_INIT. - * All ports are initialized to SK_RLMT_PS_INIT. - * - * - * SK_INIT_IO - * ========== - * - * Nothing. - * - * - * SK_INIT_RUN - * =========== - * - * Determine the adapter's random value. - * Set the hw registers, the "logical MAC address", the - * RLMT multicast address, and eventually the BPDU multicast address. - * - * Context: - * init, pageable - * - * Returns: - * Nothing. - */ -void SkRlmtInit( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Level) /* Initialization Level */ -{ - SK_U32 i, j; - SK_U64 Random; - SK_EVPARA Para; - SK_MAC_ADDR VirtualMacAddress; - SK_MAC_ADDR PhysicalAMacAddress; - SK_BOOL VirtualMacAddressSet; - SK_BOOL PhysicalAMacAddressSet; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, - ("RLMT Init level %d.\n", Level)) - - switch (Level) { - case SK_INIT_DATA: /* Initialize data structures. */ - SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT)); - - for (i = 0; i < SK_MAX_MACS; i++) { - pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT; - pAC->Rlmt.Port[i].LinkDown = SK_TRUE; - pAC->Rlmt.Port[i].PortDown = SK_TRUE; - pAC->Rlmt.Port[i].PortStarted = SK_FALSE; - pAC->Rlmt.Port[i].PortNoRx = SK_FALSE; - pAC->Rlmt.Port[i].RootIdSet = SK_FALSE; - pAC->Rlmt.Port[i].PortNumber = i; - pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0]; - pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i]; - } - - pAC->Rlmt.NumNets = 1; - for (i = 0; i < SK_MAX_NETS; i++) { - pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; - pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; - pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; - pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ - /* Just assuming. */ - pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; - pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; - pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; - pAC->Rlmt.Net[i].NetNumber = i; - } - - pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0]; - pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1]; -#if SK_MAX_NETS > 1 - pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1]; -#endif /* SK_MAX_NETS > 1 */ - break; - - case SK_INIT_IO: /* GIMacsFound first available here. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, - ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) - - pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; - - /* Initialize HW registers? */ - if (pAC->GIni.GIMacsFound == 1) { - Para.Para32[0] = SK_RLMT_MODE_CLS; - Para.Para32[1] = 0; - (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para); - } - break; - - case SK_INIT_RUN: - /* Ensure RLMT is set to one net. */ - if (pAC->Rlmt.NumNets > 1) { - Para.Para32[0] = 1; - Para.Para32[1] = -1; - SkRlmtEvtSetNets(pAC, IoC, Para); - } - - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - Random = SkOsGetTime(pAC); - *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random; - - for (j = 0; j < 4; j++) { - pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort-> - CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j]; - } - - (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY); - - /* Add RLMT MC address. */ - (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT); - - if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) { - /* Add BPDU MC address. */ - (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT); - } - - (void)SkAddrMcUpdate(pAC, IoC, i); - } - - VirtualMacAddressSet = SK_FALSE; - /* Read virtual MAC address from Control Register File. */ - for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - - SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]); - VirtualMacAddressSet |= VirtualMacAddress.a[j]; - } - - PhysicalAMacAddressSet = SK_FALSE; - /* Read physical MAC address for MAC A from Control Register File. */ - for (j = 0; j < SK_MAC_ADDR_LEN; j++) { - - SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]); - PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j]; - } - - /* check if the two mac addresses contain reasonable values */ - if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) { - - pAC->Rlmt.RlmtOff = SK_TRUE; - } - - /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD - and the RLMT_LOOKAHEAD macros */ - else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) { - - pAC->Rlmt.RlmtOff = SK_TRUE; - } - else { - pAC->Rlmt.RlmtOff = SK_FALSE; - } - break; - - default: /* error */ - break; - } - return; -} /* SkRlmtInit */ - - -/****************************************************************************** - * - * SkRlmtBuildCheckChain - build the check chain - * - * Description: - * This routine builds the local check chain: - * - Each port that is up checks the next port. - * - The last port that is up checks the first port that is up. - * - * Notes: - * - Currently only local ports are considered when building the chain. - * - Currently the SuspectState is just reset; - * it would be better to save it ... - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtBuildCheckChain( -SK_AC *pAC, /* Adapter Context */ -SK_U32 NetIdx) /* Net Number */ -{ - SK_U32 i; - SK_U32 NumMacsUp; - SK_RLMT_PORT * FirstMacUp; - SK_RLMT_PORT * PrevMacUp; - - FirstMacUp = NULL; - PrevMacUp = NULL; - - if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) { - for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) { - pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; - } - return; /* Done. */ - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtBuildCheckChain.\n")) - - NumMacsUp = 0; - - for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { - pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; - pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0; - pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &= - ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX); - - /* - * If more than two links are detected we should consider - * checking at least two other ports: - * 1. the next port that is not LinkDown and - * 2. the next port that is not PortDown. - */ - if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { - if (NumMacsUp == 0) { - FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; - } - else { - PrevMacUp->PortCheck[ - pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr = - pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress; - PrevMacUp->PortCheck[ - PrevMacUp->PortsChecked].SuspectTx = SK_FALSE; - PrevMacUp->PortsChecked++; - } - PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; - NumMacsUp++; - } - } - - if (NumMacsUp > 1) { - PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr = - FirstMacUp->AddrPort->CurrentMacAddress; - PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx = - SK_FALSE; - PrevMacUp->PortsChecked++; - } - -#ifdef DEBUG - for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d checks %d other ports: %2X.\n", i, - pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, - pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) - } -#endif /* DEBUG */ - - return; -} /* SkRlmtBuildCheckChain */ - - -/****************************************************************************** - * - * SkRlmtBuildPacket - build an RLMT packet - * - * Description: - * This routine sets up an RLMT packet. - * - * Context: - * runtime, pageable? - * - * Returns: - * NULL or pointer to RLMT mbuf - */ -RLMT_STATIC SK_MBUF *SkRlmtBuildPacket( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber, /* Sending port */ -SK_U16 PacketType, /* RLMT packet type */ -SK_MAC_ADDR *SrcAddr, /* Source address */ -SK_MAC_ADDR *DestAddr) /* Destination address */ -{ - int i; - SK_U16 Length; - SK_MBUF *pMb; - SK_RLMT_PACKET *pPacket; - -#ifdef DEBUG - SK_U8 CheckSrc = 0; - SK_U8 CheckDest = 0; - - for (i = 0; i < SK_MAC_ADDR_LEN; ++i) { - CheckSrc |= SrcAddr->a[i]; - CheckDest |= DestAddr->a[i]; - } - - if ((CheckSrc == 0) || (CheckDest == 0)) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, - ("SkRlmtBuildPacket: Invalid %s%saddr.\n", - (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) - } -#endif - - if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) { - pPacket = (SK_RLMT_PACKET*)pMb->pData; - for (i = 0; i < SK_MAC_ADDR_LEN; i++) { - pPacket->DstAddr[i] = DestAddr->a[i]; - pPacket->SrcAddr[i] = SrcAddr->a[i]; - } - pPacket->DSap = SK_RLMT_DSAP; - pPacket->SSap = SK_RLMT_SSAP; - pPacket->Ctrl = SK_RLMT_CTRL; - pPacket->Indicator[0] = SK_RLMT_INDICATOR0; - pPacket->Indicator[1] = SK_RLMT_INDICATOR1; - pPacket->Indicator[2] = SK_RLMT_INDICATOR2; - pPacket->Indicator[3] = SK_RLMT_INDICATOR3; - pPacket->Indicator[4] = SK_RLMT_INDICATOR4; - pPacket->Indicator[5] = SK_RLMT_INDICATOR5; - pPacket->Indicator[6] = SK_RLMT_INDICATOR6; - - SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]); - - for (i = 0; i < 4; i++) { - pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i]; - } - - SK_U16_TO_NETWORK_ORDER( - SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]); - - for (i = 0; i < SK_PACKET_DATA_LEN; i++) { - pPacket->Data[i] = 0x00; - } - - Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ - pMb->Length = Length; - pMb->PortIdx = PortNumber; - Length -= 14; - SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]); - - if (PacketType == SK_PACKET_ALIVE) { - pAC->Rlmt.Port[PortNumber].TxHelloCts++; - } - } - - return (pMb); -} /* SkRlmtBuildPacket */ - - -/****************************************************************************** - * - * SkRlmtBuildSpanningTreePacket - build spanning tree check packet - * - * Description: - * This routine sets up a BPDU packet for spanning tree check. - * - * Context: - * runtime, pageable? - * - * Returns: - * NULL or pointer to RLMT mbuf - */ -RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber) /* Sending port */ -{ - unsigned i; - SK_U16 Length; - SK_MBUF *pMb; - SK_SPTREE_PACKET *pSPacket; - - if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != - NULL) { - pSPacket = (SK_SPTREE_PACKET*)pMb->pData; - for (i = 0; i < SK_MAC_ADDR_LEN; i++) { - pSPacket->DstAddr[i] = BridgeMcAddr.a[i]; - pSPacket->SrcAddr[i] = - pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; - } - pSPacket->DSap = SK_RLMT_SPT_DSAP; - pSPacket->SSap = SK_RLMT_SPT_SSAP; - pSPacket->Ctrl = SK_RLMT_SPT_CTRL; - - pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0; - pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1; - pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID; - pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE; - pSPacket->Flags = SK_RLMT_SPT_FLAGS; - pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0; - pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1; - pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0; - pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1; - pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2; - pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3; - pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0; - pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1; - - /* - * Use logical MAC address as bridge ID and filter these packets - * on receive. - */ - for (i = 0; i < SK_MAC_ADDR_LEN; i++) { - pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] = - pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber]. - CurrentMacAddress.a[i]; - } - pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0; - pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1; - pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0; - pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1; - pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0; - pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1; - pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0; - pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1; - pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0; - pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1; - - Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ - pMb->Length = Length; - pMb->PortIdx = PortNumber; - Length -= 14; - SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]); - - pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++; - } - - return (pMb); -} /* SkRlmtBuildSpanningTreePacket */ - - -/****************************************************************************** - * - * SkRlmtSend - build and send check packets - * - * Description: - * Depending on the RLMT state and the checking state, several packets - * are sent through the indicated port. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing. - */ -RLMT_STATIC void SkRlmtSend( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber) /* Sending port */ -{ - unsigned j; - SK_EVPARA Para; - SK_RLMT_PORT *pRPort; - - pRPort = &pAC->Rlmt.Port[PortNumber]; - if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { - if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) { - /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */ - if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, - SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, - &SkRlmtMcAddr)) != NULL) { - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - } - else { - /* - * Send a directed RLMT packet to all ports that are - * checked by the indicated port. - */ - for (j = 0; j < pRPort->PortsChecked; j++) { - if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, - SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, - &pRPort->PortCheck[j].CheckAddr)) != NULL) { - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - } - } - } - - if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && - (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) { - /* - * Send a BPDU packet to make a connected switch tell us - * the correct root bridge. - */ - if ((Para.pParaPtr = - SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) { - pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG; - pRPort->RootIdSet = SK_FALSE; - - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, - ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) - } - } - return; -} /* SkRlmtSend */ - - -/****************************************************************************** - * - * SkRlmtPortReceives - check if port is (going) down and bring it up - * - * Description: - * This routine checks if a port who received a non-BPDU packet - * needs to go up or needs to be stopped going down. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing. - */ -RLMT_STATIC void SkRlmtPortReceives( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber) /* Port to check */ -{ - SK_RLMT_PORT *pRPort; - SK_EVPARA Para; - - pRPort = &pAC->Rlmt.Port[PortNumber]; - pRPort->PortNoRx = SK_FALSE; - - if ((pRPort->PortState == SK_RLMT_PS_DOWN) && - !(pRPort->CheckingState & SK_RLMT_PCS_TX)) { - /* - * Port is marked down (rx), but received a non-BPDU packet. - * Bring it up. - */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Received on PortDown.\n")) - - pRPort->PortState = SK_RLMT_PS_GOING_UP; - pRPort->GuTimeStamp = SkOsGetTime(pAC); - Para.Para32[0] = PortNumber; - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, - SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para); - pRPort->CheckingState &= ~SK_RLMT_PCS_RX; - /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - } /* PortDown && !SuspectTx */ - else if (pRPort->CheckingState & SK_RLMT_PCS_RX) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Stop bringing port down.\n")) - SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); - pRPort->CheckingState &= ~SK_RLMT_PCS_RX; - /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - } /* PortGoingDown */ - - return; -} /* SkRlmtPortReceives */ - - -/****************************************************************************** - * - * SkRlmtPacketReceive - receive a packet for closer examination - * - * Description: - * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing. - */ -RLMT_STATIC void SkRlmtPacketReceive( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_MBUF *pMb) /* Received packet */ -{ -#ifdef xDEBUG - extern void DumpData(char *p, int size); -#endif /* DEBUG */ - int i; - unsigned j; - SK_U16 PacketType; - SK_U32 PortNumber; - SK_ADDR_PORT *pAPort; - SK_RLMT_PORT *pRPort; - SK_RLMT_PACKET *pRPacket; - SK_SPTREE_PACKET *pSPacket; - SK_EVPARA Para; - - PortNumber = pMb->PortIdx; - pAPort = &pAC->Addr.Port[PortNumber]; - pRPort = &pAC->Rlmt.Port[PortNumber]; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)) - - pRPacket = (SK_RLMT_PACKET*)pMb->pData; - pSPacket = (SK_SPTREE_PACKET*)pRPacket; - -#ifdef xDEBUG - DumpData((char *)pRPacket, 32); -#endif /* DEBUG */ - - if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) { - SkRlmtPortReceives(pAC, IoC, PortNumber); - } - - /* Check destination address. */ - - if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) && - !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) && - !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) { - - /* Not sent to current MAC or registered MC address => Trash it. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Not for me.\n")) - - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - return; - } - else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) { - - /* - * Was sent by same port (may happen during port switching - * or in case of duplicate MAC addresses). - */ - - /* - * Check for duplicate address here: - * If Packet.Random != My.Random => DupAddr. - */ - for (i = 3; i >= 0; i--) { - if (pRPort->Random[i] != pRPacket->Random[i]) { - break; - } - } - - /* - * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply - * packets (they have the LLC_COMMAND_RESPONSE_BIT set in - * pRPacket->SSap). - */ - if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP && - pRPacket->Ctrl == SK_RLMT_CTRL && - pRPacket->SSap == SK_RLMT_SSAP && - pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && - pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && - pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && - pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && - pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && - pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && - pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Duplicate MAC Address.\n")) - - /* Error Log entry. */ - SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG); - } - else { - /* Simply trash it. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Sent by me.\n")) - } - - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - return; - } - - /* Check SuspectTx entries. */ - if (pRPort->PortsSuspect > 0) { - for (j = 0; j < pRPort->PortsChecked; j++) { - if (pRPort->PortCheck[j].SuspectTx && - SK_ADDR_EQUAL( - pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) { - pRPort->PortCheck[j].SuspectTx = SK_FALSE; - pRPort->PortsSuspect--; - break; - } - } - } - - /* Determine type of packet. */ - if (pRPacket->DSap == SK_RLMT_DSAP && - pRPacket->Ctrl == SK_RLMT_CTRL && - (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP && - pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && - pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && - pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && - pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && - pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && - pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && - pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { - - /* It's an RLMT packet. */ - PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) | - pRPacket->RlmtPacketType[1]); - - switch (PacketType) { - case SK_PACKET_ANNOUNCE: /* Not yet used. */ -#if 0 - /* Build the check chain. */ - SkRlmtBuildCheckChain(pAC); -#endif /* 0 */ - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Announce.\n")) - - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - break; - - case SK_PACKET_ALIVE: - if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Alive Reply.\n")) - - if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) || - SK_ADDR_EQUAL( - pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) { - /* Obviously we could send something. */ - if (pRPort->CheckingState & SK_RLMT_PCS_TX) { - pRPort->CheckingState &= ~SK_RLMT_PCS_TX; - SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); - } - - if ((pRPort->PortState == SK_RLMT_PS_DOWN) && - !(pRPort->CheckingState & SK_RLMT_PCS_RX)) { - pRPort->PortState = SK_RLMT_PS_GOING_UP; - pRPort->GuTimeStamp = SkOsGetTime(pAC); - - SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); - - Para.Para32[0] = PortNumber; - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->UpTimer, - SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, - SK_RLMT_PORTUP_TIM, Para); - } - } - - /* Mark sending port as alive? */ - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - } - else { /* Alive Request Packet. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Alive Request.\n")) - - pRPort->RxHelloCts++; - - /* Answer. */ - for (i = 0; i < SK_MAC_ADDR_LEN; i++) { - pRPacket->DstAddr[i] = pRPacket->SrcAddr[i]; - pRPacket->SrcAddr[i] = - pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; - } - pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT; - - Para.pParaPtr = pMb; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - break; - - case SK_PACKET_CHECK_TX: - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Check your tx line.\n")) - - /* A port checking us requests us to check our tx line. */ - pRPort->CheckingState |= SK_RLMT_PCS_TX; - - /* Start PortDownTx timer. */ - Para.Para32[0] = PortNumber; - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->DownTxTimer, - SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, - SK_RLMT_PORTDOWN_TX_TIM, Para); - - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - - if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, - SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, - &SkRlmtMcAddr)) != NULL) { - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - break; - - case SK_PACKET_ADDR_CHANGED: - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Address Change.\n")) - - /* Build the check chain. */ - SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Unknown RLMT packet.\n")) - - /* RA;:;: ??? */ - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - } - } - else if (pSPacket->DSap == SK_RLMT_SPT_DSAP && - pSPacket->Ctrl == SK_RLMT_SPT_CTRL && - (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: BPDU Packet.\n")) - - /* Spanning Tree packet. */ - pRPort->RxSpHelloCts++; - - if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt. - Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) { - /* - * Check segmentation if a new root bridge is set and - * the segmentation check is not currently running. - */ - if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) && - (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && - (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) - != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState & - SK_RLMT_RCS_SEG) == 0) { - pAC->Rlmt.Port[PortNumber].Net->CheckingState |= - SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; - } - - /* Store tree view of this port. */ - for (i = 0; i < 8; i++) { - pRPort->Root.Id[i] = pSPacket->RootId[i]; - } - pRPort->RootIdSet = SK_TRUE; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, - ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", - PortNumber, - pRPort->Root.Id[0], pRPort->Root.Id[1], - pRPort->Root.Id[2], pRPort->Root.Id[3], - pRPort->Root.Id[4], pRPort->Root.Id[5], - pRPort->Root.Id[6], pRPort->Root.Id[7])) - } - - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState & - SK_RLMT_RCS_REPORT_SEG) != 0) { - SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber); - } - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Unknown Packet Type.\n")) - - /* Unknown packet. */ - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - } - return; -} /* SkRlmtPacketReceive */ - - -/****************************************************************************** - * - * SkRlmtCheckPort - check if a port works - * - * Description: - * This routine checks if a port whose link is up received something - * and if it seems to transmit successfully. - * - * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp - * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg - * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg - * - * if (Rx - RxBpdu == 0) { # No rx. - * if (state == PsUp) { - * PortCheckingState |= ChkRx - * } - * if (ModeCheckSeg && (Timeout == - * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) { - * RlmtCheckingState |= ChkSeg) - * PortCheckingState |= ChkSeg - * } - * NewTimeout = TO_SHORTEN(Timeout) - * if (NewTimeout < RLMT_MIN_TIMEOUT) { - * NewTimeout = RLMT_MIN_TIMEOUT - * PortState = PsDown - * ... - * } - * } - * else { # something was received - * # Set counter to 0 at LinkDown? - * # No - rx may be reported after LinkDown ??? - * PortCheckingState &= ~ChkRx - * NewTimeout = RLMT_DEFAULT_TIMEOUT - * if (RxAck == 0) { - * possible reasons: - * is my tx line bad? -- - * send RLMT multicast and report - * back internally? (only possible - * between ports on same adapter) - * } - * if (RxChk == 0) { - * possible reasons: - * - tx line of port set to check me - * maybe bad - * - no other port/adapter available or set - * to check me - * - adapter checking me has a longer - * timeout - * ??? anything that can be done here? - * } - * } - * - * Context: - * runtime, pageable? - * - * Returns: - * New timeout value. - */ -RLMT_STATIC SK_U32 SkRlmtCheckPort( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber) /* Port to check */ -{ - unsigned i; - SK_U32 NewTimeout; - SK_RLMT_PORT *pRPort; - SK_EVPARA Para; - - pRPort = &pAC->Rlmt.Port[PortNumber]; - - if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n", - PortNumber, pRPort->PacketsPerTimeSlot)) - - /* - * Check segmentation if there was no receive at least twice - * in a row (PortNoRx is already set) and the segmentation - * check is not currently running. - */ - - if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && - (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && - !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) { - pAC->Rlmt.Port[PortNumber].Net->CheckingState |= - SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n", - pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)) - - if (pRPort->PortState != SK_RLMT_PS_DOWN) { - NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue); - if (NewTimeout < SK_RLMT_MIN_TO_VAL) { - NewTimeout = SK_RLMT_MIN_TO_VAL; - } - - if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) { - Para.Para32[0] = PortNumber; - pRPort->CheckingState |= SK_RLMT_PCS_RX; - - /* - * What shall we do if the port checked by this one receives - * our request frames? What's bad - our rx line or his tx line? - */ - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->DownRxTimer, - SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, - SK_RLMT_PORTDOWN_RX_TIM, Para); - - for (i = 0; i < pRPort->PortsChecked; i++) { - if (pRPort->PortCheck[i].SuspectTx) { - continue; - } - pRPort->PortCheck[i].SuspectTx = SK_TRUE; - pRPort->PortsSuspect++; - if ((Para.pParaPtr = - SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX, - &pAC->Addr.Port[PortNumber].CurrentMacAddress, - &pRPort->PortCheck[i].CheckAddr)) != NULL) { - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - } - } - } - else { /* PortDown -- or all partners suspect. */ - NewTimeout = SK_RLMT_DEF_TO_VAL; - } - pRPort->PortNoRx = SK_TRUE; - } - else { /* A non-BPDU packet was received. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n", - PortNumber, - pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot, - pRPort->PacketsPerTimeSlot)) - - SkRlmtPortReceives(pAC, IoC, PortNumber); - if (pAC->Rlmt.CheckSwitch) { - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - } - - NewTimeout = SK_RLMT_DEF_TO_VAL; - } - - return (NewTimeout); -} /* SkRlmtCheckPort */ - - -/****************************************************************************** - * - * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP) - * - * Description: - * This routine selects the port that received a broadcast frame - * substantially later than all other ports. - * - * Context: - * runtime, pageable? - * - * Returns: - * SK_BOOL - */ -RLMT_STATIC SK_BOOL SkRlmtSelectBcRx( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Active, /* Active port */ -SK_U32 PrefPort, /* Preferred port */ -SK_U32 *pSelect) /* New active port */ -{ - SK_U64 BcTimeStamp; - SK_U32 i; - SK_BOOL PortFound; - - BcTimeStamp = 0; /* Not totally necessary, but feeling better. */ - PortFound = SK_FALSE; - - /* Select port with the latest TimeStamp. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n", - i, - pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, - *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), - *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) - - if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { - if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { - BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp; - *pSelect = i; - PortFound = SK_TRUE; - } - } - } - - if (PortFound) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d received the last broadcast.\n", *pSelect)) - - /* Look if another port's time stamp is similar. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (i == *pSelect) { - continue; - } - if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx && - (pAC->Rlmt.Port[i].BcTimeStamp > - BcTimeStamp - SK_RLMT_BC_DELTA || - pAC->Rlmt.Port[i].BcTimeStamp + - SK_RLMT_BC_DELTA > BcTimeStamp)) { - PortFound = SK_FALSE; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d received a broadcast at a similar time.\n", i)) - break; - } - } - } - -#ifdef DEBUG - if (PortFound) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " - "latest broadcast (%u).\n", - *pSelect, - BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) - } -#endif /* DEBUG */ - - return (PortFound); -} /* SkRlmtSelectBcRx */ - - -/****************************************************************************** - * - * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP) - * - * Description: - * This routine selects a good port (it is PortUp && !SuspectRx). - * - * Context: - * runtime, pageable? - * - * Returns: - * SK_BOOL - */ -RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Active, /* Active port */ -SK_U32 PrefPort, /* Preferred port */ -SK_U32 *pSelect) /* New active port */ -{ - SK_U32 i; - SK_BOOL PortFound; - - PortFound = SK_FALSE; - - /* Select first port that is PortUp && !SuspectRx. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (!pAC->Rlmt.Port[i].PortDown && - !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) { - *pSelect = i; - if (!pAC->Rlmt.Port[Active].PortDown && - !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) { - *pSelect = Active; - } - if (!pAC->Rlmt.Port[PrefPort].PortDown && - !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) { - *pSelect = PrefPort; - } - PortFound = SK_TRUE; - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", - *pSelect)) - break; - } - } - return (PortFound); -} /* SkRlmtSelectNotSuspect */ - - -/****************************************************************************** - * - * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP) - * - * Description: - * This routine selects a port that is up. - * - * Context: - * runtime, pageable? - * - * Returns: - * SK_BOOL - */ -RLMT_STATIC SK_BOOL SkRlmtSelectUp( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Active, /* Active port */ -SK_U32 PrefPort, /* Preferred port */ -SK_U32 *pSelect, /* New active port */ -SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ -{ - SK_U32 i; - SK_BOOL PortFound; - - PortFound = SK_FALSE; - - /* Select first port that is PortUp. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP && - pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { - *pSelect = i; - if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP && - pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { - *pSelect = Active; - } - if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP && - pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { - *pSelect = PrefPort; - } - PortFound = SK_TRUE; - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) - break; - } - } - return (PortFound); -} /* SkRlmtSelectUp */ - - -/****************************************************************************** - * - * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP) - * - * Description: - * This routine selects the port that is going up for the longest time. - * - * Context: - * runtime, pageable? - * - * Returns: - * SK_BOOL - */ -RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Active, /* Active port */ -SK_U32 PrefPort, /* Preferred port */ -SK_U32 *pSelect, /* New active port */ -SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ -{ - SK_U64 GuTimeStamp; - SK_U32 i; - SK_BOOL PortFound; - - GuTimeStamp = 0; - PortFound = SK_FALSE; - - /* Select port that is PortGoingUp for the longest time. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && - pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { - GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; - *pSelect = i; - PortFound = SK_TRUE; - break; - } - } - - if (!PortFound) { - return (SK_FALSE); - } - - for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && - pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp && - pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { - GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; - *pSelect = i; - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) - return (SK_TRUE); -} /* SkRlmtSelectGoingUp */ - - -/****************************************************************************** - * - * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP) - * - * Description: - * This routine selects a port that is down. - * - * Context: - * runtime, pageable? - * - * Returns: - * SK_BOOL - */ -RLMT_STATIC SK_BOOL SkRlmtSelectDown( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Active, /* Active port */ -SK_U32 PrefPort, /* Preferred port */ -SK_U32 *pSelect, /* New active port */ -SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ -{ - SK_U32 i; - SK_BOOL PortFound; - - PortFound = SK_FALSE; - - /* Select first port that is PortDown. */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN && - pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { - *pSelect = i; - if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN && - pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { - *pSelect = Active; - } - if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN && - pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { - *pSelect = PrefPort; - } - PortFound = SK_TRUE; - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) - break; - } - } - return (PortFound); -} /* SkRlmtSelectDown */ - - -/****************************************************************************** - * - * SkRlmtCheckSwitch - select new active port and switch to it - * - * Description: - * This routine decides which port should be the active one and queues - * port switching if necessary. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing. - */ -RLMT_STATIC void SkRlmtCheckSwitch( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 NetIdx) /* Net index */ -{ - SK_EVPARA Para; - SK_U32 Active; - SK_U32 PrefPort; - SK_U32 i; - SK_BOOL PortFound; - - Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */ - PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */ - PortFound = SK_FALSE; - pAC->Rlmt.CheckSwitch = SK_FALSE; - -#if 0 /* RW 2001/10/18 - active port becomes always prefered one */ - if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */ - /* disable auto-fail back */ - PrefPort = Active; - } -#endif - - if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) { - /* Last link went down - shut down the net. */ - pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN; - Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP; - Para.Para32[1] = NetIdx; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para); - - Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. - Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; - Para.Para32[1] = NetIdx; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); - return; - } /* pAC->Rlmt.LinksUp == 0 */ - else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 && - pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) { - /* First link came up - get the net up. */ - pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP; - - /* - * If pAC->Rlmt.ActivePort != Para.Para32[0], - * the DRV switches to the port that came up. - */ - for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { - if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { - if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) { - i = Active; - } - if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) { - i = PrefPort; - } - PortFound = SK_TRUE; - break; - } - } - - if (PortFound) { - Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; - Para.Para32[1] = NetIdx; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); - - pAC->Rlmt.Net[NetIdx].ActivePort = i; - Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; - Para.Para32[1] = NetIdx; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); - - if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && - (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, - pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, - SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. - CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { - /* - * Send announce packet to RLMT multicast address to force - * switches to learn the new location of the logical MAC address. - */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG); - } - - return; - } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */ - else { /* Cannot be reached in dual-net mode. */ - Para.Para32[0] = Active; - - /* - * Preselection: - * If RLMT Mode != CheckLinkState - * select port that received a broadcast frame substantially later - * than all other ports - * else select first port that is not SuspectRx - * else select first port that is PortUp - * else select port that is PortGoingUp for the longest time - * else select first port that is PortDown - * else stop. - * - * For the preselected port: - * If ActivePort is equal in quality, select ActivePort. - * - * If PrefPort is equal in quality, select PrefPort. - * - * If ActivePort != SelectedPort, - * If old ActivePort is LinkDown, - * SwitchHard - * else - * SwitchSoft - */ - /* check of ChgBcPrio flag added */ - if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && - (!pAC->Rlmt.Net[0].ChgBcPrio)) { - - if (!PortFound) { - PortFound = SkRlmtSelectBcRx( - pAC, IoC, Active, PrefPort, &Para.Para32[1]); - } - - if (!PortFound) { - PortFound = SkRlmtSelectNotSuspect( - pAC, IoC, Active, PrefPort, &Para.Para32[1]); - } - } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ - - /* with changed priority for last broadcast received */ - if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && - (pAC->Rlmt.Net[0].ChgBcPrio)) { - if (!PortFound) { - PortFound = SkRlmtSelectNotSuspect( - pAC, IoC, Active, PrefPort, &Para.Para32[1]); - } - - if (!PortFound) { - PortFound = SkRlmtSelectBcRx( - pAC, IoC, Active, PrefPort, &Para.Para32[1]); - } - } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ - - if (!PortFound) { - PortFound = SkRlmtSelectUp( - pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); - } - - if (!PortFound) { - PortFound = SkRlmtSelectUp( - pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); - } - - if (!PortFound) { - PortFound = SkRlmtSelectGoingUp( - pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); - } - - if (!PortFound) { - PortFound = SkRlmtSelectGoingUp( - pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); - } - - if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { - if (!PortFound) { - PortFound = SkRlmtSelectDown(pAC, IoC, - Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); - } - - if (!PortFound) { - PortFound = SkRlmtSelectDown(pAC, IoC, - Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); - } - } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ - - if (PortFound) { - - if (Para.Para32[1] != Active) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) - pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; - Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. - Port[Para.Para32[0]]->PortNumber; - Para.Para32[1] = pAC->Rlmt.Net[NetIdx]. - Port[Para.Para32[1]]->PortNumber; - SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE); - if (pAC->Rlmt.Port[Active].LinkDown) { - SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para); - } - else { - SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); - SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para); - } - Para.Para32[1] = NetIdx; - Para.Para32[0] = - pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); - Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. - Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); - if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && - (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], - SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress, - &SkRlmtMcAddr)) != NULL) { - /* - * Send announce packet to RLMT multicast address to force - * switches to learn the new location of the logical - * MAC address. - */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); - } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */ - } /* Para.Para32[1] != Active */ - } /* PortFound */ - else { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG); - } - } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */ - return; -} /* SkRlmtCheckSwitch */ - - -/****************************************************************************** - * - * SkRlmtCheckSeg - Report if segmentation is detected - * - * Description: - * This routine checks if the ports see different root bridges and reports - * segmentation in such a case. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing. - */ -RLMT_STATIC void SkRlmtCheckSeg( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 NetIdx) /* Net number */ -{ - SK_EVPARA Para; - SK_RLMT_NET *pNet; - SK_U32 i, j; - SK_BOOL Equal; - - pNet = &pAC->Rlmt.Net[NetIdx]; - pNet->RootIdSet = SK_FALSE; - Equal = SK_TRUE; - - for (i = 0; i < pNet->NumPorts; i++) { - if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) { - continue; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, - ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i, - pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], - pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], - pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], - pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) - - if (!pNet->RootIdSet) { - pNet->Root = pNet->Port[i]->Root; - pNet->RootIdSet = SK_TRUE; - continue; - } - - for (j = 0; j < 8; j ++) { - Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j]; - if (!Equal) { - break; - } - } - - if (!Equal) { - SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG); - Para.Para32[0] = NetIdx; - Para.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para); - - pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG; - - /* 2000-03-06 RA: New. */ - Para.Para32[0] = NetIdx; - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL, - SKGE_RLMT, SK_RLMT_SEG_TIM, Para); - break; - } - } /* for (i = 0; i < pNet->NumPorts; i++) */ - - /* 2000-03-06 RA: Moved here. */ - /* Segmentation check not running anymore. */ - pNet->CheckingState &= ~SK_RLMT_RCS_SEG; - -} /* SkRlmtCheckSeg */ - - -/****************************************************************************** - * - * SkRlmtPortStart - initialize port variables and start port - * - * Description: - * This routine initializes a port's variables and issues a PORT_START - * to the HWAC module. This handles retries if the start fails or the - * link eventually goes down. - * - * Context: - * runtime, pageable? - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtPortStart( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 PortNumber) /* Port number */ -{ - SK_EVPARA Para; - - pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN; - pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE; - pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE; - pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE; - pAC->Rlmt.Port[PortNumber].CheckingState = 0; - pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; - Para.Para32[0] = PortNumber; - Para.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); -} /* SkRlmtPortStart */ - - -/****************************************************************************** - * - * SkRlmtEvtPortStartTim - PORT_START_TIM - * - * Description: - * This routine handles PORT_START_TIM events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPortStartTim( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ -{ - SK_U32 i; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) - return; - } - - /* - * Used to start non-preferred ports if the preferred one - * does not come up. - * This timeout needs only be set when starting the first - * (preferred) port. - */ - if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { - /* PORT_START failed. */ - for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) { - if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) { - SkRlmtPortStart(pAC, IoC, - pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber); - } - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")) -} /* SkRlmtEvtPortStartTim */ - - -/****************************************************************************** - * - * SkRlmtEvtLinkUp - LINK_UP - * - * Description: - * This routine handles LLINK_UP events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtLinkUp( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ -{ - SK_U32 i; - SK_RLMT_PORT *pRPort; - SK_EVPARA Para2; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) - - pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; - if (!pRPort->PortStarted) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event EMPTY.\n")) - return; - } - - if (!pRPort->LinkDown) { - /* RA;:;: Any better solution? */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event EMPTY.\n")) - return; - } - - SkTimerStop(pAC, IoC, &pRPort->UpTimer); - SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); - SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); - - /* Do something if timer already fired? */ - - pRPort->LinkDown = SK_FALSE; - pRPort->PortState = SK_RLMT_PS_GOING_UP; - pRPort->GuTimeStamp = SkOsGetTime(pAC); - pRPort->BcTimeStamp = 0; - pRPort->Net->LinksUp++; - if (pRPort->Net->LinksUp == 1) { - SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE); - } - else { - SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); - } - - for (i = 0; i < pRPort->Net->NumPorts; i++) { - if (!pRPort->Net->Port[i]->PortStarted) { - SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber); - } - } - - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - - if (pRPort->Net->LinksUp >= 2) { - if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { - /* Build the check chain. */ - SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); - } - } - - /* If the first link comes up, start the periodical RLMT timeout. */ - if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 && - (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) { - Para2.Para32[0] = pRPort->Net->NetNumber; - Para2.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer, - pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2); - } - - Para2 = Para; - Para2.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, - SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); - - /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ - if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && - (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && - (Para2.pParaPtr = - SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, - &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) - ) != NULL) { - /* Send "new" packet to RLMT multicast address. */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); - } - - if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { - if ((Para2.pParaPtr = - SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) { - pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE; - pRPort->Net->CheckingState |= - SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; - - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); - - Para.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer, - SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event END.\n")) -} /* SkRlmtEvtLinkUp */ - - -/****************************************************************************** - * - * SkRlmtEvtPortUpTim - PORT_UP_TIM - * - * Description: - * This routine handles PORT_UP_TIM events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPortUpTim( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ -{ - SK_RLMT_PORT *pRPort; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) - return; - } - - pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; - if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) - return; - } - - pRPort->PortDown = SK_FALSE; - pRPort->PortState = SK_RLMT_PS_UP; - pRPort->Net->PortsUp++; - if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { - if (pAC->Rlmt.NumNets <= 1) { - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - } - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para); - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Event END.\n")) -} /* SkRlmtEvtPortUpTim */ - - -/****************************************************************************** - * - * SkRlmtEvtPortDownTim - PORT_DOWN_* - * - * Description: - * This routine handles PORT_DOWN_* events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPortDownX( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Event, /* Event code */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ -{ - SK_RLMT_PORT *pRPort; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", - Para.Para32[0], Event)) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) - return; - } - - pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; - if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && - !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) - return; - } - - /* Stop port's timers. */ - SkTimerStop(pAC, IoC, &pRPort->UpTimer); - SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); - SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); - - if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) { - pRPort->PortState = SK_RLMT_PS_DOWN; - } - - if (!pRPort->PortDown) { - pRPort->Net->PortsUp--; - pRPort->PortDown = SK_TRUE; - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para); - } - - pRPort->PacketsPerTimeSlot = 0; - /* pRPort->DataPacketsPerTimeSlot = 0; */ - pRPort->BpduPacketsPerTimeSlot = 0; - pRPort->BcTimeStamp = 0; - - /* - * RA;:;: To be checked: - * - actions at RLMT_STOP: We should not switch anymore. - */ - if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { - if (Para.Para32[0] == - pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) { - /* Active Port went down. */ - SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)) -} /* SkRlmtEvtPortDownX */ - - -/****************************************************************************** - * - * SkRlmtEvtLinkDown - LINK_DOWN - * - * Description: - * This routine handles LINK_DOWN events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtLinkDown( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ -{ - SK_RLMT_PORT *pRPort; - - pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])) - - if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { - pRPort->Net->LinksUp--; - pRPort->LinkDown = SK_TRUE; - pRPort->PortState = SK_RLMT_PS_LINK_DOWN; - SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF); - - if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) { - /* Build the check chain. */ - SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); - } - - /* Ensure that port is marked down. */ - Para.Para32[1] = -1; - (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para); - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_DOWN Event END.\n")) -} /* SkRlmtEvtLinkDown */ - - -/****************************************************************************** - * - * SkRlmtEvtPortAddr - PORT_ADDR - * - * Description: - * This routine handles PORT_ADDR events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPortAddr( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ -{ - SK_U32 i, j; - SK_RLMT_PORT *pRPort; - SK_MAC_ADDR *pOldMacAddr; - SK_MAC_ADDR *pNewMacAddr; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Event EMPTY.\n")) - return; - } - - /* Port's physical MAC address changed. */ - pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress; - pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress; - - /* - * NOTE: This is not scalable for solutions where ports are - * checked remotely. There, we need to send an RLMT - * address change packet - and how do we ensure delivery? - */ - for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { - pRPort = &pAC->Rlmt.Port[i]; - for (j = 0; j < pRPort->PortsChecked; j++) { - if (SK_ADDR_EQUAL( - pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) { - pRPort->PortCheck[j].CheckAddr = *pNewMacAddr; - } - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Event END.\n")) -} /* SkRlmtEvtPortAddr */ - - -/****************************************************************************** - * - * SkRlmtEvtStart - START - * - * Description: - * This routine handles START events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtStart( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ - SK_EVPARA Para2; - SK_U32 PortIdx; - SK_U32 PortNumber; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) - return; - } - - if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) - return; - } - - if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("All nets should have been started.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) - return; - } - - if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >= - pAC->Rlmt.Net[Para.Para32[0]].NumPorts) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG); - - /* Change PrefPort to internal default. */ - Para2.Para32[0] = 0xFFFFFFFF; - Para2.Para32[1] = Para.Para32[0]; - (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2); - } - - PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort; - PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber; - - pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0; - pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0; - pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0; - pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN; - - /* Start preferred port. */ - SkRlmtPortStart(pAC, IoC, PortNumber); - - /* Start Timer (for first port only). */ - Para2.Para32[0] = PortNumber; - Para2.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer, - SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2); - - pAC->Rlmt.NetsStarted++; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event END.\n")) -} /* SkRlmtEvtStart */ - - -/****************************************************************************** - * - * SkRlmtEvtStop - STOP - * - * Description: - * This routine handles STOP events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtStop( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ - SK_EVPARA Para2; - SK_U32 PortNumber; - SK_U32 i; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) - return; - } - - if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) - return; - } - - if (pAC->Rlmt.NetsStarted == 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("All nets are stopped.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) - return; - } - - /* Stop RLMT timers. */ - SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer); - SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer); - - /* Stop net. */ - pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT; - pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE; - Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL; - Para2.Para32[1] = Para.Para32[0]; /* Net# */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2); - - /* Stop ports. */ - for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { - PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber; - if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) { - SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer); - SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer); - SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer); - - pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT; - pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; - pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE; - Para2.Para32[0] = PortNumber; - Para2.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2); - } - } - - pAC->Rlmt.NetsStarted--; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event END.\n")) -} /* SkRlmtEvtStop */ - - -/****************************************************************************** - * - * SkRlmtEvtTim - TIM - * - * Description: - * This routine handles TIM events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtTim( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ - SK_RLMT_PORT *pRPort; - SK_U32 Timeout; - SK_U32 NewTimeout; - SK_U32 PortNumber; - SK_U32 i; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event BEGIN.\n")) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event EMPTY.\n")) - return; - } - - if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 || - pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) { - /* Mode changed or all links down: No more link checking. */ - return; - } - -#if 0 - pAC->Rlmt.SwitchCheckCounter--; - if (pAC->Rlmt.SwitchCheckCounter == 0) { - pAC->Rlmt.SwitchCheckCounter; - } -#endif /* 0 */ - - NewTimeout = SK_RLMT_DEF_TO_VAL; - for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { - PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber; - pRPort = &pAC->Rlmt.Port[PortNumber]; - if (!pRPort->LinkDown) { - Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber); - if (Timeout < NewTimeout) { - NewTimeout = Timeout; - } - - /* - * These counters should be set to 0 for all ports before the - * first frame is sent in the next loop. - */ - pRPort->PacketsPerTimeSlot = 0; - /* pRPort->DataPacketsPerTimeSlot = 0; */ - pRPort->BpduPacketsPerTimeSlot = 0; - } - } - pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout; - - if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) { - /* - * If checking remote ports, also send packets if - * (LinksUp == 1) && - * this port checks at least one (remote) port. - */ - - /* - * Must be new loop, as SkRlmtCheckPort can request to - * check segmentation when e.g. checking the last port. - */ - for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { - if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) { - SkRlmtSend(pAC, IoC, - pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber); - } - } - } - - SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer, - pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, - Para); - - if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 && - (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) && - (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) { - SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer, - SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); - pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG; - pAC->Rlmt.Net[Para.Para32[0]].CheckingState |= - SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event END.\n")) -} /* SkRlmtEvtTim */ - - -/****************************************************************************** - * - * SkRlmtEvtSegTim - SEG_TIM - * - * Description: - * This routine handles SEG_TIM events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtSegTim( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ -#ifdef xDEBUG - int j; -#endif /* DEBUG */ - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event BEGIN.\n")) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event EMPTY.\n")) - return; - } - -#ifdef xDEBUG - for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) { - SK_ADDR_PORT *pAPort; - SK_U32 k; - SK_U16 *InAddr; - SK_U8 InAddr8[6]; - - InAddr = (SK_U16 *)&InAddr8[0]; - pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort; - for (k = 0; k < pAPort->NextExactMatchRlmt; k++) { - /* Get exact match address k from port j. */ - XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber, - XM_EXM(k), InAddr); - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n", - k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber, - InAddr8[0], InAddr8[1], InAddr8[2], - InAddr8[3], InAddr8[4], InAddr8[5], - pAPort->Exact[k].a[0], pAPort->Exact[k].a[1], - pAPort->Exact[k].a[2], pAPort->Exact[k].a[3], - pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])) - } - } -#endif /* xDEBUG */ - - SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event END.\n")) -} /* SkRlmtEvtSegTim */ - - -/****************************************************************************** - * - * SkRlmtEvtPacketRx - PACKET_RECEIVED - * - * Description: - * This routine handles PACKET_RECEIVED events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPacketRx( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_MBUF *pMb */ -{ - SK_MBUF *pMb; - SK_MBUF *pNextMb; - SK_U32 NetNumber; - - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")) - - /* Should we ignore frames during port switching? */ - -#ifdef DEBUG - pMb = Para.pParaPtr; - if (pMb == NULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")) - } - else if (pMb->pNext != NULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("More than one mbuf or pMb->pNext not set.\n")) - } -#endif /* DEBUG */ - - for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) { - pNextMb = pMb->pNext; - pMb->pNext = NULL; - - NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber; - if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) { - SkDrvFreeRlmtMbuf(pAC, IoC, pMb); - } - else { - SkRlmtPacketReceive(pAC, IoC, pMb); - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PACKET_RECEIVED Event END.\n")) -} /* SkRlmtEvtPacketRx */ - - -/****************************************************************************** - * - * SkRlmtEvtStatsClear - STATS_CLEAR - * - * Description: - * This routine handles STATS_CLEAR events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtStatsClear( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ - SK_U32 i; - SK_RLMT_PORT *pRPort; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) - return; - } - - /* Clear statistics for logical and physical ports. */ - for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) { - pRPort = - &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber]; - pRPort->TxHelloCts = 0; - pRPort->RxHelloCts = 0; - pRPort->TxSpHelloReqCts = 0; - pRPort->RxSpHelloCts = 0; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event END.\n")) -} /* SkRlmtEvtStatsClear */ - - -/****************************************************************************** - * - * SkRlmtEvtStatsUpdate - STATS_UPDATE - * - * Description: - * This routine handles STATS_UPDATE events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtStatsUpdate( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) - return; - } - - /* Update statistics - currently always up-to-date. */ - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event END.\n")) -} /* SkRlmtEvtStatsUpdate */ - - -/****************************************************************************** - * - * SkRlmtEvtPrefportChange - PREFPORT_CHANGE - * - * Description: - * This routine handles PREFPORT_CHANGE events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtPrefportChange( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])) - - if (Para.Para32[1] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[1])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) - return; - } - - /* 0xFFFFFFFF == auto-mode. */ - if (Para.Para32[0] == 0xFFFFFFFF) { - pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT; - } - else { - if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) - return; - } - - pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0]; - } - - pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0]; - - if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) { - SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]); - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event END.\n")) -} /* SkRlmtEvtPrefportChange */ - - -/****************************************************************************** - * - * SkRlmtEvtSetNets - SET_NETS - * - * Description: - * This routine handles SET_NETS events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtSetNets( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */ -{ - int i; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event BEGIN.\n")) - - if (Para.Para32[1] != (SK_U32)-1) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS || - Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad number of nets: %d.\n", Para.Para32[0])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) - return; - } - - /* Entering and leaving dual mode only allowed while nets are stopped. */ - if (pAC->Rlmt.NetsStarted > 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Changing dual mode only allowed while all nets are stopped.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) - return; - } - - if (Para.Para32[0] == 1) { - if (pAC->Rlmt.NumNets > 1) { - /* Clear logical MAC addr from second net's active port. */ - (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr. - Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL); - pAC->Rlmt.Net[1].NumPorts = 0; - } - - pAC->Rlmt.NumNets = Para.Para32[0]; - for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) { - pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; - pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; - pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */ - pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; - /* Just assuming. */ - pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; - pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; - pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; - pAC->Rlmt.Net[i].NetNumber = i; - } - - pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0]; - pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; - - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("RLMT: Changed to one net with two ports.\n")) - } - else if (Para.Para32[0] == 2) { - pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1]; - pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1; - pAC->Rlmt.Net[0].NumPorts = - pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts; - - pAC->Rlmt.NumNets = Para.Para32[0]; - for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) { - pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; - pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; - pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */ - pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; - /* Just assuming. */ - pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; - pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; - pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; - - pAC->Rlmt.Net[i].NetNumber = i; - } - - /* Set logical MAC addr on second net's active port. */ - (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr. - Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL); - - SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("RLMT: Changed to two nets with one port each.\n")) - } - else { - /* Not implemented for more than two nets. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SetNets not implemented for more than two nets.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) - return; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event END.\n")) -} /* SkRlmtSetNets */ - - -/****************************************************************************** - * - * SkRlmtEvtModeChange - MODE_CHANGE - * - * Description: - * This routine handles MODE_CHANGE events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * Nothing - */ -RLMT_STATIC void SkRlmtEvtModeChange( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */ -{ - SK_EVPARA Para2; - SK_U32 i; - SK_U32 PrevRlmtMode; - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")) - - if (Para.Para32[1] >= pAC->Rlmt.NumNets) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[1])) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) - return; - } - - Para.Para32[0] |= SK_RLMT_CHECK_LINK; - - if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) && - Para.Para32[0] != SK_RLMT_MODE_CLS) { - pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS; - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Forced RLMT mode to CLS on single port net.\n")) - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) - return; - } - - /* Update RLMT mode. */ - PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode; - pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0]; - - if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) != - (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) { - /* SK_RLMT_CHECK_LOC_LINK bit changed. */ - if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 && - pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 && - pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) { - /* 20001207 RA: Was "PortsUp == 1". */ - Para2.Para32[0] = Para.Para32[1]; - Para2.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer, - pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue, - SKGE_RLMT, SK_RLMT_TIM, Para2); - } - } - - if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) != - (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) { - /* SK_RLMT_CHECK_SEG bit changed. */ - for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) { - (void)SkAddrMcClear(pAC, IoC, - pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, - SK_ADDR_PERMANENT | SK_MC_SW_ONLY); - - /* Add RLMT MC address. */ - (void)SkAddrMcAdd(pAC, IoC, - pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, - &SkRlmtMcAddr, SK_ADDR_PERMANENT); - - if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & - SK_RLMT_CHECK_SEG) != 0) { - /* Add BPDU MC address. */ - (void)SkAddrMcAdd(pAC, IoC, - pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber, - &BridgeMcAddr, SK_ADDR_PERMANENT); - - if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) { - if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown && - (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket( - pAC, IoC, i)) != NULL) { - pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet = - SK_FALSE; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); - } - } - } - (void)SkAddrMcUpdate(pAC, IoC, - pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber); - } /* for ... */ - - if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) { - Para2.Para32[0] = Para.Para32[1]; - Para2.Para32[1] = (SK_U32)-1; - SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer, - SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2); - } - } /* SK_RLMT_CHECK_SEG bit changed. */ - - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event END.\n")) -} /* SkRlmtEvtModeChange */ - - -/****************************************************************************** - * - * SkRlmtEvent - a PORT- or an RLMT-specific event happened - * - * Description: - * This routine calls subroutines to handle PORT- and RLMT-specific events. - * - * Context: - * runtime, pageable? - * may be called after SK_INIT_IO - * - * Returns: - * 0 - */ -int SkRlmtEvent( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Event, /* Event code */ -SK_EVPARA Para) /* Event-specific parameter */ -{ - switch (Event) { - - /* ----- PORT events ----- */ - - case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */ - SkRlmtEvtPortStartTim(pAC, IoC, Para); - break; - case SK_RLMT_LINK_UP: /* From SIRQ. */ - SkRlmtEvtLinkUp(pAC, IoC, Para); - break; - case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */ - SkRlmtEvtPortUpTim(pAC, IoC, Para); - break; - case SK_RLMT_PORTDOWN: /* From RLMT. */ - case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */ - case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */ - SkRlmtEvtPortDownX(pAC, IoC, Event, Para); - break; - case SK_RLMT_LINK_DOWN: /* From SIRQ. */ - SkRlmtEvtLinkDown(pAC, IoC, Para); - break; - case SK_RLMT_PORT_ADDR: /* From ADDR. */ - SkRlmtEvtPortAddr(pAC, IoC, Para); - break; - - /* ----- RLMT events ----- */ - - case SK_RLMT_START: /* From DRV. */ - SkRlmtEvtStart(pAC, IoC, Para); - break; - case SK_RLMT_STOP: /* From DRV. */ - SkRlmtEvtStop(pAC, IoC, Para); - break; - case SK_RLMT_TIM: /* From RLMT via TIME. */ - SkRlmtEvtTim(pAC, IoC, Para); - break; - case SK_RLMT_SEG_TIM: - SkRlmtEvtSegTim(pAC, IoC, Para); - break; - case SK_RLMT_PACKET_RECEIVED: /* From DRV. */ - SkRlmtEvtPacketRx(pAC, IoC, Para); - break; - case SK_RLMT_STATS_CLEAR: /* From PNMI. */ - SkRlmtEvtStatsClear(pAC, IoC, Para); - break; - case SK_RLMT_STATS_UPDATE: /* From PNMI. */ - SkRlmtEvtStatsUpdate(pAC, IoC, Para); - break; - case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */ - SkRlmtEvtPrefportChange(pAC, IoC, Para); - break; - case SK_RLMT_MODE_CHANGE: /* From PNMI. */ - SkRlmtEvtModeChange(pAC, IoC, Para); - break; - case SK_RLMT_SET_NETS: /* From DRV. */ - SkRlmtEvtSetNets(pAC, IoC, Para); - break; - - /* ----- Unknown events ----- */ - - default: /* Create error log entry. */ - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Unknown RLMT Event %d.\n", Event)) - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG); - break; - } /* switch() */ - - return (0); -} /* SkRlmtEvent */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c deleted file mode 100644 index 4e462955ecd8..000000000000 --- a/drivers/net/sk98lin/sktimer.c +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************** - * - * Name: sktimer.c - * Project: Gigabit Ethernet Adapters, Event Scheduler Module - * Version: $Revision: 1.14 $ - * Date: $Date: 2003/09/16 13:46:51 $ - * Purpose: High level timer functions. - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - - -/* - * Event queue and dispatcher - */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell."; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#ifdef __C2MAN__ -/* - Event queue management. - - General Description: - - */ -intro() -{} -#endif - - -/* Forward declaration */ -static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart); - - -/* - * Inits the software timer - * - * needs to be called during Init level 1. - */ -void SkTimerInit( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc, /* IoContext */ -int Level) /* Init Level */ -{ - switch (Level) { - case SK_INIT_DATA: - pAC->Tim.StQueue = NULL; - break; - case SK_INIT_IO: - SkHwtInit(pAC, Ioc); - SkTimerDone(pAC, Ioc); - break; - default: - break; - } -} - -/* - * Stops a high level timer - * - If a timer is not in the queue the function returns normally, too. - */ -void SkTimerStop( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc, /* IoContext */ -SK_TIMER *pTimer) /* Timer Pointer to be started */ -{ - SK_TIMER **ppTimPrev; - SK_TIMER *pTm; - - /* - * remove timer from queue - */ - pTimer->TmActive = SK_FALSE; - - if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) { - SkHwtStop(pAC, Ioc); - } - - for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); - ppTimPrev = &pTm->TmNext ) { - - if (pTm == pTimer) { - /* - * Timer found in queue - * - dequeue it and - * - correct delta of the next timer - */ - *ppTimPrev = pTm->TmNext; - - if (pTm->TmNext) { - /* correct delta of next timer in queue */ - pTm->TmNext->TmDelta += pTm->TmDelta; - } - return; - } - } -} - -/* - * Start a high level software timer - */ -void SkTimerStart( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc, /* IoContext */ -SK_TIMER *pTimer, /* Timer Pointer to be started */ -SK_U32 Time, /* Time value */ -SK_U32 Class, /* Event Class for this timer */ -SK_U32 Event, /* Event Value for this timer */ -SK_EVPARA Para) /* Event Parameter for this timer */ -{ - SK_TIMER **ppTimPrev; - SK_TIMER *pTm; - SK_U32 Delta; - - Time /= 16; /* input is uS, clock ticks are 16uS */ - - if (!Time) - Time = 1; - - SkTimerStop(pAC, Ioc, pTimer); - - pTimer->TmClass = Class; - pTimer->TmEvent = Event; - pTimer->TmPara = Para; - pTimer->TmActive = SK_TRUE; - - if (!pAC->Tim.StQueue) { - /* First Timer to be started */ - pAC->Tim.StQueue = pTimer; - pTimer->TmNext = NULL; - pTimer->TmDelta = Time; - - SkHwtStart(pAC, Ioc, Time); - - return; - } - - /* - * timer correction - */ - timer_done(pAC, Ioc, 0); - - /* - * find position in queue - */ - Delta = 0; - for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); - ppTimPrev = &pTm->TmNext ) { - - if (Delta + pTm->TmDelta > Time) { - /* Position found */ - /* Here the timer needs to be inserted. */ - break; - } - Delta += pTm->TmDelta; - } - - /* insert in queue */ - *ppTimPrev = pTimer; - pTimer->TmNext = pTm; - pTimer->TmDelta = Time - Delta; - - if (pTm) { - /* There is a next timer - * -> correct its Delta value. - */ - pTm->TmDelta -= pTimer->TmDelta; - } - - /* restart with first */ - SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); -} - - -void SkTimerDone( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc) /* IoContext */ -{ - timer_done(pAC, Ioc, 1); -} - - -static void timer_done( -SK_AC *pAC, /* Adapters context */ -SK_IOC Ioc, /* IoContext */ -int Restart) /* Do we need to restart the Hardware timer ? */ -{ - SK_U32 Delta; - SK_TIMER *pTm; - SK_TIMER *pTComp; /* Timer completed now now */ - SK_TIMER **ppLast; /* Next field of Last timer to be deq */ - int Done = 0; - - Delta = SkHwtRead(pAC, Ioc); - - ppLast = &pAC->Tim.StQueue; - pTm = pAC->Tim.StQueue; - while (pTm && !Done) { - if (Delta >= pTm->TmDelta) { - /* Timer ran out */ - pTm->TmActive = SK_FALSE; - Delta -= pTm->TmDelta; - ppLast = &pTm->TmNext; - pTm = pTm->TmNext; - } - else { - /* We found the first timer that did not run out */ - pTm->TmDelta -= Delta; - Delta = 0; - Done = 1; - } - } - *ppLast = NULL; - /* - * pTm points to the first Timer that did not run out. - * StQueue points to the first Timer that run out. - */ - - for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { - SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara); - } - - /* Set head of timer queue to the first timer that did not run out */ - pAC->Tim.StQueue = pTm; - - if (Restart && pAC->Tim.StQueue) { - /* Restart HW timer */ - SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta); - } -} - -/* End of file */ diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c deleted file mode 100644 index 1e662aaebf84..000000000000 --- a/drivers/net/sk98lin/skvpd.c +++ /dev/null @@ -1,1091 +0,0 @@ -/****************************************************************************** - * - * Name: skvpd.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.37 $ - * Date: $Date: 2003/01/13 10:42:45 $ - * Purpose: Shared software to read and write VPD data - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2003 SysKonnect GmbH. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - Please refer skvpd.txt for information how to include this module - */ -static const char SysKonnectFileId[] = - "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK"; - -#include "h/skdrv1st.h" -#include "h/sktypes.h" -#include "h/skdebug.h" -#include "h/skdrv2nd.h" - -/* - * Static functions - */ -#ifndef SK_KR_PROTO -static SK_VPD_PARA *vpd_find_para( - SK_AC *pAC, - const char *key, - SK_VPD_PARA *p); -#else /* SK_KR_PROTO */ -static SK_VPD_PARA *vpd_find_para(); -#endif /* SK_KR_PROTO */ - -/* - * waits for a completion of a VPD transfer - * The VPD transfer must complete within SK_TICKS_PER_SEC/16 - * - * returns 0: success, transfer completes - * error exit(9) with a error message - */ -static int VpdWait( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -int event) /* event to wait for (VPD_READ / VPD_write) completion*/ -{ - SK_U64 start_time; - SK_U16 state; - - SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD wait for %s\n", event?"Write":"Read")); - start_time = SkOsGetTime(pAC); - do { - if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) { - - /* Bug fix AF: Thu Mar 28 2002 - * Do not call: VPD_STOP(pAC, IoC); - * A pending VPD read cycle can not be aborted by writing - * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register). - * Although the write threshold in the OUR-register protects - * VPD read only space from being overwritten this does not - * protect a VPD read from being `converted` into a VPD write - * operation (on the fly). As a consequence the VPD_STOP would - * delete VPD read only data. In case of any problems with the - * I2C bus we exit the loop here. The I2C read operation can - * not be aborted except by a reset (->LR). - */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR, - ("ERROR:VPD wait timeout\n")); - return(1); - } - - VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state); - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("state = %x, event %x\n",state,event)); - } while((int)(state & PCI_VPD_FLAG) == event); - - return(0); -} - -#ifdef SKDIAG - -/* - * Read the dword at address 'addr' from the VPD EEPROM. - * - * Needed Time: MIN 1,3 ms MAX 2,6 ms - * - * Note: The DWord is returned in the endianess of the machine the routine - * is running on. - * - * Returns the data read. - */ -SK_U32 VpdReadDWord( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -int addr) /* VPD address */ -{ - SK_U32 Rtv; - - /* start VPD read */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD read dword at 0x%x\n",addr)); - addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */ - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr); - - /* ignore return code here */ - (void)VpdWait(pAC, IoC, VPD_READ); - - /* Don't swap here, it's a data stream of bytes */ - Rtv = 0; - - VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv); - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD read dword data = 0x%x\n",Rtv)); - return(Rtv); -} - -#endif /* SKDIAG */ - -/* - * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from - * or to the I2C EEPROM. - * - * Returns number of bytes read / written. - */ -static int VpdWriteStream( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ -int Addr, /* VPD start address */ -int Len) /* number of bytes to read / to write */ -{ - int i; - int j; - SK_U16 AdrReg; - int Rtv; - SK_U8 * pComp; /* Compare pointer */ - SK_U8 Data; /* Input Data for Compare */ - - /* Init Compare Pointer */ - pComp = (SK_U8 *) buf; - - for (i = 0; i < Len; i++, buf++) { - if ((i%sizeof(SK_U32)) == 0) { - /* - * At the begin of each cycle read the Data Reg - * So it is initialized even if only a few bytes - * are written. - */ - AdrReg = (SK_U16) Addr; - AdrReg &= ~VPD_WRITE; /* READ operation */ - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - - /* Wait for termination */ - Rtv = VpdWait(pAC, IoC, VPD_READ); - if (Rtv != 0) { - return(i); - } - } - - /* Write current Byte */ - VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), - *(SK_U8*)buf); - - if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) { - /* New Address needs to be written to VPD_ADDR reg */ - AdrReg = (SK_U16) Addr; - Addr += sizeof(SK_U32); - AdrReg |= VPD_WRITE; /* WRITE operation */ - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - - /* Wait for termination */ - Rtv = VpdWait(pAC, IoC, VPD_WRITE); - if (Rtv != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("Write Timed Out\n")); - return(i - (i%sizeof(SK_U32))); - } - - /* - * Now re-read to verify - */ - AdrReg &= ~VPD_WRITE; /* READ operation */ - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - - /* Wait for termination */ - Rtv = VpdWait(pAC, IoC, VPD_READ); - if (Rtv != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("Verify Timed Out\n")); - return(i - (i%sizeof(SK_U32))); - } - - for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { - - VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); - - if (Data != *pComp) { - /* Verify Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("WriteStream Verify Error\n")); - return(i - (i%sizeof(SK_U32)) + j); - } - } - } - } - - return(Len); -} - - -/* - * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from - * or to the I2C EEPROM. - * - * Returns number of bytes read / written. - */ -static int VpdReadStream( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ -int Addr, /* VPD start address */ -int Len) /* number of bytes to read / to write */ -{ - int i; - SK_U16 AdrReg; - int Rtv; - - for (i = 0; i < Len; i++, buf++) { - if ((i%sizeof(SK_U32)) == 0) { - /* New Address needs to be written to VPD_ADDR reg */ - AdrReg = (SK_U16) Addr; - Addr += sizeof(SK_U32); - AdrReg &= ~VPD_WRITE; /* READ operation */ - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); - - /* Wait for termination */ - Rtv = VpdWait(pAC, IoC, VPD_READ); - if (Rtv != 0) { - return(i); - } - } - VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), - (SK_U8 *)buf); - } - - return(Len); -} - -/* - * Read ore writes 'len' bytes of VPD data, starting at 'addr' from - * or to the I2C EEPROM. - * - * Returns number of bytes read / written. - */ -static int VpdTransferBlock( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC, /* IO Context */ -char *buf, /* data buffer */ -int addr, /* VPD start address */ -int len, /* number of bytes to read / to write */ -int dir) /* transfer direction may be VPD_READ or VPD_WRITE */ -{ - int Rtv; /* Return value */ - int vpd_rom_size; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD %s block, addr = 0x%x, len = %d\n", - dir ? "write" : "read", addr, len)); - - if (len == 0) - return(0); - - vpd_rom_size = pAC->vpd.rom_size; - - if (addr > vpd_rom_size - 4) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Address error: 0x%x, exp. < 0x%x\n", - addr, vpd_rom_size - 4)); - return(0); - } - - if (addr + len > vpd_rom_size) { - len = vpd_rom_size - addr; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("Warning: len was cut to %d\n", len)); - } - - if (dir == VPD_READ) { - Rtv = VpdReadStream(pAC, IoC, buf, addr, len); - } - else { - Rtv = VpdWriteStream(pAC, IoC, buf, addr, len); - } - - return(Rtv); -} - -#ifdef SKDIAG - -/* - * Read 'len' bytes of VPD data, starting at 'addr'. - * - * Returns number of bytes read. - */ -int VpdReadBlock( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer were the data should be stored */ -int addr, /* start reading at the VPD address */ -int len) /* number of bytes to read */ -{ - return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); -} - -/* - * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'. - * - * Returns number of bytes writes. - */ -int VpdWriteBlock( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer, holds the data to write */ -int addr, /* start writing at the VPD address */ -int len) /* number of bytes to write */ -{ - return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)); -} -#endif /* SKDIAG */ - -/* - * (re)initialize the VPD buffer - * - * Reads the VPD data from the EEPROM into the VPD buffer. - * Get the remaining read only and read / write space. - * - * return 0: success - * 1: fatal VPD error - */ -static int VpdInit( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ -{ - SK_VPD_PARA *r, rp; /* RW or RV */ - int i; - unsigned char x; - int vpd_size; - SK_U16 dev_id; - SK_U32 our_reg2; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); - - VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id); - - VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); - - pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); - - /* - * this function might get used before the hardware is initialized - * therefore we cannot always trust in GIChipId - */ - if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 && - dev_id != VPD_DEV_ID_GENESIS) || - ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 && - !pAC->GIni.GIGenesis)) { - - /* for Yukon the VPD size is always 256 */ - vpd_size = VPD_SIZE_YUKON; - } - else { - /* Genesis uses the maximum ROM size up to 512 for VPD */ - if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) { - vpd_size = VPD_SIZE_GENESIS; - } - else { - vpd_size = pAC->vpd.rom_size; - } - } - - /* read the VPD data into the VPD buffer */ - if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ) - != vpd_size) { - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("Block Read Error\n")); - return(1); - } - - pAC->vpd.vpd_size = vpd_size; - - /* Asus K8V Se Deluxe bugfix. Correct VPD content */ - /* MBo April 2004 */ - if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) && - ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) && - ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) { - printk("sk98lin: Asus mainboard with buggy VPD? " - "Correcting data.\n"); - pAC->vpd.vpd_buf[0x40] = 0x38; - } - - - /* find the end tag of the RO area */ - if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: RV Tag not found\n")); - return(1); - } - - if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: Invalid VPD struct size\n")); - return(1); - } - pAC->vpd.v.vpd_free_ro = r->p_len - 1; - - /* test the checksum */ - for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) { - x += pAC->vpd.vpd_buf[i]; - } - - if (x != 0) { - /* checksum error */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("VPD Checksum Error\n")); - return(1); - } - - /* find and check the end tag of the RW area */ - if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: RV Tag not found\n")); - return(1); - } - - if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: Invalid VPD struct size\n")); - return(1); - } - pAC->vpd.v.vpd_free_rw = r->p_len; - - /* everything seems to be ok */ - if (pAC->GIni.GIChipId != 0) { - pAC->vpd.v.vpd_status |= VPD_VALID; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, - ("done. Free RO = %d, Free RW = %d\n", - pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); - - return(0); -} - -/* - * find the Keyword 'key' in the VPD buffer and fills the - * parameter struct 'p' with it's values - * - * returns *p success - * 0: parameter was not found or VPD encoding error - */ -static SK_VPD_PARA *vpd_find_para( -SK_AC *pAC, /* common data base */ -const char *key, /* keyword to find (e.g. "MN") */ -SK_VPD_PARA *p) /* parameter description struct */ -{ - char *v ; /* points to VPD buffer */ - int max; /* Maximum Number of Iterations */ - - v = pAC->vpd.vpd_buf; - max = 128; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD find para %s .. ",key)); - - /* check mandatory resource type ID string (Product Name) */ - if (*v != (char)RES_ID) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Error: 0x%x missing\n", RES_ID)); - return NULL; - } - - if (strcmp(key, VPD_NAME) == 0) { - p->p_len = VPD_GET_RES_LEN(v); - p->p_val = VPD_GET_VAL(v); - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("found, len = %d\n", p->p_len)); - return(p); - } - - v += 3 + VPD_GET_RES_LEN(v) + 3; - for (;; ) { - if (SK_MEMCMP(key,v,2) == 0) { - p->p_len = VPD_GET_VPD_LEN(v); - p->p_val = VPD_GET_VAL(v); - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("found, len = %d\n",p->p_len)); - return(p); - } - - /* exit when reaching the "RW" Tag or the maximum of itera. */ - max--; - if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) { - break; - } - - if (SK_MEMCMP(VPD_RV,v,2) == 0) { - v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ - } - else { - v += 3 + VPD_GET_VPD_LEN(v); - } - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])); - } - -#ifdef DEBUG - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n")); - if (max == 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Key/Len Encoding error\n")); - } -#endif /* DEBUG */ - return NULL; -} - -/* - * Move 'n' bytes. Begin with the last byte if 'n' is > 0, - * Start with the last byte if n is < 0. - * - * returns nothing - */ -static void vpd_move_para( -char *start, /* start of memory block */ -char *end, /* end of memory block to move */ -int n) /* number of bytes the memory block has to be moved */ -{ - char *p; - int i; /* number of byte copied */ - - if (n == 0) - return; - - i = (int) (end - start + 1); - if (n < 0) { - p = start + n; - while (i != 0) { - *p++ = *start++; - i--; - } - } - else { - p = end + n; - while (i != 0) { - *p-- = *end--; - i--; - } - } -} - -/* - * setup the VPD keyword 'key' at 'ip'. - * - * returns nothing - */ -static void vpd_insert_key( -const char *key, /* keyword to insert */ -const char *buf, /* buffer with the keyword value */ -int len, /* length of the value string */ -char *ip) /* inseration point */ -{ - SK_VPD_KEY *p; - - p = (SK_VPD_KEY *) ip; - p->p_key[0] = key[0]; - p->p_key[1] = key[1]; - p->p_len = (unsigned char) len; - SK_MEMCPY(&p->p_val,buf,len); -} - -/* - * Setup the VPD end tag "RV" / "RW". - * Also correct the remaining space variables vpd_free_ro / vpd_free_rw. - * - * returns 0: success - * 1: encoding error - */ -static int vpd_mod_endtag( -SK_AC *pAC, /* common data base */ -char *etp) /* end pointer input position */ -{ - SK_VPD_KEY *p; - unsigned char x; - int i; - int vpd_size; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])); - - vpd_size = pAC->vpd.vpd_size; - - p = (SK_VPD_KEY *) etp; - - if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) { - /* something wrong here, encoding error */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Encoding Error: invalid end tag\n")); - return(1); - } - if (etp > pAC->vpd.vpd_buf + vpd_size/2) { - /* create "RW" tag */ - p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1); - pAC->vpd.v.vpd_free_rw = (int) p->p_len; - i = pAC->vpd.v.vpd_free_rw; - etp += 3; - } - else { - /* create "RV" tag */ - p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3); - pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1; - - /* setup checksum */ - for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) { - x += pAC->vpd.vpd_buf[i]; - } - p->p_val = (char) 0 - x; - i = pAC->vpd.v.vpd_free_ro; - etp += 4; - } - while (i) { - *etp++ = 0x00; - i--; - } - - return(0); -} - -/* - * Insert a VPD keyword into the VPD buffer. - * - * The keyword 'key' is inserted at the position 'ip' in the - * VPD buffer. - * The keywords behind the input position will - * be moved. The VPD end tag "RV" or "RW" is generated again. - * - * returns 0: success - * 2: value string was cut - * 4: VPD full, keyword was not written - * 6: fatal VPD error - * - */ -static int VpdSetupPara( -SK_AC *pAC, /* common data base */ -const char *key, /* keyword to insert */ -const char *buf, /* buffer with the keyword value */ -int len, /* length of the keyword value */ -int type, /* VPD_RO_KEY or VPD_RW_KEY */ -int op) /* operation to do: ADD_KEY or OWR_KEY */ -{ - SK_VPD_PARA vp; - char *etp; /* end tag position */ - int free; /* remaining space in selected area */ - char *ip; /* input position inside the VPD buffer */ - int rtv; /* return code */ - int head; /* additional haeder bytes to move */ - int found; /* additinoal bytes if the keyword was found */ - int vpd_size; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD setup para key = %s, val = %s\n",key,buf)); - - vpd_size = pAC->vpd.vpd_size; - - rtv = 0; - ip = NULL; - if (type == VPD_RW_KEY) { - /* end tag is "RW" */ - free = pAC->vpd.v.vpd_free_rw; - etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3); - } - else { - /* end tag is "RV" */ - free = pAC->vpd.v.vpd_free_ro; - etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4); - } - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("Free RO = %d, Free RW = %d\n", - pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)); - - head = 0; - found = 0; - if (op == OWR_KEY) { - if (vpd_find_para(pAC, key, &vp)) { - found = 3; - ip = vp.p_val - 3; - free += vp.p_len + 3; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("Overwrite Key\n")); - } - else { - op = ADD_KEY; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("Add Key\n")); - } - } - if (op == ADD_KEY) { - ip = etp; - vp.p_len = 0; - head = 3; - } - - if (len + 3 > free) { - if (free < 7) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD Buffer Overflow, keyword not written\n")); - return(4); - } - /* cut it again */ - len = free - 3; - rtv = 2; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD Buffer Full, Keyword was cut\n")); - } - - vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head); - vpd_insert_key(key, buf, len, ip); - if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) { - pAC->vpd.v.vpd_status &= ~VPD_VALID; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD Encoding Error\n")); - return(6); - } - - return(rtv); -} - - -/* - * Read the contents of the VPD EEPROM and copy it to the - * VPD buffer if not already done. - * - * return: A pointer to the vpd_status structure. The structure contains - * this fields. - */ -SK_VPD_STATUS *VpdStat( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ -{ - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - (void)VpdInit(pAC, IoC); - } - return(&pAC->vpd.v); -} - - -/* - * Read the contents of the VPD EEPROM and copy it to the VPD - * buffer if not already done. - * Scan the VPD buffer for VPD keywords and create the VPD - * keyword list by copying the keywords to 'buf', all after - * each other and terminated with a '\0'. - * - * Exceptions: o The Resource Type ID String (product name) is called "Name" - * o The VPD end tags 'RV' and 'RW' are not listed - * - * The number of copied keywords is counted in 'elements'. - * - * returns 0: success - * 2: buffer overfull, one or more keywords are missing - * 6: fatal VPD error - * - * example values after returning: - * - * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0" - * *len = 30 - * *elements = 9 - */ -int VpdKeys( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *buf, /* buffer where to copy the keywords */ -int *len, /* buffer length */ -int *elements) /* number of keywords returned */ -{ - char *v; - int n; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. ")); - *elements = 0; - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - if (VpdInit(pAC, IoC) != 0) { - *len = 0; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD Init Error, terminated\n")); - return(6); - } - } - - if ((signed)strlen(VPD_NAME) + 1 <= *len) { - v = pAC->vpd.vpd_buf; - strcpy(buf,VPD_NAME); - n = strlen(VPD_NAME) + 1; - buf += n; - *elements = 1; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, - ("'%c%c' ",v[0],v[1])); - } - else { - *len = 0; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, - ("buffer overflow\n")); - return(2); - } - - v += 3 + VPD_GET_RES_LEN(v) + 3; - for (;; ) { - /* exit when reaching the "RW" Tag */ - if (SK_MEMCMP(VPD_RW,v,2) == 0) { - break; - } - - if (SK_MEMCMP(VPD_RV,v,2) == 0) { - v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ - continue; - } - - if (n+3 <= *len) { - SK_MEMCPY(buf,v,2); - buf += 2; - *buf++ = '\0'; - n += 3; - v += 3 + VPD_GET_VPD_LEN(v); - *elements += 1; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, - ("'%c%c' ",v[0],v[1])); - } - else { - *len = n; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("buffer overflow\n")); - return(2); - } - } - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n")); - *len = n; - return(0); -} - - -/* - * Read the contents of the VPD EEPROM and copy it to the - * VPD buffer if not already done. Search for the VPD keyword - * 'key' and copy its value to 'buf'. Add a terminating '\0'. - * If the value does not fit into the buffer cut it after - * 'len' - 1 bytes. - * - * returns 0: success - * 1: keyword not found - * 2: value string was cut - * 3: VPD transfer timeout - * 6: fatal VPD error - */ -int VpdRead( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -const char *key, /* keyword to read (e.g. "MN") */ -char *buf, /* buffer where to copy the keyword value */ -int *len) /* buffer length */ -{ - SK_VPD_PARA *p, vp; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key)); - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - if (VpdInit(pAC, IoC) != 0) { - *len = 0; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD init error\n")); - return(6); - } - } - - if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { - if (p->p_len > (*(unsigned *)len)-1) { - p->p_len = *len - 1; - } - SK_MEMCPY(buf, p->p_val, p->p_len); - buf[p->p_len] = '\0'; - *len = p->p_len; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, - ("%c%c%c%c.., len = %d\n", - buf[0],buf[1],buf[2],buf[3],*len)); - } - else { - *len = 0; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n")); - return(1); - } - return(0); -} - - -/* - * Check whether a given key may be written - * - * returns - * SK_TRUE Yes it may be written - * SK_FALSE No it may be written - */ -SK_BOOL VpdMayWrite( -char *key) /* keyword to write (allowed values "Yx", "Vx") */ -{ - if ((*key != 'Y' && *key != 'V') || - key[1] < '0' || key[1] > 'Z' || - (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { - - return(SK_FALSE); - } - return(SK_TRUE); -} - -/* - * Read the contents of the VPD EEPROM and copy it to the VPD - * buffer if not already done. Insert/overwrite the keyword 'key' - * in the VPD buffer. Cut the keyword value if it does not fit - * into the VPD read / write area. - * - * returns 0: success - * 2: value string was cut - * 3: VPD transfer timeout - * 4: VPD full, keyword was not written - * 5: keyword cannot be written - * 6: fatal VPD error - */ -int VpdWrite( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -const char *key, /* keyword to write (allowed values "Yx", "Vx") */ -const char *buf) /* buffer where the keyword value can be read from */ -{ - int len; /* length of the keyword to write */ - int rtv; /* return code */ - int rtv2; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, - ("VPD write %s = %s\n",key,buf)); - - if ((*key != 'Y' && *key != 'V') || - key[1] < '0' || key[1] > 'Z' || - (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("illegal key tag, keyword not written\n")); - return(5); - } - - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - if (VpdInit(pAC, IoC) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD init error\n")); - return(6); - } - } - - rtv = 0; - len = strlen(buf); - if (len > VPD_MAX_LEN) { - /* cut it */ - len = VPD_MAX_LEN; - rtv = 2; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN)); - } - if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD write error\n")); - return(rtv2); - } - - return(rtv); -} - -/* - * Read the contents of the VPD EEPROM and copy it to the - * VPD buffer if not already done. Remove the VPD keyword - * 'key' from the VPD buffer. - * Only the keywords in the read/write area can be deleted. - * Keywords in the read only area cannot be deleted. - * - * returns 0: success, keyword was removed - * 1: keyword not found - * 5: keyword cannot be deleted - * 6: fatal VPD error - */ -int VpdDelete( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *key) /* keyword to read (e.g. "MN") */ -{ - SK_VPD_PARA *p, vp; - char *etp; - int vpd_size; - - vpd_size = pAC->vpd.vpd_size; - - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - if (VpdInit(pAC, IoC) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD init error\n")); - return(6); - } - } - - if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { - if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) { - /* try to delete read only keyword */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("cannot delete RO keyword\n")); - return(5); - } - - etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3); - - vpd_move_para(vp.p_val+vp.p_len, etp+2, - - ((int)(vp.p_len + 3))); - if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) { - pAC->vpd.v.vpd_status &= ~VPD_VALID; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD encoding error\n")); - return(6); - } - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("keyword not found\n")); - return(1); - } - - return(0); -} - -/* - * If the VPD buffer contains valid data write the VPD - * read/write area back to the VPD EEPROM. - * - * returns 0: success - * 3: VPD transfer timeout - */ -int VpdUpdate( -SK_AC *pAC, /* Adapters context */ -SK_IOC IoC) /* IO Context */ -{ - int vpd_size; - - vpd_size = pAC->vpd.vpd_size; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. ")); - if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) { - if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2, - vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) { - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("transfer timed out\n")); - return(3); - } - } - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n")); - return(0); -} - diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c deleted file mode 100644 index b4e75022a657..000000000000 --- a/drivers/net/sk98lin/skxmac2.c +++ /dev/null @@ -1,4160 +0,0 @@ -/****************************************************************************** - * - * Name: skxmac2.c - * Project: Gigabit Ethernet Adapters, Common Modules - * Version: $Revision: 1.102 $ - * Date: $Date: 2003/10/02 16:53:58 $ - * Purpose: Contains functions to initialize the MACs and PHYs - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * 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. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#include "h/skdrv1st.h" -#include "h/skdrv2nd.h" - -/* typedefs *******************************************************************/ - -/* BCOM PHY magic pattern list */ -typedef struct s_PhyHack { - int PhyReg; /* Phy register */ - SK_U16 PhyVal; /* Value to write */ -} BCOM_HACK; - -/* local variables ************************************************************/ - -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell."; -#endif - -#ifdef GENESIS -static BCOM_HACK BcomRegA1Hack[] = { - { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, - { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, - { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, - { 0, 0 } -}; -static BCOM_HACK BcomRegC0Hack[] = { - { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, - { 0x15, 0x0A04 }, { 0x18, 0x0420 }, - { 0, 0 } -}; -#endif - -/* function prototypes ********************************************************/ -#ifdef GENESIS -static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL); -static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int); -static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int); -#endif /* GENESIS */ -#ifdef YUKON -static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL); -static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int); -#endif /* YUKON */ -#ifdef OTHER_PHY -static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL); -static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL); -static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int); -static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int); -#endif /* OTHER_PHY */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmPhyRead() - Read from XMAC PHY register - * - * Description: reads a 16-bit word from XMAC PHY or ext. PHY - * - * Returns: - * nothing - */ -void SkXmPhyRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 SK_FAR *pVal) /* Pointer to Value */ -{ - SK_U16 Mmu; - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - /* write the PHY register's address */ - XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); - - /* get the PHY register's value */ - XM_IN16(IoC, Port, XM_PHY_DATA, pVal); - - if (pPrt->PhyType != SK_PHY_XMAC) { - do { - XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); - /* wait until 'Ready' is set */ - } while ((Mmu & XM_MMU_PHY_RDY) == 0); - - /* get the PHY register's value */ - XM_IN16(IoC, Port, XM_PHY_DATA, pVal); - } -} /* SkXmPhyRead */ - - -/****************************************************************************** - * - * SkXmPhyWrite() - Write to XMAC PHY register - * - * Description: writes a 16-bit word to XMAC PHY or ext. PHY - * - * Returns: - * nothing - */ -void SkXmPhyWrite( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 Val) /* Value */ -{ - SK_U16 Mmu; - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PhyType != SK_PHY_XMAC) { - do { - XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); - /* wait until 'Busy' is cleared */ - } while ((Mmu & XM_MMU_PHY_BUSY) != 0); - } - - /* write the PHY register's address */ - XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); - - /* write the PHY register's value */ - XM_OUT16(IoC, Port, XM_PHY_DATA, Val); - - if (pPrt->PhyType != SK_PHY_XMAC) { - do { - XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); - /* wait until 'Busy' is cleared */ - } while ((Mmu & XM_MMU_PHY_BUSY) != 0); - } -} /* SkXmPhyWrite */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmPhyRead() - Read from GPHY register - * - * Description: reads a 16-bit word from GPHY through MDIO - * - * Returns: - * nothing - */ -void SkGmPhyRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 SK_FAR *pVal) /* Pointer to Value */ -{ - SK_U16 Ctrl; - SK_GEPORT *pPrt; -#ifdef VCPU - u_long SimCyle; - u_long SimLowTime; - - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n", - PhyReg, SimCyle, SimLowTime); -#endif /* VCPU */ - - pPrt = &pAC->GIni.GP[Port]; - - /* set PHY-Register offset and 'Read' OpCode (= 1) */ - *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | - GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD); - - GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal); - - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - - /* additional check for MDC/MDIO activity */ - if ((Ctrl & GM_SMI_CT_BUSY) == 0) { - *pVal = 0; - return; - } - - *pVal |= GM_SMI_CT_BUSY; - - do { -#ifdef VCPU - VCPUwaitTime(1000); -#endif /* VCPU */ - - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - - /* wait until 'ReadValid' is set */ - } while (Ctrl == *pVal); - - /* get the PHY register's value */ - GM_IN16(IoC, Port, GM_SMI_DATA, pVal); - -#ifdef VCPU - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", - SimCyle, SimLowTime); -#endif /* VCPU */ - -} /* SkGmPhyRead */ - - -/****************************************************************************** - * - * SkGmPhyWrite() - Write to GPHY register - * - * Description: writes a 16-bit word to GPHY through MDIO - * - * Returns: - * nothing - */ -void SkGmPhyWrite( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 Val) /* Value */ -{ - SK_U16 Ctrl; - SK_GEPORT *pPrt; -#ifdef VCPU - SK_U32 DWord; - u_long SimCyle; - u_long SimLowTime; - - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n", - PhyReg, Val, SimCyle, SimLowTime); -#endif /* VCPU */ - - pPrt = &pAC->GIni.GP[Port]; - - /* write the PHY register's value */ - GM_OUT16(IoC, Port, GM_SMI_DATA, Val); - - /* set PHY-Register offset and 'Write' OpCode (= 0) */ - Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg); - - GM_OUT16(IoC, Port, GM_SMI_CTRL, Val); - - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - - /* additional check for MDC/MDIO activity */ - if ((Ctrl & GM_SMI_CT_BUSY) == 0) { - return; - } - - Val |= GM_SMI_CT_BUSY; - - do { -#ifdef VCPU - /* read Timer value */ - SK_IN32(IoC, B2_TI_VAL, &DWord); - - VCPUwaitTime(1000); -#endif /* VCPU */ - - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - - /* wait until 'Busy' is cleared */ - } while (Ctrl == Val); - -#ifdef VCPU - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", - SimCyle, SimLowTime); -#endif /* VCPU */ - -} /* SkGmPhyWrite */ -#endif /* YUKON */ - - -#ifdef SK_DIAG -/****************************************************************************** - * - * SkGePhyRead() - Read from PHY register - * - * Description: calls a read PHY routine dep. on board type - * - * Returns: - * nothing - */ -void SkGePhyRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 *pVal) /* Pointer to Value */ -{ - void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal); - - if (pAC->GIni.GIGenesis) { - r_func = SkXmPhyRead; - } - else { - r_func = SkGmPhyRead; - } - - r_func(pAC, IoC, Port, PhyReg, pVal); -} /* SkGePhyRead */ - - -/****************************************************************************** - * - * SkGePhyWrite() - Write to PHY register - * - * Description: calls a write PHY routine dep. on board type - * - * Returns: - * nothing - */ -void SkGePhyWrite( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Port, /* Port Index (MAC_1 + n) */ -int PhyReg, /* Register Address (Offset) */ -SK_U16 Val) /* Value */ -{ - void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val); - - if (pAC->GIni.GIGenesis) { - w_func = SkXmPhyWrite; - } - else { - w_func = SkGmPhyWrite; - } - - w_func(pAC, IoC, Port, PhyReg, Val); -} /* SkGePhyWrite */ -#endif /* SK_DIAG */ - - -/****************************************************************************** - * - * SkMacPromiscMode() - Enable / Disable Promiscuous Mode - * - * Description: - * enables / disables promiscuous mode by setting Mode Register (XMAC) or - * Receive Control Register (GMAC) dep. on board type - * - * Returns: - * nothing - */ -void SkMacPromiscMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL Enable) /* Enable / Disable */ -{ -#ifdef YUKON - SK_U16 RcReg; -#endif -#ifdef GENESIS - SK_U32 MdReg; -#endif - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - /* enable or disable promiscuous mode */ - if (Enable) { - MdReg |= XM_MD_ENA_PROM; - } - else { - MdReg &= ~XM_MD_ENA_PROM; - } - /* setup Mode Register */ - XM_OUT32(IoC, Port, XM_MODE, MdReg); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); - - /* enable or disable unicast and multicast filtering */ - if (Enable) { - RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); - } - else { - RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); - } - /* setup Receive Control Register */ - GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); - } -#endif /* YUKON */ - -} /* SkMacPromiscMode*/ - - -/****************************************************************************** - * - * SkMacHashing() - Enable / Disable Hashing - * - * Description: - * enables / disables hashing by setting Mode Register (XMAC) or - * Receive Control Register (GMAC) dep. on board type - * - * Returns: - * nothing - */ -void SkMacHashing( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL Enable) /* Enable / Disable */ -{ -#ifdef YUKON - SK_U16 RcReg; -#endif -#ifdef GENESIS - SK_U32 MdReg; -#endif - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - /* enable or disable hashing */ - if (Enable) { - MdReg |= XM_MD_ENA_HASH; - } - else { - MdReg &= ~XM_MD_ENA_HASH; - } - /* setup Mode Register */ - XM_OUT32(IoC, Port, XM_MODE, MdReg); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); - - /* enable or disable multicast filtering */ - if (Enable) { - RcReg |= GM_RXCR_MCF_ENA; - } - else { - RcReg &= ~GM_RXCR_MCF_ENA; - } - /* setup Receive Control Register */ - GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg); - } -#endif /* YUKON */ - -} /* SkMacHashing*/ - - -#ifdef SK_DIAG -/****************************************************************************** - * - * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register - * - * Description: - * The features - * - FCS stripping, SK_STRIP_FCS_ON/OFF - * - pad byte stripping, SK_STRIP_PAD_ON/OFF - * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF - * for inrange length error frames - * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF - * for frames > 1514 bytes - * - enable Rx of own packets SK_SELF_RX_ON/OFF - * - * for incoming packets may be enabled/disabled by this function. - * Additional modes may be added later. - * Multiple modes can be enabled/disabled at the same time. - * The new configuration is written to the Rx Command register immediately. - * - * Returns: - * nothing - */ -static void SkXmSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, - SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ -{ - SK_U16 OldRxCmd; - SK_U16 RxCmd; - - XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd); - - RxCmd = OldRxCmd; - - switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { - case SK_STRIP_FCS_ON: - RxCmd |= XM_RX_STRIP_FCS; - break; - case SK_STRIP_FCS_OFF: - RxCmd &= ~XM_RX_STRIP_FCS; - break; - } - - switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) { - case SK_STRIP_PAD_ON: - RxCmd |= XM_RX_STRIP_PAD; - break; - case SK_STRIP_PAD_OFF: - RxCmd &= ~XM_RX_STRIP_PAD; - break; - } - - switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) { - case SK_LENERR_OK_ON: - RxCmd |= XM_RX_LENERR_OK; - break; - case SK_LENERR_OK_OFF: - RxCmd &= ~XM_RX_LENERR_OK; - break; - } - - switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) { - case SK_BIG_PK_OK_ON: - RxCmd |= XM_RX_BIG_PK_OK; - break; - case SK_BIG_PK_OK_OFF: - RxCmd &= ~XM_RX_BIG_PK_OK; - break; - } - - switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) { - case SK_SELF_RX_ON: - RxCmd |= XM_RX_SELF_RX; - break; - case SK_SELF_RX_OFF: - RxCmd &= ~XM_RX_SELF_RX; - break; - } - - /* Write the new mode to the Rx command register if required */ - if (OldRxCmd != RxCmd) { - XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd); - } -} /* SkXmSetRxCmd */ - - -/****************************************************************************** - * - * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register - * - * Description: - * The features - * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF - * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF - * for frames > 1514 bytes - * - enable Rx of own packets SK_SELF_RX_ON/OFF - * - * for incoming packets may be enabled/disabled by this function. - * Additional modes may be added later. - * Multiple modes can be enabled/disabled at the same time. - * The new configuration is written to the Rx Command register immediately. - * - * Returns: - * nothing - */ -static void SkGmSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, - SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ -{ - SK_U16 OldRxCmd; - SK_U16 RxCmd; - - if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) { - - GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd); - - RxCmd = OldRxCmd; - - if ((Mode & SK_STRIP_FCS_ON) != 0) { - RxCmd |= GM_RXCR_CRC_DIS; - } - else { - RxCmd &= ~GM_RXCR_CRC_DIS; - } - /* Write the new mode to the Rx control register if required */ - if (OldRxCmd != RxCmd) { - GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); - } - } - - if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) { - - GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd); - - RxCmd = OldRxCmd; - - if ((Mode & SK_BIG_PK_OK_ON) != 0) { - RxCmd |= GM_SMOD_JUMBO_ENA; - } - else { - RxCmd &= ~GM_SMOD_JUMBO_ENA; - } - /* Write the new mode to the Rx control register if required */ - if (OldRxCmd != RxCmd) { - GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); - } - } -} /* SkGmSetRxCmd */ - - -/****************************************************************************** - * - * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register - * - * Description: modifies the MAC's Rx Control reg. dep. on board type - * - * Returns: - * nothing - */ -void SkMacSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Mode) /* Rx Mode */ -{ - if (pAC->GIni.GIGenesis) { - - SkXmSetRxCmd(pAC, IoC, Port, Mode); - } - else { - - SkGmSetRxCmd(pAC, IoC, Port, Mode); - } - -} /* SkMacSetRxCmd */ - - -/****************************************************************************** - * - * SkMacCrcGener() - Enable / Disable CRC Generation - * - * Description: enables / disables CRC generation dep. on board type - * - * Returns: - * nothing - */ -void SkMacCrcGener( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL Enable) /* Enable / Disable */ -{ - SK_U16 Word; - - if (pAC->GIni.GIGenesis) { - - XM_IN16(IoC, Port, XM_TX_CMD, &Word); - - if (Enable) { - Word &= ~XM_TX_NO_CRC; - } - else { - Word |= XM_TX_NO_CRC; - } - /* setup Tx Command Register */ - XM_OUT16(IoC, Port, XM_TX_CMD, Word); - } - else { - - GM_IN16(IoC, Port, GM_TX_CTRL, &Word); - - if (Enable) { - Word &= ~GM_TXCR_CRC_DIS; - } - else { - Word |= GM_TXCR_CRC_DIS; - } - /* setup Tx Control Register */ - GM_OUT16(IoC, Port, GM_TX_CTRL, Word); - } - -} /* SkMacCrcGener*/ - -#endif /* SK_DIAG */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmClrExactAddr() - Clear Exact Match Address Registers - * - * Description: - * All Exact Match Address registers of the XMAC 'Port' will be - * cleared starting with 'StartNum' up to (and including) the - * Exact Match address number of 'StopNum'. - * - * Returns: - * nothing - */ -void SkXmClrExactAddr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int StartNum, /* Begin with this Address Register Index (0..15) */ -int StopNum) /* Stop after finished with this Register Idx (0..15) */ -{ - int i; - SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; - - if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 || - StartNum > StopNum) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG); - return; - } - - for (i = StartNum; i <= StopNum; i++) { - XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); - } -} /* SkXmClrExactAddr */ -#endif /* GENESIS */ - - -/****************************************************************************** - * - * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO - * - * Description: - * Flush the transmit FIFO of the MAC specified by the index 'Port' - * - * Returns: - * nothing - */ -void SkMacFlushTxFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ -#ifdef GENESIS - SK_U32 MdReg; - - if (pAC->GIni.GIGenesis) { - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - - XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* no way to flush the FIFO we have to issue a reset */ - /* TBD */ - } -#endif /* YUKON */ - -} /* SkMacFlushTxFifo */ - - -/****************************************************************************** - * - * SkMacFlushRxFifo() - Flush the MAC's receive FIFO - * - * Description: - * Flush the receive FIFO of the MAC specified by the index 'Port' - * - * Returns: - * nothing - */ -static void SkMacFlushRxFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ -#ifdef GENESIS - SK_U32 MdReg; - - if (pAC->GIni.GIGenesis) { - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - - XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* no way to flush the FIFO we have to issue a reset */ - /* TBD */ - } -#endif /* YUKON */ - -} /* SkMacFlushRxFifo */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmSoftRst() - Do a XMAC software reset - * - * Description: - * The PHY registers should not be destroyed during this - * kind of software reset. Therefore the XMAC Software Reset - * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used! - * - * The software reset is done by - * - disabling the Rx and Tx state machine, - * - resetting the statistics module, - * - clear all other significant XMAC Mode, - * Command, and Control Registers - * - clearing the Hash Register and the - * Exact Match Address registers, and - * - flushing the XMAC's Rx and Tx FIFOs. - * - * Note: - * Another requirement when stopping the XMAC is to - * avoid sending corrupted frames on the network. - * Disabling the Tx state machine will NOT interrupt - * the currently transmitted frame. But we must take care - * that the Tx FIFO is cleared AFTER the current frame - * is complete sent to the network. - * - * It takes about 12ns to send a frame with 1538 bytes. - * One PCI clock goes at least 15ns (66MHz). Therefore - * after reading XM_GP_PORT back, we are sure that the - * transmitter is disabled AND idle. And this means - * we may flush the transmit FIFO now. - * - * Returns: - * nothing - */ -static void SkXmSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000}; - - /* reset the statistics module */ - XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT); - - /* disable all XMAC IRQs */ - XM_OUT16(IoC, Port, XM_IMSK, 0xffff); - - XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */ - - XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */ - XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */ - - /* disable all PHY IRQs */ - switch (pAC->GIni.GP[Port].PhyType) { - case SK_PHY_BCOM: - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0); - break; - case SK_PHY_NAT: - /* todo: National - SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */ - break; -#endif /* OTHER_PHY */ - } - - /* clear the Hash Register */ - XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr); - - /* clear the Exact Match Address registers */ - SkXmClrExactAddr(pAC, IoC, Port, 0, 15); - - /* clear the Source Check Address registers */ - XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr); - -} /* SkXmSoftRst */ - - -/****************************************************************************** - * - * SkXmHardRst() - Do a XMAC hardware reset - * - * Description: - * The XMAC of the specified 'Port' and all connected devices - * (PHY and SERDES) will receive a reset signal on its *Reset pins. - * External PHYs must be reset by clearing a bit in the GPIO register - * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns). - * - * ATTENTION: - * It is absolutely necessary to reset the SW_RST Bit first - * before calling this function. - * - * Returns: - * nothing - */ -static void SkXmHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U32 Reg; - int i; - int TOut; - SK_U16 Word; - - for (i = 0; i < 4; i++) { - /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); - - TOut = 0; - do { - if (TOut++ > 10000) { - /* - * Adapter seems to be in RESET state. - * Registers cannot be written. - */ - return; - } - - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST); - - SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word); - - } while ((Word & MFF_SET_MAC_RST) == 0); - } - - /* For external PHYs there must be special handling */ - if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { - - SK_IN32(IoC, B2_GP_IO, &Reg); - - if (Port == 0) { - Reg |= GP_DIR_0; /* set to output */ - Reg &= ~GP_IO_0; /* set PHY reset (active low) */ - } - else { - Reg |= GP_DIR_2; /* set to output */ - Reg &= ~GP_IO_2; /* set PHY reset (active low) */ - } - /* reset external PHY */ - SK_OUT32(IoC, B2_GP_IO, Reg); - - /* short delay */ - SK_IN32(IoC, B2_GP_IO, &Reg); - } -} /* SkXmHardRst */ - - -/****************************************************************************** - * - * SkXmClearRst() - Release the PHY & XMAC reset - * - * Description: - * - * Returns: - * nothing - */ -static void SkXmClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U32 DWord; - - /* clear HW reset */ - SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); - - if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { - - SK_IN32(IoC, B2_GP_IO, &DWord); - - if (Port == 0) { - DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */ - } - else { - DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */ - } - /* Clear PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - - /* Enable GMII interface */ - XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); - } -} /* SkXmClearRst */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmSoftRst() - Do a GMAC software reset - * - * Description: - * The GPHY registers should not be destroyed during this - * kind of software reset. - * - * Returns: - * nothing - */ -static void SkGmSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000}; - SK_U16 RxCtrl; - - /* reset the statistics module */ - - /* disable all GMAC IRQs */ - SK_OUT8(IoC, GMAC_IRQ_MSK, 0); - - /* disable all PHY IRQs */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); - - /* clear the Hash Register */ - GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash); - - /* Enable Unicast and Multicast filtering */ - GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); - - GM_OUT16(IoC, Port, GM_RX_CTRL, - (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)); - -} /* SkGmSoftRst */ - - -/****************************************************************************** - * - * SkGmHardRst() - Do a GMAC hardware reset - * - * Description: - * - * Returns: - * nothing - */ -static void SkGmHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U32 DWord; - - /* WA code for COMA mode */ - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { - - SK_IN32(IoC, B2_GP_IO, &DWord); - - DWord |= (GP_DIR_9 | GP_IO_9); - - /* set PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - } - - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); - - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); - -} /* SkGmHardRst */ - - -/****************************************************************************** - * - * SkGmClearRst() - Release the GPHY & GMAC reset - * - * Description: - * - * Returns: - * nothing - */ -static void SkGmClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U32 DWord; - -#ifdef XXX - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); - - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); -#endif /* XXX */ - - /* WA code for COMA mode */ - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { - - SK_IN32(IoC, B2_GP_IO, &DWord); - - DWord |= GP_DIR_9; /* set to output */ - DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ - - /* clear PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - } - - /* set HWCFG_MODE */ - DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | - GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | - (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : - GPC_HWCFG_GMII_FIB); - - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); - - /* release GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); - -#ifdef VCPU - VCpuWait(9000); -#endif /* VCPU */ - - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); - -#ifdef VCPU - VCpuWait(2000); - - SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord); - - SK_IN32(IoC, B0_ISRC, &DWord); -#endif /* VCPU */ - -} /* SkGmClearRst */ -#endif /* YUKON */ - - -/****************************************************************************** - * - * SkMacSoftRst() - Do a MAC software reset - * - * Description: calls a MAC software reset routine dep. on board type - * - * Returns: - * nothing - */ -void SkMacSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - /* disable receiver and transmitter */ - SkMacRxTxDisable(pAC, IoC, Port); - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SkXmSoftRst(pAC, IoC, Port); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmSoftRst(pAC, IoC, Port); - } -#endif /* YUKON */ - - /* flush the MAC's Rx and Tx FIFOs */ - SkMacFlushTxFifo(pAC, IoC, Port); - - SkMacFlushRxFifo(pAC, IoC, Port); - - pPrt->PState = SK_PRT_STOP; - -} /* SkMacSoftRst */ - - -/****************************************************************************** - * - * SkMacHardRst() - Do a MAC hardware reset - * - * Description: calls a MAC hardware reset routine dep. on board type - * - * Returns: - * nothing - */ -void SkMacHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SkXmHardRst(pAC, IoC, Port); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmHardRst(pAC, IoC, Port); - } -#endif /* YUKON */ - - pAC->GIni.GP[Port].PState = SK_PRT_RESET; - -} /* SkMacHardRst */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmInitMac() - Initialize the XMAC II - * - * Description: - * Initialize the XMAC of the specified port. - * The XMAC must be reset or stopped before calling this function. - * - * Note: - * The XMAC's Rx and Tx state machine is still disabled when returning. - * - * Returns: - * nothing - */ -void SkXmInitMac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - int i; - SK_U16 SWord; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PState == SK_PRT_STOP) { - /* Port State: SK_PRT_STOP */ - /* Verify that the reset bit is cleared */ - SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); - - if ((SWord & MFF_SET_MAC_RST) != 0) { - /* PState does not match HW state */ - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); - /* Correct it */ - pPrt->PState = SK_PRT_RESET; - } - } - - if (pPrt->PState == SK_PRT_RESET) { - - SkXmClearRst(pAC, IoC, Port); - - if (pPrt->PhyType != SK_PHY_XMAC) { - /* read Id from external PHY (all have the same address) */ - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1); - - /* - * Optimize MDIO transfer by suppressing preamble. - * Must be done AFTER first access to BCOM chip. - */ - XM_IN16(IoC, Port, XM_MMU_CMD, &SWord); - - XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE); - - if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) { - /* - * Workaround BCOM Errata for the C0 type. - * Write magic patterns to reserved registers. - */ - i = 0; - while (BcomRegC0Hack[i].PhyReg != 0) { - SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg, - BcomRegC0Hack[i].PhyVal); - i++; - } - } - else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) { - /* - * Workaround BCOM Errata for the A1 type. - * Write magic patterns to reserved registers. - */ - i = 0; - while (BcomRegA1Hack[i].PhyReg != 0) { - SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg, - BcomRegA1Hack[i].PhyVal); - i++; - } - } - - /* - * Workaround BCOM Errata (#10523) for all BCom PHYs. - * Disable Power Management after reset. - */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); - - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, - (SK_U16)(SWord | PHY_B_AC_DIS_PM)); - - /* PHY LED initialization is done in SkGeXmitLED() */ - } - - /* Dummy read the Interrupt source register */ - XM_IN16(IoC, Port, XM_ISRC, &SWord); - - /* - * The auto-negotiation process starts immediately after - * clearing the reset. The auto-negotiation process should be - * started by the SIRQ, therefore stop it here immediately. - */ - SkMacInitPhy(pAC, IoC, Port, SK_FALSE); - -#ifdef TEST_ONLY - /* temp. code: enable signal detect */ - /* WARNING: do not override GMII setting above */ - XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG); -#endif - } - - /* - * configure the XMACs Station Address - * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A - * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B - */ - for (i = 0; i < 3; i++) { - /* - * The following 2 statements are together endianess - * independent. Remember this when changing. - */ - SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); - - XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); - } - - /* Tx Inter Packet Gap (XM_TX_IPG): use default */ - /* Tx High Water Mark (XM_TX_HI_WM): use default */ - /* Tx Low Water Mark (XM_TX_LO_WM): use default */ - /* Host Request Threshold (XM_HT_THR): use default */ - /* Rx Request Threshold (XM_RX_THR): use default */ - /* Rx Low Water Mark (XM_RX_LO_WM): use default */ - - /* configure Rx High Water Mark (XM_RX_HI_WM) */ - XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM); - - /* Configure Tx Request Threshold */ - SWord = SK_XM_THR_SL; /* for single port */ - - if (pAC->GIni.GIMacsFound > 1) { - switch (pAC->GIni.GIPortUsage) { - case SK_RED_LINK: - SWord = SK_XM_THR_REDL; /* redundant link */ - break; - case SK_MUL_LINK: - SWord = SK_XM_THR_MULL; /* load balancing */ - break; - case SK_JUMBO_LINK: - SWord = SK_XM_THR_JUMBO; /* jumbo frames */ - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG); - break; - } - } - XM_OUT16(IoC, Port, XM_TX_THR, SWord); - - /* setup register defaults for the Tx Command Register */ - XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD); - - /* setup register defaults for the Rx Command Register */ - SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; - - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - SWord |= XM_RX_BIG_PK_OK; - } - - if (pPrt->PLinkMode == SK_LMODE_HALF) { - /* - * If in manual half duplex mode the other side might be in - * full duplex mode, so ignore if a carrier extension is not seen - * on frames received - */ - SWord |= XM_RX_DIS_CEXT; - } - - XM_OUT16(IoC, Port, XM_RX_CMD, SWord); - - /* - * setup register defaults for the Mode Register - * - Don't strip error frames to avoid Store & Forward - * on the Rx side. - * - Enable 'Check Station Address' bit - * - Enable 'Check Address Array' bit - */ - XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE); - - /* - * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) - * - Enable all bits excepting 'Octets Rx OK Low CntOv' - * and 'Octets Rx OK Hi Cnt Ov'. - */ - XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK); - - /* - * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) - * - Enable all bits excepting 'Octets Tx OK Low CntOv' - * and 'Octets Tx OK Hi Cnt Ov'. - */ - XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK); - - /* - * Do NOT init XMAC interrupt mask here. - * All interrupts remain disable until link comes up! - */ - - /* - * Any additional configuration changes may be done now. - * The last action is to enable the Rx and Tx state machine. - * This should be done after the auto-negotiation process - * has been completed successfully. - */ -} /* SkXmInitMac */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmInitMac() - Initialize the GMAC - * - * Description: - * Initialize the GMAC of the specified port. - * The GMAC must be reset or stopped before calling this function. - * - * Note: - * The GMAC's Rx and Tx state machine is still disabled when returning. - * - * Returns: - * nothing - */ -void SkGmInitMac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - int i; - SK_U16 SWord; - SK_U32 DWord; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PState == SK_PRT_STOP) { - /* Port State: SK_PRT_STOP */ - /* Verify that the reset bit is cleared */ - SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord); - - if ((DWord & GMC_RST_SET) != 0) { - /* PState does not match HW state */ - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); - /* Correct it */ - pPrt->PState = SK_PRT_RESET; - } - } - - if (pPrt->PState == SK_PRT_RESET) { - - SkGmHardRst(pAC, IoC, Port); - - SkGmClearRst(pAC, IoC, Port); - - /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - /* Auto-negotiation disabled */ - - /* get General Purpose Control */ - GM_IN16(IoC, Port, GM_GP_CTRL, &SWord); - - /* disable auto-update for speed, duplex and flow-control */ - SWord |= GM_GPCR_AU_ALL_DIS; - - /* setup General Purpose Control Register */ - GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); - - SWord = GM_GPCR_AU_ALL_DIS; - } - else { - SWord = 0; - } - - /* speed settings */ - switch (pPrt->PLinkSpeed) { - case SK_LSPEED_AUTO: - case SK_LSPEED_1000MBPS: - SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; - break; - case SK_LSPEED_100MBPS: - SWord |= GM_GPCR_SPEED_100; - break; - case SK_LSPEED_10MBPS: - break; - } - - /* duplex settings */ - if (pPrt->PLinkMode != SK_LMODE_HALF) { - /* set full duplex */ - SWord |= GM_GPCR_DUP_FULL; - } - - /* flow-control settings */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - /* set Pause Off */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); - /* disable Tx & Rx flow-control */ - SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; - break; - case SK_FLOW_MODE_LOC_SEND: - /* disable Rx flow-control */ - SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; - break; - case SK_FLOW_MODE_SYMMETRIC: - case SK_FLOW_MODE_SYM_OR_REM: - /* enable Tx & Rx flow-control */ - break; - } - - /* setup General Purpose Control Register */ - GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); - - /* dummy read the Interrupt Source Register */ - SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); - -#ifndef VCPU - /* read Id from PHY */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); - - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); -#endif /* VCPU */ - } - - (void)SkGmResetCounter(pAC, IoC, Port); - - /* setup Transmit Control Register */ - GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); - - /* setup Receive Control Register */ - GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | - GM_RXCR_CRC_DIS); - - /* setup Transmit Flow Control Register */ - GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); - - /* setup Transmit Parameter Register */ -#ifdef VCPU - GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); -#endif /* VCPU */ - - SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | - TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | - TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); - - GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); - - /* configure the Serial Mode Register */ -#ifdef VCPU - GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); -#endif /* VCPU */ - - SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); - - if (pPrt->PMacLimit4) { - /* reset of collision counter after 4 consecutive collisions */ - SWord |= GM_SMOD_LIMIT_4; - } - - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - /* enable jumbo mode (Max. Frame Length = 9018) */ - SWord |= GM_SMOD_JUMBO_ENA; - } - - GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); - - /* - * configure the GMACs Station Addresses - * in PROM you can find our addresses at: - * B2_MAC_1 = xx xx xx xx xx x0 virtual address - * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A - * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort - */ - - for (i = 0; i < 3; i++) { - /* - * The following 2 statements are together endianess - * independent. Remember this when changing. - */ - /* physical address: will be used for pause frames */ - SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); - -#ifdef WA_DEV_16 - /* WA for deviation #16 */ - if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) { - /* swap the address bytes */ - SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8); - - /* write to register in reversed order */ - GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord); - } - else { - GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); - } -#else - GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); -#endif /* WA_DEV_16 */ - - /* virtual address: will be used for data */ - SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); - - GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); - - /* reset Multicast filtering Hash registers 1-3 */ - GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); - } - - /* reset Multicast filtering Hash register 4 */ - GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0); - - /* enable interrupt mask for counter overflows */ - GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0); - GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); - GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); - -#if defined(SK_DIAG) || defined(DEBUG) - /* read General Purpose Status */ - GM_IN16(IoC, Port, GM_GP_STAT, &SWord); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("MAC Stat Reg.=0x%04X\n", SWord)); -#endif /* SK_DIAG || DEBUG */ - -#ifdef SK_DIAG - c_print("MAC Stat Reg=0x%04X\n", SWord); -#endif /* SK_DIAG */ - -} /* SkGmInitMac */ -#endif /* YUKON */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmInitDupMd() - Initialize the XMACs Duplex Mode - * - * Description: - * This function initializes the XMACs Duplex Mode. - * It should be called after successfully finishing - * the Auto-negotiation Process - * - * Returns: - * nothing - */ -static void SkXmInitDupMd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - switch (pAC->GIni.GP[Port].PLinkModeStatus) { - case SK_LMODE_STAT_AUTOHALF: - case SK_LMODE_STAT_HALF: - /* Configuration Actions for Half Duplex Mode */ - /* - * XM_BURST = default value. We are probable not quick - * enough at the 'XMAC' bus to burst 8kB. - * The XMAC stops bursting if no transmit frames - * are available or the burst limit is exceeded. - */ - /* XM_TX_RT_LIM = default value (15) */ - /* XM_TX_STIME = default value (0xff = 4096 bit times) */ - break; - case SK_LMODE_STAT_AUTOFULL: - case SK_LMODE_STAT_FULL: - /* Configuration Actions for Full Duplex Mode */ - /* - * The duplex mode is configured by the PHY, - * therefore it seems to be that there is nothing - * to do here. - */ - break; - case SK_LMODE_STAT_UNKNOWN: - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG); - break; - } -} /* SkXmInitDupMd */ - - -/****************************************************************************** - * - * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port - * - * Description: - * This function initializes the Pause Mode which should - * be used for this port. - * It should be called after successfully finishing - * the Auto-negotiation Process - * - * Returns: - * nothing - */ -static void SkXmInitPauseMd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U32 DWord; - SK_U16 Word; - - pPrt = &pAC->GIni.GP[Port]; - - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - - if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || - pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { - - /* Disable Pause Frame Reception */ - Word |= XM_MMU_IGN_PF; - } - else { - /* - * enabling pause frame reception is required for 1000BT - * because the XMAC is not reset if the link is going down - */ - /* Enable Pause Frame Reception */ - Word &= ~XM_MMU_IGN_PF; - } - - XM_OUT16(IoC, Port, XM_MMU_CMD, Word); - - XM_IN32(IoC, Port, XM_MODE, &DWord); - - if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC || - pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { - - /* - * Configure Pause Frame Generation - * Use internal and external Pause Frame Generation. - * Sending pause frames is edge triggered. - * Send a Pause frame with the maximum pause time if - * internal oder external FIFO full condition occurs. - * Send a zero pause time frame to re-start transmission. - */ - - /* XM_PAUSE_DA = '010000C28001' (default) */ - - /* XM_MAC_PTIME = 0xffff (maximum) */ - /* remember this value is defined in big endian (!) */ - XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); - - /* Set Pause Mode in Mode Register */ - DWord |= XM_PAUSE_MODE; - - /* Set Pause Mode in MAC Rx FIFO */ - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE); - } - else { - /* - * disable pause frame generation is required for 1000BT - * because the XMAC is not reset if the link is going down - */ - /* Disable Pause Mode in Mode Register */ - DWord &= ~XM_PAUSE_MODE; - - /* Disable Pause Mode in MAC Rx FIFO */ - SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); - } - - XM_OUT32(IoC, Port, XM_MODE, DWord); -} /* SkXmInitPauseMd*/ - - -/****************************************************************************** - * - * SkXmInitPhyXmac() - Initialize the XMAC Phy registers - * - * Description: initializes all the XMACs Phy registers - * - * Note: - * - * Returns: - * nothing - */ -static void SkXmInitPhyXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ - SK_GEPORT *pPrt; - SK_U16 Ctrl; - - pPrt = &pAC->GIni.GP[Port]; - Ctrl = 0; - - /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ - if (pPrt->PLinkMode == SK_LMODE_FULL) { - Ctrl |= PHY_CT_DUP_MD; - } - - /* - * Do NOT enable Auto-negotiation here. This would hold - * the link down because no IDLEs are transmitted - */ - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyXmac: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - Ctrl |= PHY_X_AN_HD; - break; - case SK_LMODE_AUTOFULL: - Ctrl |= PHY_X_AN_FD; - break; - case SK_LMODE_AUTOBOTH: - Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, - SKERR_HWI_E015MSG); - } - - /* Set Flow-control capabilities */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - Ctrl |= PHY_X_P_NO_PAUSE; - break; - case SK_FLOW_MODE_LOC_SEND: - Ctrl |= PHY_X_P_ASYM_MD; - break; - case SK_FLOW_MODE_SYMMETRIC: - Ctrl |= PHY_X_P_SYM_MD; - break; - case SK_FLOW_MODE_SYM_OR_REM: - Ctrl |= PHY_X_P_BOTH_MD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - - /* Write AutoNeg Advertisement Register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl); - - /* Restart Auto-negotiation */ - Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG; - } - - if (DoLoop) { - /* Set the Phy Loopback bit, too */ - Ctrl |= PHY_CT_LOOP; - } - - /* Write to the Phy control register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl); -} /* SkXmInitPhyXmac */ - - -/****************************************************************************** - * - * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers - * - * Description: initializes all the Broadcom Phy registers - * - * Note: - * - * Returns: - * nothing - */ -static void SkXmInitPhyBcom( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ - SK_GEPORT *pPrt; - SK_U16 Ctrl1; - SK_U16 Ctrl2; - SK_U16 Ctrl3; - SK_U16 Ctrl4; - SK_U16 Ctrl5; - - Ctrl1 = PHY_CT_SP1000; - Ctrl2 = 0; - Ctrl3 = PHY_SEL_TYPE; - Ctrl4 = PHY_B_PEC_EN_LTR; - Ctrl5 = PHY_B_AC_TX_TST; - - pPrt = &pAC->GIni.GP[Port]; - - /* manually Master/Slave ? */ - if (pPrt->PMSMode != SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_B_1000C_MSE; - - if (pPrt->PMSMode == SK_MS_MODE_MASTER) { - Ctrl2 |= PHY_B_1000C_MSC; - } - } - /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ - if (pPrt->PLinkMode == SK_LMODE_FULL) { - Ctrl1 |= PHY_CT_DUP_MD; - } - - /* Determine Master/Slave manually if not already done */ - if (pPrt->PMSMode == SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ - } - - /* - * Do NOT enable Auto-negotiation here. This would hold - * the link down because no IDLES are transmitted - */ - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyBcom: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ - - /* - * Workaround BCOM Errata #1 for the C5 type. - * 1000Base-T Link Acquisition Failure in Slave Mode - * Set Repeater/DTE bit 10 of the 1000Base-T Control Register - */ - Ctrl2 |= PHY_B_1000C_RD; - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - Ctrl2 |= PHY_B_1000C_AHD; - break; - case SK_LMODE_AUTOFULL: - Ctrl2 |= PHY_B_1000C_AFD; - break; - case SK_LMODE_AUTOBOTH: - Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, - SKERR_HWI_E015MSG); - } - - /* Set Flow-control capabilities */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - Ctrl3 |= PHY_B_P_NO_PAUSE; - break; - case SK_FLOW_MODE_LOC_SEND: - Ctrl3 |= PHY_B_P_ASYM_MD; - break; - case SK_FLOW_MODE_SYMMETRIC: - Ctrl3 |= PHY_B_P_SYM_MD; - break; - case SK_FLOW_MODE_SYM_OR_REM: - Ctrl3 |= PHY_B_P_BOTH_MD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - - /* Restart Auto-negotiation */ - Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; - } - - /* Initialize LED register here? */ - /* No. Please do it in SkDgXmitLed() (if required) and swap - init order of LEDs and XMAC. (MAl) */ - - /* Write 1000Base-T Control Register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); - - /* Write AutoNeg Advertisement Register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); - - if (DoLoop) { - /* Set the Phy Loopback bit, too */ - Ctrl1 |= PHY_CT_LOOP; - } - - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { - /* configure FIFO to high latency for transmission of ext. packets */ - Ctrl4 |= PHY_B_PEC_HIGH_LA; - - /* configure reception of extended packets */ - Ctrl5 |= PHY_B_AC_LONG_PACK; - - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5); - } - - /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); - - /* Write to the Phy control register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Control Reg=0x%04X\n", Ctrl1)); -} /* SkXmInitPhyBcom */ -#endif /* GENESIS */ - -#ifdef YUKON -/****************************************************************************** - * - * SkGmInitPhyMarv() - Initialize the Marvell Phy registers - * - * Description: initializes all the Marvell Phy registers - * - * Note: - * - * Returns: - * nothing - */ -static void SkGmInitPhyMarv( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ - SK_GEPORT *pPrt; - SK_U16 PhyCtrl; - SK_U16 C1000BaseT; - SK_U16 AutoNegAdv; - SK_U16 ExtPhyCtrl; - SK_U16 LedCtrl; - SK_BOOL AutoNeg; -#if defined(SK_DIAG) || defined(DEBUG) - SK_U16 PhyStat; - SK_U16 PhyStat1; - SK_U16 PhySpecStat; -#endif /* SK_DIAG || DEBUG */ - - pPrt = &pAC->GIni.GP[Port]; - - /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyMarv: Port %d, auto-negotiation %s\n", - Port, AutoNeg ? "ON" : "OFF")); - -#ifdef VCPU - VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", - Port, DoLoop); -#else /* VCPU */ - if (DoLoop) { - /* Set 'MAC Power up'-bit, set Manual MDI configuration */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, - PHY_M_PC_MAC_POW_UP); - } - else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { - /* Read Ext. PHY Specific Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); - - ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | - PHY_M_EC_MAC_S_MSK); - - ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | - PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); - } - - /* Read PHY Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); - - if (!AutoNeg) { - /* Disable Auto-negotiation */ - PhyCtrl &= ~PHY_CT_ANE; - } - - PhyCtrl |= PHY_CT_RESET; - /* Assert software reset */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); -#endif /* VCPU */ - - PhyCtrl = 0 /* PHY_CT_COL_TST */; - C1000BaseT = 0; - AutoNegAdv = PHY_SEL_TYPE; - - /* manually Master/Slave ? */ - if (pPrt->PMSMode != SK_MS_MODE_AUTO) { - /* enable Manual Master/Slave */ - C1000BaseT |= PHY_M_1000C_MSE; - - if (pPrt->PMSMode == SK_MS_MODE_MASTER) { - C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ - } - } - - /* Auto-negotiation ? */ - if (!AutoNeg) { - - if (pPrt->PLinkMode == SK_LMODE_FULL) { - /* Set Full Duplex Mode */ - PhyCtrl |= PHY_CT_DUP_MD; - } - - /* Set Master/Slave manually if not already done */ - if (pPrt->PMSMode == SK_MS_MODE_AUTO) { - C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ - } - - /* Set Speed */ - switch (pPrt->PLinkSpeed) { - case SK_LSPEED_AUTO: - case SK_LSPEED_1000MBPS: - PhyCtrl |= PHY_CT_SP1000; - break; - case SK_LSPEED_100MBPS: - PhyCtrl |= PHY_CT_SP100; - break; - case SK_LSPEED_10MBPS: - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, - SKERR_HWI_E019MSG); - } - - if (!DoLoop) { - PhyCtrl |= PHY_CT_RESET; - } - } - else { - /* Set Auto-negotiation advertisement */ - - if (pAC->GIni.GICopperType) { - /* Set Speed capabilities */ - switch (pPrt->PLinkSpeed) { - case SK_LSPEED_AUTO: - C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; - AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | - PHY_M_AN_10_FD | PHY_M_AN_10_HD; - break; - case SK_LSPEED_1000MBPS: - C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; - break; - case SK_LSPEED_100MBPS: - AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | - /* advertise 10Base-T also */ - PHY_M_AN_10_FD | PHY_M_AN_10_HD; - break; - case SK_LSPEED_10MBPS: - AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, - SKERR_HWI_E019MSG); - } - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - C1000BaseT &= ~PHY_M_1000C_AFD; - AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD); - break; - case SK_LMODE_AUTOFULL: - C1000BaseT &= ~PHY_M_1000C_AHD; - AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD); - break; - case SK_LMODE_AUTOBOTH: - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, - SKERR_HWI_E015MSG); - } - - /* Set Flow-control capabilities */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - AutoNegAdv |= PHY_B_P_NO_PAUSE; - break; - case SK_FLOW_MODE_LOC_SEND: - AutoNegAdv |= PHY_B_P_ASYM_MD; - break; - case SK_FLOW_MODE_SYMMETRIC: - AutoNegAdv |= PHY_B_P_SYM_MD; - break; - case SK_FLOW_MODE_SYM_OR_REM: - AutoNegAdv |= PHY_B_P_BOTH_MD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - } - else { /* special defines for FIBER (88E1011S only) */ - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - AutoNegAdv |= PHY_M_AN_1000X_AHD; - break; - case SK_LMODE_AUTOFULL: - AutoNegAdv |= PHY_M_AN_1000X_AFD; - break; - case SK_LMODE_AUTOBOTH: - AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, - SKERR_HWI_E015MSG); - } - - /* Set Flow-control capabilities */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - AutoNegAdv |= PHY_M_P_NO_PAUSE_X; - break; - case SK_FLOW_MODE_LOC_SEND: - AutoNegAdv |= PHY_M_P_ASYM_MD_X; - break; - case SK_FLOW_MODE_SYMMETRIC: - AutoNegAdv |= PHY_M_P_SYM_MD_X; - break; - case SK_FLOW_MODE_SYM_OR_REM: - AutoNegAdv |= PHY_M_P_BOTH_MD_X; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - } - - if (!DoLoop) { - /* Restart Auto-negotiation */ - PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; - } - } - -#ifdef VCPU - /* - * E-mail from Gu Lin (08-03-2002): - */ - - /* Program PHY register 30 as 16'h0708 for simulation speed up */ - SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); - - VCpuWait(2000); - -#else /* VCPU */ - - /* Write 1000Base-T Control Register */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); - - /* Write AutoNeg Advertisement Register */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); -#endif /* VCPU */ - - if (DoLoop) { - /* Set the PHY Loopback bit */ - PhyCtrl |= PHY_CT_LOOP; - -#ifdef XXX - /* Program PHY register 16 as 16'h0400 to force link good */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); -#endif /* XXX */ - -#ifndef VCPU - if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { - /* Write Ext. PHY Specific Control */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, - (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); - } -#endif /* VCPU */ - } -#ifdef TEST_ONLY - else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { - /* Write PHY Specific Control */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, - PHY_M_PC_EN_DET_MSK); - } -#endif - - /* Write to the PHY Control register */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); - -#ifdef VCPU - VCpuWait(2000); -#else - - LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); - - if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { - LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; - } - - if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { - LedCtrl |= PHY_M_LEDC_DP_CTRL; - } - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); - - if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { - /* only in forced 100 Mbps mode */ - if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, - PHY_M_LED_MO_100(MO_LED_ON)); - } - } - -#ifdef SK_DIAG - c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); - c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); - c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); - c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl); -#endif /* SK_DIAG */ - -#if defined(SK_DIAG) || defined(DEBUG) - /* Read PHY Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); - - /* Read 1000Base-T Control Register */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); - - /* Read AutoNeg Advertisement Register */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); - - /* Read Ext. PHY Specific Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); - - /* Read PHY Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Stat Reg.=0x%04X\n", PhyStat)); - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Stat Reg.=0x%04X\n", PhyStat1)); - - /* Read PHY Specific Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Spec Stat=0x%04X\n", PhySpecStat)); -#endif /* SK_DIAG || DEBUG */ - -#ifdef SK_DIAG - c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); - c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); - c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); - c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); - c_print("PHY Stat Reg=0x%04X\n", PhyStat); - c_print("PHY Stat Reg=0x%04X\n", PhyStat1); - c_print("PHY Spec Reg=0x%04X\n", PhySpecStat); -#endif /* SK_DIAG */ - -#endif /* VCPU */ - -} /* SkGmInitPhyMarv */ -#endif /* YUKON */ - - -#ifdef OTHER_PHY -/****************************************************************************** - * - * SkXmInitPhyLone() - Initialize the Level One Phy registers - * - * Description: initializes all the Level One Phy registers - * - * Note: - * - * Returns: - * nothing - */ -static void SkXmInitPhyLone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ - SK_GEPORT *pPrt; - SK_U16 Ctrl1; - SK_U16 Ctrl2; - SK_U16 Ctrl3; - - Ctrl1 = PHY_CT_SP1000; - Ctrl2 = 0; - Ctrl3 = PHY_SEL_TYPE; - - pPrt = &pAC->GIni.GP[Port]; - - /* manually Master/Slave ? */ - if (pPrt->PMSMode != SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_L_1000C_MSE; - - if (pPrt->PMSMode == SK_MS_MODE_MASTER) { - Ctrl2 |= PHY_L_1000C_MSC; - } - } - /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - /* - * level one spec say: "1000 Mbps: manual mode not allowed" - * but lets see what happens... - */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyLone: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ - if (pPrt->PLinkMode == SK_LMODE_FULL) { - Ctrl1 |= PHY_CT_DUP_MD; - } - - /* Determine Master/Slave manually if not already done */ - if (pPrt->PMSMode == SK_MS_MODE_AUTO) { - Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ - } - - /* - * Do NOT enable Auto-negotiation here. This would hold - * the link down because no IDLES are transmitted - */ - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyLone: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ - - /* Set Full/half duplex capabilities */ - switch (pPrt->PLinkMode) { - case SK_LMODE_AUTOHALF: - Ctrl2 |= PHY_L_1000C_AHD; - break; - case SK_LMODE_AUTOFULL: - Ctrl2 |= PHY_L_1000C_AFD; - break; - case SK_LMODE_AUTOBOTH: - Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, - SKERR_HWI_E015MSG); - } - - /* Set Flow-control capabilities */ - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - Ctrl3 |= PHY_L_P_NO_PAUSE; - break; - case SK_FLOW_MODE_LOC_SEND: - Ctrl3 |= PHY_L_P_ASYM_MD; - break; - case SK_FLOW_MODE_SYMMETRIC: - Ctrl3 |= PHY_L_P_SYM_MD; - break; - case SK_FLOW_MODE_SYM_OR_REM: - Ctrl3 |= PHY_L_P_BOTH_MD; - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - - /* Restart Auto-negotiation */ - Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; - } - - /* Write 1000Base-T Control Register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); - - /* Write AutoNeg Advertisement Register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); - - if (DoLoop) { - /* Set the Phy Loopback bit, too */ - Ctrl1 |= PHY_CT_LOOP; - } - - /* Write to the Phy control register */ - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Control Reg=0x%04X\n", Ctrl1)); -} /* SkXmInitPhyLone */ - - -/****************************************************************************** - * - * SkXmInitPhyNat() - Initialize the National Phy registers - * - * Description: initializes all the National Phy registers - * - * Note: - * - * Returns: - * nothing - */ -static void SkXmInitPhyNat( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ -/* todo: National */ -} /* SkXmInitPhyNat */ -#endif /* OTHER_PHY */ - - -/****************************************************************************** - * - * SkMacInitPhy() - Initialize the PHY registers - * - * Description: calls the Init PHY routines dep. on board type - * - * Note: - * - * Returns: - * nothing - */ -void SkMacInitPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - switch (pPrt->PhyType) { - case SK_PHY_XMAC: - SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_BCOM: - SkXmInitPhyBcom(pAC, IoC, Port, DoLoop); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmInitPhyLone(pAC, IoC, Port, DoLoop); - break; - case SK_PHY_NAT: - SkXmInitPhyNat(pAC, IoC, Port, DoLoop); - break; -#endif /* OTHER_PHY */ - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); - } -#endif /* YUKON */ - -} /* SkMacInitPhy */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmAutoNegDoneXmac() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkXmAutoNegDoneXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 ResAb; /* Resolved Ability */ - SK_U16 LPAb; /* Link Partner Ability */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneXmac, Port %d\n", Port)); - - pPrt = &pAC->GIni.GP[Port]; - - /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb); - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); - - if ((LPAb & PHY_X_AN_RFB) != 0) { - /* At least one of the remote fault bit is set */ - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Remote fault bit set Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_OTHER); - } - - /* Check Duplex mismatch */ - if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; - } - else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; - } - else { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_DUP_CAP); - } - - /* Check PAUSE mismatch */ - /* We are NOT using chapter 4.23 of the Xaqti manual */ - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC || - pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && - (LPAb & PHY_X_P_SYM_MD) != 0) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM && - (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { - /* Enable PAUSE receive, disable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; - } - else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND && - (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { - /* Disable PAUSE receive, enable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; - } - else { - /* PAUSE mismatch -> no PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - } - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; - - return(SK_AND_OK); -} /* SkXmAutoNegDoneXmac */ - - -/****************************************************************************** - * - * SkXmAutoNegDoneBcom() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkXmAutoNegDoneBcom( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 LPAb; /* Link Partner Ability */ - SK_U16 AuxStat; /* Auxiliary Status */ - -#ifdef TEST_ONLY -01-Sep-2000 RA;:;: - SK_U16 ResAb; /* Resolved Ability */ -#endif /* 0 */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneBcom, Port %d\n", Port)); - pPrt = &pAC->GIni.GP[Port]; - - /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); -#ifdef TEST_ONLY -01-Sep-2000 RA;:;: - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); -#endif /* 0 */ - - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat); - - if ((LPAb & PHY_B_AN_RF) != 0) { - /* Remote fault bit is set: Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Remote fault bit set Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_OTHER); - } - - /* Check Duplex mismatch */ - if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; - } - else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; - } - else { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_DUP_CAP); - } - -#ifdef TEST_ONLY -01-Sep-2000 RA;:;: - /* Check Master/Slave resolution */ - if ((ResAb & PHY_B_1000S_MSF) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - return(SK_AND_OTHER); - } - - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; -#endif /* 0 */ - - /* Check PAUSE mismatch ??? */ - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) { - /* Enable PAUSE receive, disable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; - } - else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) { - /* Disable PAUSE receive, enable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; - } - else { - /* PAUSE mismatch -> no PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - } - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; - - return(SK_AND_OK); -} /* SkXmAutoNegDoneBcom */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmAutoNegDoneMarv() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkGmAutoNegDoneMarv( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 LPAb; /* Link Partner Ability */ - SK_U16 ResAb; /* Resolved Ability */ - SK_U16 AuxStat; /* Auxiliary Status */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneMarv, Port %d\n", Port)); - pPrt = &pAC->GIni.GP[Port]; - - /* Get PHY parameters */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Link P.Abil.=0x%04X\n", LPAb)); - - if ((LPAb & PHY_M_AN_RF) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Remote fault bit set Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_OTHER); - } - - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); - - /* Check Master/Slave resolution */ - if ((ResAb & PHY_B_1000S_MSF) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - return(SK_AND_OTHER); - } - - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; - - /* Read PHY Specific Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat); - - /* Check Speed & Duplex resolved */ - if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - return(SK_AND_DUP_CAP); - } - - if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; - } - else { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; - } - - /* Check PAUSE mismatch ??? */ - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) { - /* Enable PAUSE receive, disable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; - } - else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) { - /* Disable PAUSE receive, enable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; - } - else { - /* PAUSE mismatch -> no PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - } - - /* set used link speed */ - switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { - case (unsigned)PHY_M_PS_SPEED_1000: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; - break; - case PHY_M_PS_SPEED_100: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; - break; - default: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; - } - - return(SK_AND_OK); -} /* SkGmAutoNegDoneMarv */ -#endif /* YUKON */ - - -#ifdef OTHER_PHY -/****************************************************************************** - * - * SkXmAutoNegDoneLone() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkXmAutoNegDoneLone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 ResAb; /* Resolved Ability */ - SK_U16 LPAb; /* Link Partner Ability */ - SK_U16 QuickStat; /* Auxiliary Status */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegDoneLone, Port %d\n", Port)); - pPrt = &pAC->GIni.GP[Port]; - - /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb); - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb); - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat); - - if ((LPAb & PHY_L_AN_RF) != 0) { - /* Remote fault bit is set */ - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegFail: Remote fault bit set Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - return(SK_AND_OTHER); - } - - /* Check Duplex mismatch */ - if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; - } - else { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; - } - - /* Check Master/Slave resolution */ - if ((ResAb & PHY_L_1000S_MSF) != 0) { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - return(SK_AND_OTHER); - } - else if (ResAb & PHY_L_1000S_MSR) { - pPrt->PMSStatus = SK_MS_STAT_MASTER; - } - else { - pPrt->PMSStatus = SK_MS_STAT_SLAVE; - } - - /* Check PAUSE mismatch */ - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - /* we must manually resolve the abilities here */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - - switch (pPrt->PFlowCtrlMode) { - case SK_FLOW_MODE_NONE: - /* default */ - break; - case SK_FLOW_MODE_LOC_SEND: - if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == - (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) { - /* Disable PAUSE receive, enable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; - } - break; - case SK_FLOW_MODE_SYMMETRIC: - if ((QuickStat & PHY_L_QS_PAUSE) != 0) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - break; - case SK_FLOW_MODE_SYM_OR_REM: - if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == - PHY_L_QS_AS_PAUSE) { - /* Enable PAUSE receive, disable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; - } - else if ((QuickStat & PHY_L_QS_PAUSE) != 0) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, - SKERR_HWI_E016MSG); - } - - return(SK_AND_OK); -} /* SkXmAutoNegDoneLone */ - - -/****************************************************************************** - * - * SkXmAutoNegDoneNat() - Auto-negotiation handling - * - * Description: - * This function handles the auto-negotiation if the Done bit is set. - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -static int SkXmAutoNegDoneNat( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ -/* todo: National */ - return(SK_AND_OK); -} /* SkXmAutoNegDoneNat */ -#endif /* OTHER_PHY */ - - -/****************************************************************************** - * - * SkMacAutoNegDone() - Auto-negotiation handling - * - * Description: calls the auto-negotiation done routines dep. on board type - * - * Returns: - * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened - */ -int SkMacAutoNegDone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - int Rtv; - - Rtv = SK_AND_OK; - - pPrt = &pAC->GIni.GP[Port]; - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - switch (pPrt->PhyType) { - - case SK_PHY_XMAC: - Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); - break; - case SK_PHY_BCOM: - Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port); - break; - case SK_PHY_NAT: - Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port); - break; -#endif /* OTHER_PHY */ - default: - return(SK_AND_OTHER); - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); - } -#endif /* YUKON */ - - if (Rtv != SK_AND_OK) { - return(Rtv); - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg done Port %d\n", Port)); - - /* We checked everything and may now enable the link */ - pPrt->PAutoNegFail = SK_FALSE; - - SkMacRxTxEnable(pAC, IoC, Port); - - return(SK_AND_OK); -} /* SkMacAutoNegDone */ - - -/****************************************************************************** - * - * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up - * - * Description: enables Rx/Tx dep. on board type - * - * Returns: - * 0 o.k. - * != 0 Error happened - */ -int SkMacRxTxEnable( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 Reg; /* 16-bit register value */ - SK_U16 IntMask; /* MAC interrupt mask */ -#ifdef GENESIS - SK_U16 SWord; -#endif - - pPrt = &pAC->GIni.GP[Port]; - - if (!pPrt->PHWLinkUp) { - /* The Hardware link is NOT up */ - return(0); - } - - if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || - pPrt->PLinkMode == SK_LMODE_AUTOFULL || - pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && - pPrt->PAutoNegFail) { - /* Auto-negotiation is not done or failed */ - return(0); - } - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* set Duplex Mode and Pause Mode */ - SkXmInitDupMd(pAC, IoC, Port); - - SkXmInitPauseMd(pAC, IoC, Port); - - /* - * Initialize the Interrupt Mask Register. Default IRQs are... - * - Link Asynchronous Event - * - Link Partner requests config - * - Auto Negotiation Done - * - Rx Counter Event Overflow - * - Tx Counter Event Overflow - * - Transmit FIFO Underrun - */ - IntMask = XM_DEF_MSK; - -#ifdef DEBUG - /* add IRQ for Receive FIFO Overflow */ - IntMask &= ~XM_IS_RXF_OV; -#endif /* DEBUG */ - - if (pPrt->PhyType != SK_PHY_XMAC) { - /* disable GP0 interrupt bit */ - IntMask |= XM_IS_INP_ASS; - } - XM_OUT16(IoC, Port, XM_IMSK, IntMask); - - /* get MMU Command Reg. */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); - - if (pPrt->PhyType != SK_PHY_XMAC && - (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { - /* set to Full Duplex */ - Reg |= XM_MMU_GMII_FD; - } - - switch (pPrt->PhyType) { - case SK_PHY_BCOM: - /* - * Workaround BCOM Errata (#10523) for all BCom Phys - * Enable Power Management after link up - */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, - (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, - (SK_U16)PHY_B_DEF_MSK); - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK); - break; - case SK_PHY_NAT: - /* todo National: - SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */ - /* no interrupts possible from National ??? */ - break; -#endif /* OTHER_PHY */ - } - - /* enable Rx/Tx */ - XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* - * Initialize the Interrupt Mask Register. Default IRQs are... - * - Rx Counter Event Overflow - * - Tx Counter Event Overflow - * - Transmit FIFO Underrun - */ - IntMask = GMAC_DEF_MSK; - -#ifdef DEBUG - /* add IRQ for Receive FIFO Overrun */ - IntMask |= GM_IS_RX_FF_OR; -#endif /* DEBUG */ - - SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask); - - /* get General Purpose Control */ - GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); - - if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || - pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) { - /* set to Full Duplex */ - Reg |= GM_GPCR_DUP_FULL; - } - - /* enable Rx/Tx */ - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA)); - -#ifndef VCPU - /* Enable all PHY interrupts */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, - (SK_U16)PHY_M_DEF_MSK); -#endif /* VCPU */ - } -#endif /* YUKON */ - - return(0); - -} /* SkMacRxTxEnable */ - - -/****************************************************************************** - * - * SkMacRxTxDisable() - Disable Receiver and Transmitter - * - * Description: disables Rx/Tx dep. on board type - * - * Returns: N/A - */ -void SkMacRxTxDisable( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U16 Word; - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - - /* dummy read to ensure writing */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - GM_IN16(IoC, Port, GM_GP_CTRL, &Word); - - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA))); - - /* dummy read to ensure writing */ - GM_IN16(IoC, Port, GM_GP_CTRL, &Word); - } -#endif /* YUKON */ - -} /* SkMacRxTxDisable */ - - -/****************************************************************************** - * - * SkMacIrqDisable() - Disable IRQ from MAC - * - * Description: sets the IRQ-mask to disable IRQ dep. on board type - * - * Returns: N/A - */ -void SkMacIrqDisable( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; -#ifdef GENESIS - SK_U16 Word; -#endif - - pPrt = &pAC->GIni.GP[Port]; - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - /* disable all XMAC IRQs */ - XM_OUT16(IoC, Port, XM_IMSK, 0xffff); - - /* Disable all PHY interrupts */ - switch (pPrt->PhyType) { - case SK_PHY_BCOM: - /* Make sure that PHY is initialized */ - if (pPrt->PState != SK_PRT_RESET) { - /* NOT allowed if BCOM is in RESET state */ - /* Workaround BCOM Errata (#10523) all BCom */ - /* Disable Power Management if link is down */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, - (SK_U16)(Word | PHY_B_AC_DIS_PM)); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff); - } - break; -#ifdef OTHER_PHY - case SK_PHY_LONE: - SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0); - break; - case SK_PHY_NAT: - /* todo: National - SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */ - break; -#endif /* OTHER_PHY */ - } - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* disable all GMAC IRQs */ - SK_OUT8(IoC, GMAC_IRQ_MSK, 0); - -#ifndef VCPU - /* Disable all PHY interrupts */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); -#endif /* VCPU */ - } -#endif /* YUKON */ - -} /* SkMacIrqDisable */ - - -#ifdef SK_DIAG -/****************************************************************************** - * - * SkXmSendCont() - Enable / Disable Send Continuous Mode - * - * Description: enable / disable Send Continuous Mode on XMAC - * - * Returns: - * nothing - */ -void SkXmSendCont( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL Enable) /* Enable / Disable */ -{ - SK_U32 MdReg; - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - - if (Enable) { - MdReg |= XM_MD_TX_CONT; - } - else { - MdReg &= ~XM_MD_TX_CONT; - } - /* setup Mode Register */ - XM_OUT32(IoC, Port, XM_MODE, MdReg); - -} /* SkXmSendCont */ - - -/****************************************************************************** - * - * SkMacTimeStamp() - Enable / Disable Time Stamp - * - * Description: enable / disable Time Stamp generation for Rx packets - * - * Returns: - * nothing - */ -void SkMacTimeStamp( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL Enable) /* Enable / Disable */ -{ - SK_U32 MdReg; - SK_U8 TimeCtrl; - - if (pAC->GIni.GIGenesis) { - - XM_IN32(IoC, Port, XM_MODE, &MdReg); - - if (Enable) { - MdReg |= XM_MD_ATS; - } - else { - MdReg &= ~XM_MD_ATS; - } - /* setup Mode Register */ - XM_OUT32(IoC, Port, XM_MODE, MdReg); - } - else { - if (Enable) { - TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ; - } - else { - TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; - } - /* Start/Stop Time Stamp Timer */ - SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl); - } - -} /* SkMacTimeStamp*/ - -#else /* !SK_DIAG */ - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg - * - * This function analyses the Interrupt status word. If any of the - * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable - * is set true. - */ -void SkXmAutoNegLipaXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus) /* Interrupt Status word to analyse */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n", - Port, IStatus)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; - } -} /* SkXmAutoNegLipaXmac */ -#endif /* GENESIS */ - - -/****************************************************************************** - * - * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg - * - * This function analyses the PHY status word. - * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable - * is set true. - */ -void SkMacAutoNegLipaPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_U16 PhyStat) /* PHY Status word to analyse */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO && - (PhyStat & PHY_ST_AN_OVER) != 0) { - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n", - Port, PhyStat)); - pPrt->PLipaAutoNeg = SK_LIPA_AUTO; - } -} /* SkMacAutoNegLipaPhy */ - - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmIrq() - Interrupt Service Routine - * - * Description: services an Interrupt Request of the XMAC - * - * Note: - * With an external PHY, some interrupt bits are not meaningfull any more: - * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE - * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC - * - Page Received (bit #9) XM_IS_RX_PAGE - * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE - * - AutoNegDone (bit #7) XM_IS_AND - * Also probably not valid any more is the GP0 input bit: - * - GPRegisterBit0set XM_IS_INP_ASS - * - * Returns: - * nothing - */ -static void SkXmIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_EVPARA Para; - SK_U16 IStatus; /* Interrupt status read from the XMAC */ - SK_U16 IStatus2; -#ifdef SK_SLIM - SK_U64 OverflowStatus; -#endif - - pPrt = &pAC->GIni.GP[Port]; - - XM_IN16(IoC, Port, XM_ISRC, &IStatus); - - /* LinkPartner Auto-negable? */ - if (pPrt->PhyType == SK_PHY_XMAC) { - SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); - } - else { - /* mask bits that are not used with ext. PHY */ - IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC | - XM_IS_RX_PAGE | XM_IS_TX_PAGE | - XM_IS_AND | XM_IS_INP_ASS); - } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); - - if (!pPrt->PHWLinkUp) { - /* Spurious XMAC interrupt */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: spurious interrupt on Port %d\n", Port)); - return; - } - - if ((IStatus & XM_IS_INP_ASS) != 0) { - /* Reread ISR Register if link is not in sync */ - XM_IN16(IoC, Port, XM_ISRC, &IStatus2); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n", - Port, IStatus, IStatus2)); - IStatus &= ~XM_IS_INP_ASS; - IStatus |= IStatus2; - } - - if ((IStatus & XM_IS_LNK_AE) != 0) { - /* not used, GP0 is used instead */ - } - - if ((IStatus & XM_IS_TX_ABORT) != 0) { - /* not used */ - } - - if ((IStatus & XM_IS_FRC_INT) != 0) { - /* not used, use ASIC IRQ instead if needed */ - } - - if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) { - SkHWLinkDown(pAC, IoC, Port); - - /* Signal to RLMT */ - Para.Para32[0] = (SK_U32)Port; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); - - /* Start workaround Errata #2 timer */ - SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, - SKGE_HWAC, SK_HWEV_WATIM, Para); - } - - if ((IStatus & XM_IS_RX_PAGE) != 0) { - /* not used */ - } - - if ((IStatus & XM_IS_TX_PAGE) != 0) { - /* not used */ - } - - if ((IStatus & XM_IS_AND) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("SkXmIrq: AND on link that is up Port %d\n", Port)); - } - - if ((IStatus & XM_IS_TSC_OV) != 0) { - /* not used */ - } - - /* Combined Tx & Rx Counter Overflow SIRQ Event */ - if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) { -#ifdef SK_SLIM - SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); -#else - Para.Para32[0] = (SK_U32)Port; - Para.Para32[1] = (SK_U32)IStatus; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); -#endif /* SK_SLIM */ - } - - if ((IStatus & XM_IS_RXF_OV) != 0) { - /* normal situation -> no effect */ -#ifdef DEBUG - pPrt->PRxOverCnt++; -#endif /* DEBUG */ - } - - if ((IStatus & XM_IS_TXF_UR) != 0) { - /* may NOT happen -> error log */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); - } - - if ((IStatus & XM_IS_TX_COMP) != 0) { - /* not served here */ - } - - if ((IStatus & XM_IS_RX_COMP) != 0) { - /* not served here */ - } -} /* SkXmIrq */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmIrq() - Interrupt Service Routine - * - * Description: services an Interrupt Request of the GMAC - * - * Note: - * - * Returns: - * nothing - */ -static void SkGmIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U8 IStatus; /* Interrupt status */ -#ifdef SK_SLIM - SK_U64 OverflowStatus; -#else - SK_EVPARA Para; -#endif - - pPrt = &pAC->GIni.GP[Port]; - - SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); - -#ifdef XXX - /* LinkPartner Auto-negable? */ - SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); -#endif /* XXX */ - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); - - /* Combined Tx & Rx Counter Overflow SIRQ Event */ - if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { - /* these IRQs will be cleared by reading GMACs register */ -#ifdef SK_SLIM - SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); -#else - Para.Para32[0] = (SK_U32)Port; - Para.Para32[1] = (SK_U32)IStatus; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); -#endif - } - - if (IStatus & GM_IS_RX_FF_OR) { - /* clear GMAC Rx FIFO Overrun IRQ */ - SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); -#ifdef DEBUG - pPrt->PRxOverCnt++; -#endif /* DEBUG */ - } - - if (IStatus & GM_IS_TX_FF_UR) { - /* clear GMAC Tx FIFO Underrun IRQ */ - SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU); - /* may NOT happen -> error log */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG); - } - - if (IStatus & GM_IS_TX_COMPL) { - /* not served here */ - } - - if (IStatus & GM_IS_RX_COMPL) { - /* not served here */ - } -} /* SkGmIrq */ -#endif /* YUKON */ - - -/****************************************************************************** - * - * SkMacIrq() - Interrupt Service Routine for MAC - * - * Description: calls the Interrupt Service Routine dep. on board type - * - * Returns: - * nothing - */ -void SkMacIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - /* IRQ from XMAC */ - SkXmIrq(pAC, IoC, Port); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - /* IRQ from GMAC */ - SkGmIrq(pAC, IoC, Port); - } -#endif /* YUKON */ - -} /* SkMacIrq */ - -#endif /* !SK_DIAG */ - -#ifdef GENESIS -/****************************************************************************** - * - * SkXmUpdateStats() - Force the XMAC to output the current statistic - * - * Description: - * The XMAC holds its statistic internally. To obtain the current - * values a command must be sent so that the statistic data will - * be written to a predefined memory area on the adapter. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkXmUpdateStats( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port) /* Port Index (MAC_1 + n) */ -{ - SK_GEPORT *pPrt; - SK_U16 StatReg; - int WaitIndex; - - pPrt = &pAC->GIni.GP[Port]; - WaitIndex = 0; - - /* Send an update command to XMAC specified */ - XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); - - /* - * It is an auto-clearing register. If the command bits - * went to zero again, the statistics are transferred. - * Normally the command should be executed immediately. - * But just to be sure we execute a loop. - */ - do { - - XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg); - - if (++WaitIndex > 10) { - - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG); - - return(1); - } - } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); - - return(0); -} /* SkXmUpdateStats */ - - -/****************************************************************************** - * - * SkXmMacStatistic() - Get XMAC counter value - * - * Description: - * Gets the 32bit counter value. Except for the octet counters - * the lower 32bit are counted in hardware and the upper 32bit - * must be counted in software by monitoring counter overflow interrupts. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkXmMacStatistic( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ -{ - if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); - - return(1); - } - - XM_IN32(IoC, Port, StatAddr, pVal); - - return(0); -} /* SkXmMacStatistic */ - - -/****************************************************************************** - * - * SkXmResetCounter() - Clear MAC statistic counter - * - * Description: - * Force the XMAC to clear its statistic counter. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkXmResetCounter( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port) /* Port Index (MAC_1 + n) */ -{ - XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ - XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); - - return(0); -} /* SkXmResetCounter */ - - -/****************************************************************************** - * - * SkXmOverflowStatus() - Gets the status of counter overflow interrupt - * - * Description: - * Checks the source causing an counter overflow interrupt. On success the - * resulting counter overflow status is written to , whereas the - * upper dword stores the XMAC ReceiveCounterEvent register and the lower - * dword the XMAC TransmitCounterEvent register. - * - * Note: - * For XMAC the interrupt source is a self-clearing register, so the source - * must be checked only once. SIRQ module does another check to be sure - * that no interrupt get lost during process time. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkXmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ -{ - SK_U64 Status; /* Overflow status */ - SK_U32 RegVal; - - Status = 0; - - if ((IStatus & XM_IS_RXC_OV) != 0) { - - XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); - Status |= (SK_U64)RegVal << 32; - } - - if ((IStatus & XM_IS_TXC_OV) != 0) { - - XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); - Status |= (SK_U64)RegVal; - } - - *pStatus = Status; - - return(0); -} /* SkXmOverflowStatus */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmUpdateStats() - Force the GMAC to output the current statistic - * - * Description: - * Empty function for GMAC. Statistic data is accessible in direct way. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkGmUpdateStats( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port) /* Port Index (MAC_1 + n) */ -{ - return(0); -} - - -/****************************************************************************** - * - * SkGmMacStatistic() - Get GMAC counter value - * - * Description: - * Gets the 32bit counter value. Except for the octet counters - * the lower 32bit are counted in hardware and the upper 32bit - * must be counted in software by monitoring counter overflow interrupts. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkGmMacStatistic( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ -{ - - if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); - return(1); - } - - GM_IN32(IoC, Port, StatAddr, pVal); - - return(0); -} /* SkGmMacStatistic */ - - -/****************************************************************************** - * - * SkGmResetCounter() - Clear MAC statistic counter - * - * Description: - * Force GMAC to clear its statistic counter. - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkGmResetCounter( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port) /* Port Index (MAC_1 + n) */ -{ - SK_U16 Reg; /* Phy Address Register */ - SK_U16 Word; - int i; - - GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg); - - /* set MIB Clear Counter Mode */ - GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); - - /* read all MIB Counters with Clear Mode set */ - for (i = 0; i < GM_MIB_CNT_SIZE; i++) { - /* the reset is performed only when the lower 16 bits are read */ - GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word); - } - - /* clear MIB Clear Counter Mode */ - GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); - - return(0); -} /* SkGmResetCounter */ - - -/****************************************************************************** - * - * SkGmOverflowStatus() - Gets the status of counter overflow interrupt - * - * Description: - * Checks the source causing an counter overflow interrupt. On success the - * resulting counter overflow status is written to , whereas the - * the following bit coding is used: - * 63:56 - unused - * 55:48 - TxRx interrupt register bit7:0 - * 32:47 - Rx interrupt register - * 31:24 - unused - * 23:16 - TxRx interrupt register bit15:8 - * 15:0 - Tx interrupt register - * - * Returns: - * 0: success - * 1: something went wrong - */ -int SkGmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ -{ - SK_U64 Status; /* Overflow status */ - SK_U16 RegVal; - - Status = 0; - - if ((IStatus & GM_IS_RX_CO_OV) != 0) { - /* this register is self-clearing after read */ - GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal); - Status |= (SK_U64)RegVal << 32; - } - - if ((IStatus & GM_IS_TX_CO_OV) != 0) { - /* this register is self-clearing after read */ - GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal); - Status |= (SK_U64)RegVal; - } - - /* this register is self-clearing after read */ - GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal); - /* Rx overflow interrupt register bits (LoByte)*/ - Status |= (SK_U64)((SK_U8)RegVal) << 48; - /* Tx overflow interrupt register bits (HiByte)*/ - Status |= (SK_U64)(RegVal >> 8) << 16; - - *pStatus = Status; - - return(0); -} /* SkGmOverflowStatus */ - - -#ifndef SK_SLIM -/****************************************************************************** - * - * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test - * - * Description: - * starts the cable diagnostic test if 'StartTest' is true - * gets the results if 'StartTest' is true - * - * NOTE: this test is meaningful only when link is down - * - * Returns: - * 0: success - * 1: no YUKON copper - * 2: test in progress - */ -int SkGmCableDiagStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL StartTest) /* flag for start / get result */ -{ - int i; - SK_U16 RegVal; - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - if (pPrt->PhyType != SK_PHY_MARV_COPPER) { - - return(1); - } - - if (StartTest) { - /* only start the cable test */ - if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) { - /* apply TDR workaround from Marvell */ - SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e); - - SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100); - } - - /* set address to 0 for MDI[0] */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); - - /* Read Cable Diagnostic Reg */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); - - /* start Cable Diagnostic Test */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, - (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST)); - - return(0); - } - - /* Read Cable Diagnostic Reg */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Cable Diag.=0x%04X\n", RegVal)); - - if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) { - /* test is running */ - return(2); - } - - /* get the test results */ - for (i = 0; i < 4; i++) { - /* set address to i for MDI[i] */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); - - /* get Cable Diagnostic values */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); - - pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK); - - pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13); - } - - return(0); -} /* SkGmCableDiagStatus */ -#endif /* !SK_SLIM */ -#endif /* YUKON */ - -/* End of file */ From 4c3ca4da8086c3c9fcc81dccc387c34bee6b755e Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Thu, 5 Jul 2007 09:26:25 +0200 Subject: [PATCH 544/551] eHEA: Capability flag for DLPAR support This patch introduces a capability flag that is used by the DLPAR userspace tool to check which DLPAR features are supported by the eHEA driver. Missing goto has been included. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 8 +++++++- drivers/net/ehea/ehea_main.c | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index abaf3ac94936..f03f070451de 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,13 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0065" +#define DRV_VERSION "EHEA_0067" + +/* EHEA capability flags */ +#define DLPAR_PORT_ADD_REM 1 +#define DLPAR_MEM_ADD 2 +#define DLPAR_MEM_REM 4 +#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM) #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index bdb52419dbf5..383144db4d18 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2923,6 +2923,15 @@ static int check_module_parm(void) return ret; } +static ssize_t ehea_show_capabilities(struct device_driver *drv, + char *buf) +{ + return sprintf(buf, "%d", EHEA_CAPABILITIES); +} + +static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH, + ehea_show_capabilities, NULL); + int __init ehea_module_init(void) { int ret; @@ -2934,8 +2943,19 @@ int __init ehea_module_init(void) if (ret) goto out; ret = ibmebus_register_driver(&ehea_driver); - if (ret) + if (ret) { ehea_error("failed registering eHEA device driver on ebus"); + goto out; + } + + ret = driver_create_file(&ehea_driver.driver, + &driver_attr_capabilities); + if (ret) { + ehea_error("failed to register capabilities attribute, ret=%d", + ret); + ibmebus_unregister_driver(&ehea_driver); + goto out; + } out: return ret; @@ -2943,6 +2963,7 @@ out: static void __exit ehea_module_exit(void) { + driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); } From def47c5095d53814512bb0c62ec02dfdec769db1 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 10 Jul 2007 14:06:48 -0400 Subject: [PATCH 545/551] [netdrvr] Fix dependencies for ax88796 ne2k clone driver It needs writesb(), not available on all platforms. Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a3bef229a125..a64c2fb8ac28 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -199,6 +199,7 @@ source "drivers/net/arm/Kconfig" config AX88796 tristate "ASIX AX88796 NE2000 clone support" + depends on ARM || MIPS select CRC32 select MII help From 02c1889166b47b9ade309a8f4b7c4ddf0489d869 Mon Sep 17 00:00:00 2001 From: Masakazu Mokuno Date: Thu, 5 Jul 2007 20:11:16 +0900 Subject: [PATCH 546/551] ps3: gigabit ethernet driver for PS3, take3 Hi, This is the third submission of the network driver for PS3. The differences from the previous one are: - renamed source file names so that their prefix can match with the module name - added cbe-oss-dev@ozlabs.org line for MAINTAINER file - changed some in copyright comments If there are no more comments, please apply for 2.6.23. Thank you -- Subject: PS3: Ethernet driver From: Masakazu Mokuno Add Gigabit Ethernet support for the PS3 game console. The module will be called ps3_gelic. CC: Geoff Levand Signed-off-by: Masakazu Mokuno Signed-off-by: Jeff Garzik --- MAINTAINERS | 7 + drivers/net/Kconfig | 10 + drivers/net/Makefile | 2 + drivers/net/ps3_gelic_net.c | 1576 +++++++++++++++++++++++++++++++++++ drivers/net/ps3_gelic_net.h | 239 ++++++ 5 files changed, 1834 insertions(+) create mode 100644 drivers/net/ps3_gelic_net.c create mode 100644 drivers/net/ps3_gelic_net.h diff --git a/MAINTAINERS b/MAINTAINERS index 2c1dfb271613..0223d6d191df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2930,6 +2930,13 @@ M: mikpe@it.uu.se L: linux-ide@vger.kernel.org S: Maintained +PS3 NETWORK SUPPORT +P: Masakazu Mokuno +M: mokuno@sm.sony.co.jp +L: netdev@vger.kernel.org +L: cbe-oss-dev@ozlabs.org +S: Supported + PS3 PLATFORM SUPPORT P: Geoff Levand M: geoffrey.levand@am.sony.com diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a64c2fb8ac28..ec846842c480 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2200,6 +2200,16 @@ config TSI108_ETH To compile this driver as a module, choose M here: the module will be called tsi108_eth. +config GELIC_NET + tristate "PS3 Gigabit Ethernet driver" + depends on PPC_PS3 + help + This driver supports the network device on the PS3 game + console. This driver has built-in support for Ethernet. + + To compile this driver as a module, choose M here: the + module will be called ps3_gelic. + config GIANFAR tristate "Gianfar Ethernet" depends on 85xx || 83xx || PPC_86xx diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 77bd8222ab44..1bbcbedad04a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -60,6 +60,8 @@ obj-$(CONFIG_TIGON3) += tg3.o obj-$(CONFIG_BNX2) += bnx2.o spidernet-y += spider_net.o spider_net_ethtool.o obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o +obj-$(CONFIG_GELIC_NET) += ps3_gelic.o +ps3_gelic-objs += ps3_gelic_net.o obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c new file mode 100644 index 000000000000..08d25066f051 --- /dev/null +++ b/drivers/net/ps3_gelic_net.c @@ -0,0 +1,1576 @@ +/* + * PS3 gelic network driver. + * + * Copyright (C) 2007 Sony Computer Entertainment Inc. + * Copyright 2006, 2007 Sony Corporation + * + * This file is based on: spider_net.c + * + * (C) Copyright IBM Corp. 2005 + * + * Authors : Utz Bacher + * Jens Osterkamp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#undef DEBUG + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ps3_gelic_net.h" + +#define DRV_NAME "Gelic Network Driver" +#define DRV_VERSION "1.0" + +MODULE_AUTHOR("SCE Inc."); +MODULE_DESCRIPTION("Gelic Network driver"); +MODULE_LICENSE("GPL"); + +static inline struct device *ctodev(struct gelic_net_card *card) +{ + return &card->dev->core; +} +static inline unsigned int bus_id(struct gelic_net_card *card) +{ + return card->dev->bus_id; +} +static inline unsigned int dev_id(struct gelic_net_card *card) +{ + return card->dev->dev_id; +} + +/* set irq_mask */ +static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask) +{ + int status; + + status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card), + mask, 0); + if (status) + dev_info(ctodev(card), + "lv1_net_set_interrupt_mask failed %d\n", status); + return status; +} +static inline void gelic_net_rx_irq_on(struct gelic_net_card *card) +{ + gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT); +} +static inline void gelic_net_rx_irq_off(struct gelic_net_card *card) +{ + gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT); +} +/** + * gelic_net_get_descr_status -- returns the status of a descriptor + * @descr: descriptor to look at + * + * returns the status as in the dmac_cmd_status field of the descriptor + */ +static enum gelic_net_descr_status +gelic_net_get_descr_status(struct gelic_net_descr *descr) +{ + u32 cmd_status; + + cmd_status = descr->dmac_cmd_status; + cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT; + return cmd_status; +} + +/** + * gelic_net_set_descr_status -- sets the status of a descriptor + * @descr: descriptor to change + * @status: status to set in the descriptor + * + * changes the status to the specified value. Doesn't change other bits + * in the status + */ +static void gelic_net_set_descr_status(struct gelic_net_descr *descr, + enum gelic_net_descr_status status) +{ + u32 cmd_status; + + /* read the status */ + cmd_status = descr->dmac_cmd_status; + /* clean the upper 4 bits */ + cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO; + /* add the status to it */ + cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT; + /* and write it back */ + descr->dmac_cmd_status = cmd_status; + /* + * dma_cmd_status field is used to indicate whether the descriptor + * is valid or not. + * Usually caller of this function wants to inform that to the + * hardware, so we assure here the hardware sees the change. + */ + wmb(); +} + +/** + * gelic_net_free_chain - free descriptor chain + * @card: card structure + * @descr_in: address of desc + */ +static void gelic_net_free_chain(struct gelic_net_card *card, + struct gelic_net_descr *descr_in) +{ + struct gelic_net_descr *descr; + + for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) { + dma_unmap_single(ctodev(card), descr->bus_addr, + GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); + descr->bus_addr = 0; + } +} + +/** + * gelic_net_init_chain - links descriptor chain + * @card: card structure + * @chain: address of chain + * @start_descr: address of descriptor array + * @no: number of descriptors + * + * we manage a circular list that mirrors the hardware structure, + * except that the hardware uses bus addresses. + * + * returns 0 on success, <0 on failure + */ +static int gelic_net_init_chain(struct gelic_net_card *card, + struct gelic_net_descr_chain *chain, + struct gelic_net_descr *start_descr, int no) +{ + int i; + struct gelic_net_descr *descr; + + descr = start_descr; + memset(descr, 0, sizeof(*descr) * no); + + /* set up the hardware pointers in each descriptor */ + for (i = 0; i < no; i++, descr++) { + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); + descr->bus_addr = + dma_map_single(ctodev(card), descr, + GELIC_NET_DESCR_SIZE, + DMA_BIDIRECTIONAL); + + if (!descr->bus_addr) + goto iommu_error; + + descr->next = descr + 1; + descr->prev = descr - 1; + } + /* make them as ring */ + (descr - 1)->next = start_descr; + start_descr->prev = (descr - 1); + + /* chain bus addr of hw descriptor */ + descr = start_descr; + for (i = 0; i < no; i++, descr++) { + descr->next_descr_addr = descr->next->bus_addr; + } + + chain->head = start_descr; + chain->tail = start_descr; + + /* do not chain last hw descriptor */ + (descr - 1)->next_descr_addr = 0; + + return 0; + +iommu_error: + for (i--, descr--; 0 <= i; i--, descr--) + if (descr->bus_addr) + dma_unmap_single(ctodev(card), descr->bus_addr, + GELIC_NET_DESCR_SIZE, + DMA_BIDIRECTIONAL); + return -ENOMEM; +} + +/** + * gelic_net_prepare_rx_descr - reinitializes a rx descriptor + * @card: card structure + * @descr: descriptor to re-init + * + * return 0 on succes, <0 on failure + * + * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. + * Activate the descriptor state-wise + */ +static int gelic_net_prepare_rx_descr(struct gelic_net_card *card, + struct gelic_net_descr *descr) +{ + int offset; + unsigned int bufsize; + + if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) { + dev_info(ctodev(card), "%s: ERROR status \n", __func__); + } + /* we need to round up the buffer size to a multiple of 128 */ + bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN); + + /* and we need to have it 128 byte aligned, therefore we allocate a + * bit more */ + descr->skb = netdev_alloc_skb(card->netdev, + bufsize + GELIC_NET_RXBUF_ALIGN - 1); + if (!descr->skb) { + descr->buf_addr = 0; /* tell DMAC don't touch memory */ + dev_info(ctodev(card), + "%s:allocate skb failed !!\n", __func__); + return -ENOMEM; + } + descr->buf_size = bufsize; + descr->dmac_cmd_status = 0; + descr->result_size = 0; + descr->valid_size = 0; + descr->data_error = 0; + + offset = ((unsigned long)descr->skb->data) & + (GELIC_NET_RXBUF_ALIGN - 1); + if (offset) + skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); + /* io-mmu-map the skb */ + descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data, + GELIC_NET_MAX_MTU, + DMA_FROM_DEVICE); + if (!descr->buf_addr) { + dev_kfree_skb_any(descr->skb); + descr->skb = NULL; + dev_info(ctodev(card), + "%s:Could not iommu-map rx buffer\n", __func__); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); + return -ENOMEM; + } else { + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED); + return 0; + } +} + +/** + * gelic_net_release_rx_chain - free all skb of rx descr + * @card: card structure + * + */ +static void gelic_net_release_rx_chain(struct gelic_net_card *card) +{ + struct gelic_net_descr *descr = card->rx_chain.head; + + do { + if (descr->skb) { + dma_unmap_single(ctodev(card), + descr->buf_addr, + descr->skb->len, + DMA_FROM_DEVICE); + descr->buf_addr = 0; + dev_kfree_skb_any(descr->skb); + descr->skb = NULL; + descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE; + } + descr = descr->next; + } while (descr != card->rx_chain.head); +} + +/** + * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains + * @card: card structure + * + * fills all descriptors in the rx chain: allocates skbs + * and iommu-maps them. + * returns 0 on success, <0 on failure + */ +static int gelic_net_fill_rx_chain(struct gelic_net_card *card) +{ + struct gelic_net_descr *descr = card->rx_chain.head; + int ret; + + do { + if (!descr->skb) { + ret = gelic_net_prepare_rx_descr(card, descr); + if (ret) + goto rewind; + } + descr = descr->next; + } while (descr != card->rx_chain.head); + + return 0; +rewind: + gelic_net_release_rx_chain(card); + return ret; +} + +/** + * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains + * @card: card structure + * + * returns 0 on success, <0 on failure + */ +static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card) +{ + struct gelic_net_descr_chain *chain; + int ret; + chain = &card->rx_chain; + ret = gelic_net_fill_rx_chain(card); + chain->head = card->rx_top->prev; /* point to the last */ + return ret; +} + +/** + * gelic_net_release_tx_descr - processes a used tx descriptor + * @card: card structure + * @descr: descriptor to release + * + * releases a used tx descriptor (unmapping, freeing of skb) + */ +static void gelic_net_release_tx_descr(struct gelic_net_card *card, + struct gelic_net_descr *descr) +{ + struct sk_buff *skb; + + + if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) { + /* 2nd descriptor */ + skb = descr->skb; + dma_unmap_single(ctodev(card), descr->buf_addr, skb->len, + DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + } else { + dma_unmap_single(ctodev(card), descr->buf_addr, + descr->buf_size, DMA_TO_DEVICE); + } + + descr->buf_addr = 0; + descr->buf_size = 0; + descr->next_descr_addr = 0; + descr->result_size = 0; + descr->valid_size = 0; + descr->data_status = 0; + descr->data_error = 0; + descr->skb = NULL; + + /* set descr status */ + descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE; +} + +/** + * gelic_net_release_tx_chain - processes sent tx descriptors + * @card: adapter structure + * @stop: net_stop sequence + * + * releases the tx descriptors that gelic has finished with + */ +static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop) +{ + struct gelic_net_descr_chain *tx_chain; + enum gelic_net_descr_status status; + int release = 0; + + for (tx_chain = &card->tx_chain; + tx_chain->head != tx_chain->tail && tx_chain->tail; + tx_chain->tail = tx_chain->tail->next) { + status = gelic_net_get_descr_status(tx_chain->tail); + switch (status) { + case GELIC_NET_DESCR_RESPONSE_ERROR: + case GELIC_NET_DESCR_PROTECTION_ERROR: + case GELIC_NET_DESCR_FORCE_END: + if (printk_ratelimit()) + dev_info(ctodev(card), + "%s: forcing end of tx descriptor " \ + "with status %x\n", + __func__, status); + card->netdev_stats.tx_dropped++; + break; + + case GELIC_NET_DESCR_COMPLETE: + card->netdev_stats.tx_packets++; + card->netdev_stats.tx_bytes += + tx_chain->tail->skb->len; + break; + + case GELIC_NET_DESCR_CARDOWNED: + /* pending tx request */ + default: + /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */ + goto out; + } + gelic_net_release_tx_descr(card, tx_chain->tail); + release = 1; + } +out: + if (!stop && release) + netif_wake_queue(card->netdev); +} + +/** + * gelic_net_set_multi - sets multicast addresses and promisc flags + * @netdev: interface device structure + * + * gelic_net_set_multi configures multicast addresses as needed for the + * netdev interface. It also sets up multicast, allmulti and promisc + * flags appropriately + */ +static void gelic_net_set_multi(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + struct dev_mc_list *mc; + unsigned int i; + uint8_t *p; + u64 addr; + int status; + + /* clear all multicast address */ + status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card), + 0, 1); + if (status) + dev_err(ctodev(card), + "lv1_net_remove_multicast_address failed %d\n", + status); + /* set broadcast address */ + status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), + GELIC_NET_BROADCAST_ADDR, 0); + if (status) + dev_err(ctodev(card), + "lv1_net_add_multicast_address failed, %d\n", + status); + + if (netdev->flags & IFF_ALLMULTI + || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */ + status = lv1_net_add_multicast_address(bus_id(card), + dev_id(card), + 0, 1); + if (status) + dev_err(ctodev(card), + "lv1_net_add_multicast_address failed, %d\n", + status); + return; + } + + /* set multicast address */ + for (mc = netdev->mc_list; mc; mc = mc->next) { + addr = 0; + p = mc->dmi_addr; + for (i = 0; i < ETH_ALEN; i++) { + addr <<= 8; + addr |= *p++; + } + status = lv1_net_add_multicast_address(bus_id(card), + dev_id(card), + addr, 0); + if (status) + dev_err(ctodev(card), + "lv1_net_add_multicast_address failed, %d\n", + status); + } +} + +/** + * gelic_net_enable_rxdmac - enables the receive DMA controller + * @card: card structure + * + * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN + * in the GDADMACCNTR register + */ +static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card) +{ + int status; + + status = lv1_net_start_rx_dma(bus_id(card), dev_id(card), + card->rx_chain.tail->bus_addr, 0); + if (status) + dev_info(ctodev(card), + "lv1_net_start_rx_dma failed, status=%d\n", status); +} + +/** + * gelic_net_disable_rxdmac - disables the receive DMA controller + * @card: card structure + * + * gelic_net_disable_rxdmac terminates processing on the DMA controller by + * turing off DMA and issueing a force end + */ +static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card) +{ + int status; + + /* this hvc blocks until the DMA in progress really stopped */ + status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0); + if (status) + dev_err(ctodev(card), + "lv1_net_stop_rx_dma faild, %d\n", status); +} + +/** + * gelic_net_disable_txdmac - disables the transmit DMA controller + * @card: card structure + * + * gelic_net_disable_txdmac terminates processing on the DMA controller by + * turing off DMA and issueing a force end + */ +static inline void gelic_net_disable_txdmac(struct gelic_net_card *card) +{ + int status; + + /* this hvc blocks until the DMA in progress really stopped */ + status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0); + if (status) + dev_err(ctodev(card), + "lv1_net_stop_tx_dma faild, status=%d\n", status); +} + +/** + * gelic_net_stop - called upon ifconfig down + * @netdev: interface device structure + * + * always returns 0 + */ +static int gelic_net_stop(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + netif_poll_disable(netdev); + netif_stop_queue(netdev); + + /* turn off DMA, force end */ + gelic_net_disable_rxdmac(card); + gelic_net_disable_txdmac(card); + + gelic_net_set_irq_mask(card, 0); + + /* disconnect event port */ + free_irq(card->netdev->irq, card->netdev); + ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); + card->netdev->irq = NO_IRQ; + + netif_carrier_off(netdev); + + /* release chains */ + gelic_net_release_tx_chain(card, 1); + gelic_net_release_rx_chain(card); + + gelic_net_free_chain(card, card->tx_top); + gelic_net_free_chain(card, card->rx_top); + + return 0; +} + +/** + * gelic_net_get_next_tx_descr - returns the next available tx descriptor + * @card: device structure to get descriptor from + * + * returns the address of the next descriptor, or NULL if not available. + */ +static struct gelic_net_descr * +gelic_net_get_next_tx_descr(struct gelic_net_card *card) +{ + if (!card->tx_chain.head) + return NULL; + /* see if we can two consecutive free descrs */ + if (card->tx_chain.tail != card->tx_chain.head->next && + gelic_net_get_descr_status(card->tx_chain.head) == + GELIC_NET_DESCR_NOT_IN_USE && + card->tx_chain.tail != card->tx_chain.head->next->next && + gelic_net_get_descr_status(card->tx_chain.head->next) == + GELIC_NET_DESCR_NOT_IN_USE ) + return card->tx_chain.head; + else + return NULL; + +} + +/** + * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field + * @descr: descriptor structure to fill out + * @skb: packet to consider + * @middle: middle of frame + * + * fills out the command and status field of the descriptor structure, + * depending on hardware checksum settings. This function assumes a wmb() + * has executed before. + */ +static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr, + struct sk_buff *skb, int middle) +{ + u32 eofr; + + if (middle) + eofr = 0; + else + eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; + else { + /* is packet ip? + * if yes: tcp? udp? */ + if (skb->protocol == htons(ETH_P_IP)) { + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + descr->dmac_cmd_status = + GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr; + else if (ip_hdr(skb)->protocol == IPPROTO_UDP) + descr->dmac_cmd_status = + GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr; + else /* + * the stack should checksum non-tcp and non-udp + * packets on his own: NETIF_F_IP_CSUM + */ + descr->dmac_cmd_status = + GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; + } + } +} + +/** + * gelic_net_prepare_tx_descr_v - get dma address of skb_data + * @card: card structure + * @descr: descriptor structure + * @skb: packet to use + * + * returns 0 on success, <0 on failure. + * + */ +static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card, + struct gelic_net_descr *descr, + struct sk_buff *skb) +{ + dma_addr_t buf[2]; + unsigned int vlan_len; + + if (skb->len < GELIC_NET_VLAN_POS) + return -EINVAL; + + memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS); + if (card->vlan_index != -1) { + descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/ + descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]); + vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */ + } else + vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */ + + /* first descr */ + buf[0] = dma_map_single(ctodev(card), &descr->vlan, + vlan_len, DMA_TO_DEVICE); + + if (!buf[0]) { + dev_err(ctodev(card), + "dma map 1 failed (%p, %i). Dropping packet\n", + skb->data, vlan_len); + return -ENOMEM; + } + + descr->buf_addr = buf[0]; + descr->buf_size = vlan_len; + descr->skb = skb; /* not used */ + descr->data_status = 0; + gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */ + + /* second descr */ + card->tx_chain.head = card->tx_chain.head->next; + descr->next_descr_addr = descr->next->bus_addr; + descr = descr->next; + if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) + /* XXX will be removed */ + dev_err(ctodev(card), "descr is not free!\n"); + + buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS, + skb->len - GELIC_NET_VLAN_POS, + DMA_TO_DEVICE); + + if (!buf[1]) { + dev_err(ctodev(card), + "dma map 2 failed (%p, %i). Dropping packet\n", + skb->data + GELIC_NET_VLAN_POS, + skb->len - GELIC_NET_VLAN_POS); + dma_unmap_single(ctodev(card), buf[0], vlan_len, + DMA_TO_DEVICE); + return -ENOMEM; + } + + descr->buf_addr = buf[1]; + descr->buf_size = skb->len - GELIC_NET_VLAN_POS; + descr->skb = skb; + descr->data_status = 0; + descr->next_descr_addr = 0; /* terminate hw descr */ + gelic_net_set_txdescr_cmdstat(descr, skb, 0); + + return 0; +} + +/** + * gelic_net_kick_txdma - enables TX DMA processing + * @card: card structure + * @descr: descriptor address to enable TX processing at + * + */ +static int gelic_net_kick_txdma(struct gelic_net_card *card, + struct gelic_net_descr *descr) +{ + int status = -ENXIO; + int count = 10; + + if (card->tx_dma_progress) + return 0; + + if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) { + card->tx_dma_progress = 1; + /* sometimes we need retry here */ + while (count--) { + status = lv1_net_start_tx_dma(bus_id(card), + dev_id(card), + descr->bus_addr, 0); + if (!status) + break; + } + if (!count) + dev_info(ctodev(card), "lv1_net_start_txdma failed," \ + "status=%d %#lx\n", + status, card->irq_status); + } + return status; +} + +/** + * gelic_net_xmit - transmits a frame over the device + * @skb: packet to send out + * @netdev: interface device structure + * + * returns 0 on success, <0 on failure + */ +static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + struct gelic_net_descr *descr = NULL; + int result; + unsigned long flags; + + spin_lock_irqsave(&card->tx_dma_lock, flags); + + gelic_net_release_tx_chain(card, 0); + if (!skb) + goto kick; + descr = gelic_net_get_next_tx_descr(card); + if (!descr) { + netif_stop_queue(netdev); + spin_unlock_irqrestore(&card->tx_dma_lock, flags); + return NETDEV_TX_BUSY; + } + result = gelic_net_prepare_tx_descr_v(card, descr, skb); + + if (result) + goto error; + + card->tx_chain.head = card->tx_chain.head->next; + + if (descr->prev) + descr->prev->next_descr_addr = descr->bus_addr; +kick: + /* + * as hardware descriptor is modified in the above lines, + * ensure that the hardware sees it + */ + wmb(); + if (gelic_net_kick_txdma(card, card->tx_chain.tail)) + goto error; + + netdev->trans_start = jiffies; + spin_unlock_irqrestore(&card->tx_dma_lock, flags); + return NETDEV_TX_OK; + +error: + card->netdev_stats.tx_dropped++; + spin_unlock_irqrestore(&card->tx_dma_lock, flags); + return NETDEV_TX_LOCKED; +} + +/** + * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on + * @descr: descriptor to process + * @card: card structure + * + * iommu-unmaps the skb, fills out skb structure and passes the data to the + * stack. The descriptor state is not changed. + */ +static void gelic_net_pass_skb_up(struct gelic_net_descr *descr, + struct gelic_net_card *card) +{ + struct sk_buff *skb; + struct net_device *netdev; + u32 data_status, data_error; + + data_status = descr->data_status; + data_error = descr->data_error; + netdev = card->netdev; + /* unmap skb buffer */ + skb = descr->skb; + dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU, + DMA_FROM_DEVICE); + + skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size); + if (!descr->valid_size) + dev_info(ctodev(card), "buffer full %x %x %x\n", + descr->result_size, descr->buf_size, + descr->dmac_cmd_status); + + descr->skb = NULL; + /* + * the card put 2 bytes vlan tag in front + * of the ethernet frame + */ + skb_pull(skb, 2); + skb->protocol = eth_type_trans(skb, netdev); + + /* checksum offload */ + if (card->rx_csum) { + if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) && + (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + } else + skb->ip_summed = CHECKSUM_NONE; + + /* update netdevice statistics */ + card->netdev_stats.rx_packets++; + card->netdev_stats.rx_bytes += skb->len; + + /* pass skb up to stack */ + netif_receive_skb(skb); +} + +/** + * gelic_net_decode_one_descr - processes an rx descriptor + * @card: card structure + * + * returns 1 if a packet has been sent to the stack, otherwise 0 + * + * processes an rx descriptor by iommu-unmapping the data buffer and passing + * the packet up to the stack + */ +static int gelic_net_decode_one_descr(struct gelic_net_card *card) +{ + enum gelic_net_descr_status status; + struct gelic_net_descr_chain *chain = &card->rx_chain; + struct gelic_net_descr *descr = chain->tail; + int dmac_chain_ended; + + status = gelic_net_get_descr_status(descr); + /* is this descriptor terminated with next_descr == NULL? */ + dmac_chain_ended = + descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS; + + if (status == GELIC_NET_DESCR_CARDOWNED) + return 0; + + if (status == GELIC_NET_DESCR_NOT_IN_USE) { + dev_dbg(ctodev(card), "dormant descr? %p\n", descr); + return 0; + } + + if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) || + (status == GELIC_NET_DESCR_PROTECTION_ERROR) || + (status == GELIC_NET_DESCR_FORCE_END)) { + dev_info(ctodev(card), "dropping RX descriptor with state %x\n", + status); + card->netdev_stats.rx_dropped++; + goto refill; + } + + if ((status != GELIC_NET_DESCR_COMPLETE) && + (status != GELIC_NET_DESCR_FRAME_END)) { + dev_dbg(ctodev(card), "RX descriptor with state %x\n", + status); + goto refill; + } + + /* ok, we've got a packet in descr */ + gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */ + +refill: + descr->next_descr_addr = 0; /* unlink the descr */ + + /* change the descriptor state: */ + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); + + /* refill one desc + * FIXME: this can fail, but for now, just leave this + * descriptor without skb + */ + gelic_net_prepare_rx_descr(card, descr); + chain->head = descr; + chain->tail = descr->next; + descr->prev->next_descr_addr = descr->bus_addr; + + if (dmac_chain_ended) { + gelic_net_enable_rxdmac(card); + dev_dbg(ctodev(card), "reenable rx dma\n"); + } + + return 1; +} + +/** + * gelic_net_poll - NAPI poll function called by the stack to return packets + * @netdev: interface device structure + * @budget: number of packets we can pass to the stack at most + * + * returns 0 if no more packets available to the driver/stack. Returns 1, + * if the quota is exceeded, but the driver has still packets. + * + */ +static int gelic_net_poll(struct net_device *netdev, int *budget) +{ + struct gelic_net_card *card = netdev_priv(netdev); + int packets_to_do, packets_done = 0; + int no_more_packets = 0; + + packets_to_do = min(*budget, netdev->quota); + + while (packets_to_do) { + if (gelic_net_decode_one_descr(card)) { + packets_done++; + packets_to_do--; + } else { + /* no more packets for the stack */ + no_more_packets = 1; + break; + } + } + netdev->quota -= packets_done; + *budget -= packets_done; + if (no_more_packets) { + netif_rx_complete(netdev); + gelic_net_rx_irq_on(card); + return 0; + } else + return 1; +} + +/** + * gelic_net_get_stats - get interface statistics + * @netdev: interface device structure + * + * returns the interface statistics residing in the gelic_net_card struct + */ +static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + return &card->netdev_stats; +} + +/** + * gelic_net_change_mtu - changes the MTU of an interface + * @netdev: interface device structure + * @new_mtu: new MTU value + * + * returns 0 on success, <0 on failure + */ +static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) +{ + /* no need to re-alloc skbs or so -- the max mtu is about 2.3k + * and mtu is outbound only anyway */ + if ((new_mtu < GELIC_NET_MIN_MTU) || + (new_mtu > GELIC_NET_MAX_MTU)) { + return -EINVAL; + } + netdev->mtu = new_mtu; + return 0; +} + +/** + * gelic_net_interrupt - event handler for gelic_net + */ +static irqreturn_t gelic_net_interrupt(int irq, void *ptr) +{ + unsigned long flags; + struct net_device *netdev = ptr; + struct gelic_net_card *card = netdev_priv(netdev); + u64 status; + + status = card->irq_status; + + if (!status) + return IRQ_NONE; + + if (status & GELIC_NET_RXINT) { + gelic_net_rx_irq_off(card); + netif_rx_schedule(netdev); + } + + if (status & GELIC_NET_TXINT) { + spin_lock_irqsave(&card->tx_dma_lock, flags); + card->tx_dma_progress = 0; + spin_unlock_irqrestore(&card->tx_dma_lock, flags); + /* start pending DMA */ + gelic_net_xmit(NULL, netdev); + } + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * gelic_net_poll_controller - artificial interrupt for netconsole etc. + * @netdev: interface device structure + * + * see Documentation/networking/netconsole.txt + */ +static void gelic_net_poll_controller(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + gelic_net_set_irq_mask(card, 0); + gelic_net_interrupt(netdev->irq, netdev); + gelic_net_set_irq_mask(card, card->ghiintmask); +} +#endif /* CONFIG_NET_POLL_CONTROLLER */ + +/** + * gelic_net_open_device - open device and map dma region + * @card: card structure + */ +static int gelic_net_open_device(struct gelic_net_card *card) +{ + int result; + + result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY, + &card->netdev->irq); + + if (result) { + dev_info(ctodev(card), + "%s:%d: gelic_net_open_device failed (%d)\n", + __func__, __LINE__, result); + result = -EPERM; + goto fail_alloc_irq; + } + + result = request_irq(card->netdev->irq, gelic_net_interrupt, + IRQF_DISABLED, "gelic network", card->netdev); + + if (result) { + dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n", + __func__, __LINE__, result); + goto fail_request_irq; + } + + return 0; + +fail_request_irq: + ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); + card->netdev->irq = NO_IRQ; +fail_alloc_irq: + return result; +} + + +/** + * gelic_net_open - called upon ifonfig up + * @netdev: interface device structure + * + * returns 0 on success, <0 on failure + * + * gelic_net_open allocates all the descriptors and memory needed for + * operation, sets up multicast list and enables interrupts + */ +static int gelic_net_open(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__); + + gelic_net_open_device(card); + + if (gelic_net_init_chain(card, &card->tx_chain, + card->descr, GELIC_NET_TX_DESCRIPTORS)) + goto alloc_tx_failed; + if (gelic_net_init_chain(card, &card->rx_chain, + card->descr + GELIC_NET_RX_DESCRIPTORS, + GELIC_NET_RX_DESCRIPTORS)) + goto alloc_rx_failed; + + /* head of chain */ + card->tx_top = card->tx_chain.head; + card->rx_top = card->rx_chain.head; + dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n", + card->rx_top, card->tx_top, sizeof(struct gelic_net_descr), + GELIC_NET_RX_DESCRIPTORS); + /* allocate rx skbs */ + if (gelic_net_alloc_rx_skbs(card)) + goto alloc_skbs_failed; + + card->tx_dma_progress = 0; + card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT; + + gelic_net_set_irq_mask(card, card->ghiintmask); + gelic_net_enable_rxdmac(card); + + netif_start_queue(netdev); + netif_carrier_on(netdev); + netif_poll_enable(netdev); + + return 0; + +alloc_skbs_failed: + gelic_net_free_chain(card, card->rx_top); +alloc_rx_failed: + gelic_net_free_chain(card, card->tx_top); +alloc_tx_failed: + return -ENOMEM; +} + +#ifdef GELIC_NET_ETHTOOL +static void gelic_net_get_drvinfo (struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1); + strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1); +} + +static int gelic_net_get_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct gelic_net_card *card = netdev_priv(netdev); + int status; + u64 v1, v2; + int speed, duplex; + + speed = duplex = -1; + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, + &v1, &v2); + if (status) { + /* link down */ + } else { + if (v1 & GELIC_NET_FULL_DUPLEX) { + duplex = DUPLEX_FULL; + } else { + duplex = DUPLEX_HALF; + } + + if (v1 & GELIC_NET_SPEED_10 ) { + speed = SPEED_10; + } else if (v1 & GELIC_NET_SPEED_100) { + speed = SPEED_100; + } else if (v1 & GELIC_NET_SPEED_1000) { + speed = SPEED_1000; + } + } + cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | + SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + cmd->advertising = cmd->supported; + cmd->speed = speed; + cmd->duplex = duplex; + cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ + cmd->port = PORT_TP; + + return 0; +} + +static u32 gelic_net_get_link(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + int status; + u64 v1, v2; + int link; + + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, + &v1, &v2); + if (status) + return 0; /* link down */ + + if (v1 & GELIC_NET_LINK_UP) + link = 1; + else + link = 0; + + return link; +} + +static int gelic_net_nway_reset(struct net_device *netdev) +{ + if (netif_running(netdev)) { + gelic_net_stop(netdev); + gelic_net_open(netdev); + } + return 0; +} + +static u32 gelic_net_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_IP_CSUM) != 0; +} + +static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data) +{ + if (data) + netdev->features |= NETIF_F_IP_CSUM; + else + netdev->features &= ~NETIF_F_IP_CSUM; + + return 0; +} + +static u32 gelic_net_get_rx_csum(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + return card->rx_csum; +} + +static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) +{ + struct gelic_net_card *card = netdev_priv(netdev); + + card->rx_csum = data; + return 0; +} + +static struct ethtool_ops gelic_net_ethtool_ops = { + .get_drvinfo = gelic_net_get_drvinfo, + .get_settings = gelic_net_get_settings, + .get_link = gelic_net_get_link, + .nway_reset = gelic_net_nway_reset, + .get_tx_csum = gelic_net_get_tx_csum, + .set_tx_csum = gelic_net_set_tx_csum, + .get_rx_csum = gelic_net_get_rx_csum, + .set_rx_csum = gelic_net_set_rx_csum, +}; +#endif + +/** + * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout + * function (to be called not under interrupt status) + * @work: work is context of tx timout task + * + * called as task when tx hangs, resets interface (if interface is up) + */ +static void gelic_net_tx_timeout_task(struct work_struct *work) +{ + struct gelic_net_card *card = + container_of(work, struct gelic_net_card, tx_timeout_task); + struct net_device *netdev = card->netdev; + + dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); + + if (!(netdev->flags & IFF_UP)) + goto out; + + netif_device_detach(netdev); + gelic_net_stop(netdev); + + gelic_net_open(netdev); + netif_device_attach(netdev); + +out: + atomic_dec(&card->tx_timeout_task_counter); +} + +/** + * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in. + * @netdev: interface device structure + * + * called, if tx hangs. Schedules a task that resets the interface + */ +static void gelic_net_tx_timeout(struct net_device *netdev) +{ + struct gelic_net_card *card; + + card = netdev_priv(netdev); + atomic_inc(&card->tx_timeout_task_counter); + if (netdev->flags & IFF_UP) + schedule_work(&card->tx_timeout_task); + else + atomic_dec(&card->tx_timeout_task_counter); +} + +/** + * gelic_net_setup_netdev_ops - initialization of net_device operations + * @netdev: net_device structure + * + * fills out function pointers in the net_device structure + */ +static void gelic_net_setup_netdev_ops(struct net_device *netdev) +{ + netdev->open = &gelic_net_open; + netdev->stop = &gelic_net_stop; + netdev->hard_start_xmit = &gelic_net_xmit; + netdev->get_stats = &gelic_net_get_stats; + netdev->set_multicast_list = &gelic_net_set_multi; + netdev->change_mtu = &gelic_net_change_mtu; + /* tx watchdog */ + netdev->tx_timeout = &gelic_net_tx_timeout; + netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT; + /* NAPI */ + netdev->poll = &gelic_net_poll; + netdev->weight = GELIC_NET_NAPI_WEIGHT; +#ifdef GELIC_NET_ETHTOOL + netdev->ethtool_ops = &gelic_net_ethtool_ops; +#endif +} + +/** + * gelic_net_setup_netdev - initialization of net_device + * @card: card structure + * + * Returns 0 on success or <0 on failure + * + * gelic_net_setup_netdev initializes the net_device structure + **/ +static int gelic_net_setup_netdev(struct gelic_net_card *card) +{ + struct net_device *netdev = card->netdev; + struct sockaddr addr; + unsigned int i; + int status; + u64 v1, v2; + + SET_MODULE_OWNER(netdev); + SET_NETDEV_DEV(netdev, &card->dev->core); + spin_lock_init(&card->tx_dma_lock); + + card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT; + + gelic_net_setup_netdev_ops(netdev); + + netdev->features = NETIF_F_IP_CSUM; + + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_MAC_ADDRESS, + 0, 0, 0, &v1, &v2); + if (status || !is_valid_ether_addr((u8 *)&v1)) { + dev_info(ctodev(card), + "%s:lv1_net_control GET_MAC_ADDR failed %d\n", + __func__, status); + return -EINVAL; + } + v1 <<= 16; + memcpy(addr.sa_data, &v1, ETH_ALEN); + memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN); + dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", + netdev->dev_addr[0], netdev->dev_addr[1], + netdev->dev_addr[2], netdev->dev_addr[3], + netdev->dev_addr[4], netdev->dev_addr[5]); + + card->vlan_index = -1; /* no vlan */ + for (i = 0; i < GELIC_NET_VLAN_MAX; i++) { + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_VLAN_ID, + i + 1, /* index; one based */ + 0, 0, &v1, &v2); + if (status == GELIC_NET_VLAN_NO_ENTRY) { + dev_dbg(ctodev(card), + "GELIC_VLAN_ID no entry:%d, VLAN disabled\n", + status); + card->vlan_id[i] = 0; + } else if (status) { + dev_dbg(ctodev(card), + "%s:GELIC_NET_VLAN_ID faild, status=%d\n", + __func__, status); + card->vlan_id[i] = 0; + } else { + card->vlan_id[i] = (u32)v1; + dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1); + } + } + if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) + card->vlan_index = GELIC_NET_VLAN_WIRED - 1; + + status = register_netdev(netdev); + if (status) { + dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n", + __func__, status); + return status; + } + + return 0; +} + +/** + * gelic_net_alloc_card - allocates net_device and card structure + * + * returns the card structure or NULL in case of errors + * + * the card and net_device structures are linked to each other + */ +static struct gelic_net_card *gelic_net_alloc_card(void) +{ + struct net_device *netdev; + struct gelic_net_card *card; + size_t alloc_size; + + alloc_size = sizeof (*card) + + sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS + + sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS; + /* + * we assume private data is allocated 32 bytes (or more) aligned + * so that gelic_net_descr should be 32 bytes aligned. + * Current alloc_etherdev() does do it because NETDEV_ALIGN + * is 32. + * check this assumption here. + */ + BUILD_BUG_ON(NETDEV_ALIGN < 32); + BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8); + BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32); + + netdev = alloc_etherdev(alloc_size); + if (!netdev) + return NULL; + + card = netdev_priv(netdev); + card->netdev = netdev; + INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); + init_waitqueue_head(&card->waitq); + atomic_set(&card->tx_timeout_task_counter, 0); + + return card; +} + +/** + * ps3_gelic_driver_probe - add a device to the control of this driver + */ +static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev) +{ + struct gelic_net_card *card = gelic_net_alloc_card(); + int result; + + if (!card) { + dev_info(&dev->core, "gelic_net_alloc_card failed\n"); + result = -ENOMEM; + goto fail_alloc_card; + } + + ps3_system_bus_set_driver_data(dev, card); + card->dev = dev; + + result = ps3_open_hv_device(dev); + + if (result) { + dev_dbg(&dev->core, "ps3_open_hv_device failed\n"); + goto fail_open; + } + + result = ps3_dma_region_create(dev->d_region); + + if (result) { + dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n", + result); + BUG_ON("check region type"); + goto fail_dma_region; + } + + result = lv1_net_set_interrupt_status_indicator(bus_id(card), + dev_id(card), + ps3_mm_phys_to_lpar(__pa(&card->irq_status)), + 0); + + if (result) { + dev_dbg(&dev->core, + "lv1_net_set_interrupt_status_indicator failed: %s\n", + ps3_result(result)); + result = -EIO; + goto fail_status_indicator; + } + + result = gelic_net_setup_netdev(card); + + if (result) { + dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " + "(%d)\n", __func__, __LINE__, result); + goto fail_setup_netdev; + } + + return 0; + +fail_setup_netdev: + lv1_net_set_interrupt_status_indicator(bus_id(card), + bus_id(card), + 0 , 0); +fail_status_indicator: + ps3_dma_region_free(dev->d_region); +fail_dma_region: + ps3_close_hv_device(dev); +fail_open: + ps3_system_bus_set_driver_data(dev, NULL); + free_netdev(card->netdev); +fail_alloc_card: + return result; +} + +/** + * ps3_gelic_driver_remove - remove a device from the control of this driver + */ + +static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev) +{ + struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev); + + wait_event(card->waitq, + atomic_read(&card->tx_timeout_task_counter) == 0); + + lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card), + 0 , 0); + + unregister_netdev(card->netdev); + free_netdev(card->netdev); + + ps3_system_bus_set_driver_data(dev, NULL); + + ps3_dma_region_free(dev->d_region); + + ps3_close_hv_device(dev); + + return 0; +} + +static struct ps3_system_bus_driver ps3_gelic_driver = { + .match_id = PS3_MATCH_ID_GELIC, + .probe = ps3_gelic_driver_probe, + .remove = ps3_gelic_driver_remove, + .shutdown = ps3_gelic_driver_remove, + .core.name = "ps3_gelic_driver", + .core.owner = THIS_MODULE, +}; + +static int __init ps3_gelic_driver_init (void) +{ + return firmware_has_feature(FW_FEATURE_PS3_LV1) + ? ps3_system_bus_driver_register(&ps3_gelic_driver) + : -ENODEV; +} + +static void __exit ps3_gelic_driver_exit (void) +{ + ps3_system_bus_driver_unregister(&ps3_gelic_driver); +} + +module_init (ps3_gelic_driver_init); +module_exit (ps3_gelic_driver_exit); + +MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC); + diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h new file mode 100644 index 000000000000..5e1c28654e16 --- /dev/null +++ b/drivers/net/ps3_gelic_net.h @@ -0,0 +1,239 @@ +/* + * PS3 Platfom gelic network driver. + * + * Copyright (C) 2007 Sony Computer Entertainment Inc. + * Copyright 2006, 2007 Sony Corporation. + * + * This file is based on: spider_net.h + * + * (C) Copyright IBM Corp. 2005 + * + * Authors : Utz Bacher + * Jens Osterkamp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _GELIC_NET_H +#define _GELIC_NET_H + +#define GELIC_NET_DRV_NAME "Gelic Network Driver" +#define GELIC_NET_DRV_VERSION "1.0" + +#define GELIC_NET_ETHTOOL /* use ethtool */ + +/* ioctl */ +#define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0) +#define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1) + +/* descriptors */ +#define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */ +#define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */ + +#define GELIC_NET_MAX_MTU 2308 +#define GELIC_NET_MIN_MTU 64 +#define GELIC_NET_RXBUF_ALIGN 128 +#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */ +#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ +#define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS) +#define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL +#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2) +#define GELIC_NET_VLAN_MAX 4 +#define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */ + +enum gelic_net_int0_status { + GELIC_NET_GDTDCEINT = 24, + GELIC_NET_GRFANMINT = 28, +}; + +/* GHIINT1STS bits */ +enum gelic_net_int1_status { + GELIC_NET_GDADCEINT = 14, +}; + +/* interrupt mask */ +#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32)) + +#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32)) +#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT) +#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1) + + /* RX descriptor data_status bits */ +#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */ +#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */ +#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */ +#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */ +#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */ +#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */ +#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */ +#define GELIC_NET_RXSESPAH 0x01000000 /* + * IPsec ESP protocol auth + * performed + */ + +#define GELIC_NET_RXWTPKT 0x00C00000 /* + * wakeup trigger packet + * 01: Magic Packet (TM) + * 10: ARP packet + * 11: Multicast MAC addr + */ +#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */ +/* bit 20..16 reserved */ +#define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */ +/* bit 7..0 reserved */ + +#define GELIC_NET_TXDESC_TAIL 0 +#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK) + +/* RX descriptor data_error bits */ +/* bit 31 reserved */ +#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */ +#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */ +#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */ +#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */ +#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */ +#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */ +#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */ +#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */ +#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol + * processing */ +#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol + * processing */ +#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */ +#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */ +/* bit 18 reserved */ +#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */ +#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length + * error */ +#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */ +#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */ +/* bit 13..0 reserved */ +#define GELIC_NET_DATA_ERROR_CHK_MASK \ + (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR) + + +/* tx descriptor command and status */ +#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */ +#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000 +#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000 +#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */ + +#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end + * interrupt status */ + +#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */ +#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000 +#define GELIC_NET_DESCR_IND_PROC_SHIFT 28 +#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff + + +enum gelic_net_descr_status { + GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ + GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ + GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ + GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */ + GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ + GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ + GELIC_NET_DESCR_NOT_IN_USE /* any other value */ +}; +/* for lv1_net_control */ +#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001 +#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002 +#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003 +#define GELIC_NET_GET_VLAN_ID 0x0000000000000004 + +#define GELIC_NET_LINK_UP 0x0000000000000001 +#define GELIC_NET_FULL_DUPLEX 0x0000000000000002 +#define GELIC_NET_AUTO_NEG 0x0000000000000004 +#define GELIC_NET_SPEED_10 0x0000000000000010 +#define GELIC_NET_SPEED_100 0x0000000000000020 +#define GELIC_NET_SPEED_1000 0x0000000000000040 + +#define GELIC_NET_VLAN_ALL 0x0000000000000001 +#define GELIC_NET_VLAN_WIRED 0x0000000000000002 +#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003 +#define GELIC_NET_VLAN_PSP 0x0000000000000004 +#define GELIC_NET_VLAN_PORT0 0x0000000000000010 +#define GELIC_NET_VLAN_PORT1 0x0000000000000011 +#define GELIC_NET_VLAN_PORT2 0x0000000000000012 +#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013 +#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014 +#define GELIC_NET_VLAN_NO_ENTRY -6 + +#define GELIC_NET_PORT 2 /* for port status */ + +/* size of hardware part of gelic descriptor */ +#define GELIC_NET_DESCR_SIZE (32) +struct gelic_net_descr { + /* as defined by the hardware */ + u32 buf_addr; + u32 buf_size; + u32 next_descr_addr; + u32 dmac_cmd_status; + u32 result_size; + u32 valid_size; /* all zeroes for tx */ + u32 data_status; + u32 data_error; /* all zeroes for tx */ + + /* used in the driver */ + struct sk_buff *skb; + dma_addr_t bus_addr; + struct gelic_net_descr *next; + struct gelic_net_descr *prev; + struct vlan_ethhdr vlan; +} __attribute__((aligned(32))); + +struct gelic_net_descr_chain { + /* we walk from tail to head */ + struct gelic_net_descr *head; + struct gelic_net_descr *tail; +}; + +struct gelic_net_card { + struct net_device *netdev; + /* + * hypervisor requires irq_status should be + * 8 bytes aligned, but u64 member is + * always disposed in that manner + */ + u64 irq_status; + u64 ghiintmask; + + struct ps3_system_bus_device *dev; + u32 vlan_id[GELIC_NET_VLAN_MAX]; + int vlan_index; + + struct gelic_net_descr_chain tx_chain; + struct gelic_net_descr_chain rx_chain; + /* gurad dmac descriptor chain*/ + spinlock_t chain_lock; + + struct net_device_stats netdev_stats; + int rx_csum; + /* guard tx_dma_progress */ + spinlock_t tx_dma_lock; + int tx_dma_progress; + + struct work_struct tx_timeout_task; + atomic_t tx_timeout_task_counter; + wait_queue_head_t waitq; + + struct gelic_net_descr *tx_top, *rx_top; + struct gelic_net_descr descr[0]; +}; + + +extern unsigned long p_to_lp(long pa); + +#endif /* _GELIC_NET_H */ From 4ad072c984ebe329c99965ddd1e58b0bb24af12b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jul 2007 11:51:12 -0700 Subject: [PATCH 547/551] bonding/bond_main.c: make 2 functions static Signed-off-by: Adrian Bunk Cc: Chad Tindel Cc: Jay Vosburgh Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/bonding/bond_main.c | 5 +++-- drivers/net/bonding/bonding.h | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2bb70e052090..cb9cb3013f42 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -187,7 +187,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond); /*---------------------------- General routines -----------------------------*/ -const char *bond_mode_name(int mode) +static const char *bond_mode_name(int mode) { switch (mode) { case BOND_MODE_ROUNDROBIN : @@ -1224,7 +1224,8 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave) /*---------------------------------- IOCTL ----------------------------------*/ -int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) +static int bond_sethwaddr(struct net_device *bond_dev, + struct net_device *slave_dev) { dprintk("bond_dev=%p\n", bond_dev); dprintk("slave_dev=%p\n", slave_dev); diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index a89102116ccb..6dcbd25e3ef0 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -301,13 +301,11 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); -int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev); void bond_mii_monitor(struct net_device *bond_dev); void bond_loadbalance_arp_mon(struct net_device *bond_dev); void bond_activebackup_arp_mon(struct net_device *bond_dev); void bond_set_mode_ops(struct bonding *bond, int mode); int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); -const char *bond_mode_name(int mode); void bond_select_active_slave(struct bonding *bond); void bond_change_active_slave(struct bonding *bond, struct slave *new_active); void bond_register_arp(struct bonding *); From 64c70b1cf43de158282bc1675918d503e5b15cc1 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 10 Jul 2007 17:22:24 -0700 Subject: [PATCH 548/551] Add LZO1X algorithm to the kernel This is a hybrid version of the patch to add the LZO1X compression algorithm to the kernel. Nitin and myself have merged the best parts of the various patches to form this version which we're both happy with (and are jointly signing off). The performance of this version is equivalent to the original minilzo code it was based on. Bytecode comparisons have also been made on ARM, i386 and x86_64 with favourable results. There are several users of LZO lined up including jffs2, crypto and reiser4 since its much faster than zlib. Signed-off-by: Nitin Gupta Signed-off-by: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/lzo.h | 44 +++++++ lib/Kconfig | 6 + lib/Makefile | 2 + lib/lzo/Makefile | 5 + lib/lzo/lzo1x_compress.c | 226 +++++++++++++++++++++++++++++++++ lib/lzo/lzo1x_decompress.c | 254 +++++++++++++++++++++++++++++++++++++ lib/lzo/lzodefs.h | 43 +++++++ 7 files changed, 580 insertions(+) create mode 100644 include/linux/lzo.h create mode 100644 lib/lzo/Makefile create mode 100644 lib/lzo/lzo1x_compress.c create mode 100644 lib/lzo/lzo1x_decompress.c create mode 100644 lib/lzo/lzodefs.h diff --git a/include/linux/lzo.h b/include/linux/lzo.h new file mode 100644 index 000000000000..582d8b711a13 --- /dev/null +++ b/include/linux/lzo.h @@ -0,0 +1,44 @@ +#ifndef __LZO_H__ +#define __LZO_H__ +/* + * LZO Public Kernel Interface + * A mini subset of the LZO real-time data compression library + * + * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer + * + * The full LZO package can be found at: + * http://www.oberhumer.com/opensource/lzo/ + * + * Changed for kernel use by: + * Nitin Gupta + * Richard Purdie + */ + +#define LZO1X_MEM_COMPRESS (16384 * sizeof(unsigned char *)) +#define LZO1X_1_MEM_COMPRESS LZO1X_MEM_COMPRESS + +#define lzo1x_worst_compress(x) (x + (x / 64) + 16 + 3) + +/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */ +int lzo1x_1_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + +/* safe decompression with overrun testing */ +int lzo1x_decompress_safe(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len); + +/* + * Return values (< 0 = Error) + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) +#define LZO_E_NOT_COMPRESSIBLE (-3) +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) + +#endif diff --git a/lib/Kconfig b/lib/Kconfig index 2e7ae6b9215b..3eb29d5dc4f5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -64,6 +64,12 @@ config ZLIB_INFLATE config ZLIB_DEFLATE tristate +config LZO_COMPRESS + tristate + +config LZO_DECOMPRESS + tristate + # # Generic allocator support is selected if needed # diff --git a/lib/Makefile b/lib/Makefile index c8c8e20784ce..d1b366bdf86e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -49,6 +49,8 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ +obj-$(CONFIG_LZO_COMPRESS) += lzo/ +obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile new file mode 100644 index 000000000000..e764116ea12d --- /dev/null +++ b/lib/lzo/Makefile @@ -0,0 +1,5 @@ +lzo_compress-objs := lzo1x_compress.o +lzo_decompress-objs := lzo1x_decompress.o + +obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o +obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c new file mode 100644 index 000000000000..c935f00073e9 --- /dev/null +++ b/lib/lzo/lzo1x_compress.c @@ -0,0 +1,226 @@ +/* + * LZO1X Compressor from MiniLZO + * + * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer + * + * The full LZO package can be found at: + * http://www.oberhumer.com/opensource/lzo/ + * + * Changed for kernel use by: + * Nitin Gupta + * Richard Purdie + */ + +#include +#include +#include +#include +#include "lzodefs.h" + +static noinline size_t +_lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + unsigned char *out, size_t *out_len, void *wrkmem) +{ + const unsigned char * const in_end = in + in_len; + const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5; + const unsigned char ** const dict = wrkmem; + const unsigned char *ip = in, *ii = ip; + const unsigned char *end, *m, *m_pos; + size_t m_off, m_len, dindex; + unsigned char *op = out; + + ip += 4; + + for (;;) { + dindex = ((0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK; + m_pos = dict[dindex]; + + if (m_pos < in) + goto literal; + + if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET) + goto literal; + + m_off = ip - m_pos; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + + dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f); + m_pos = dict[dindex]; + + if (m_pos < in) + goto literal; + + if (ip == m_pos || (ip - m_pos) > M4_MAX_OFFSET) + goto literal; + + m_off = ip - m_pos; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + + goto literal; + +try_match: + if (get_unaligned((const unsigned short *)m_pos) + == get_unaligned((const unsigned short *)ip)) { + if (likely(m_pos[2] == ip[2])) + goto match; + } + +literal: + dict[dindex] = ip; + ++ip; + if (unlikely(ip >= ip_end)) + break; + continue; + +match: + dict[dindex] = ip; + if (ip != ii) { + size_t t = ip - ii; + + if (t <= 3) { + op[-2] |= t; + } else if (t <= 18) { + *op++ = (t - 3); + } else { + size_t tt = t - 18; + + *op++ = 0; + while (tt > 255) { + tt -= 255; + *op++ = 0; + } + *op++ = tt; + } + do { + *op++ = *ii++; + } while (--t > 0); + } + + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ + || m_pos[5] != *ip++ || m_pos[6] != *ip++ + || m_pos[7] != *ip++ || m_pos[8] != *ip++) { + --ip; + m_len = ip - ii; + + if (m_off <= M2_MAX_OFFSET) { + m_off -= 1; + *op++ = (((m_len - 1) << 5) + | ((m_off & 7) << 2)); + *op++ = (m_off >> 3); + } else if (m_off <= M3_MAX_OFFSET) { + m_off -= 1; + *op++ = (M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } else { + m_off -= 0x4000; + + *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11) + | (m_len - 2)); + goto m3_m4_offset; + } + } else { + end = in_end; + m = m_pos + M2_MAX_LEN + 1; + + while (ip < end && *m == *ip) { + m++; + ip++; + } + m_len = ip - ii; + + if (m_off <= M3_MAX_OFFSET) { + m_off -= 1; + if (m_len <= 33) { + *op++ = (M3_MARKER | (m_len - 2)); + } else { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } else { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) { + *op++ = (M4_MARKER + | ((m_off & 0x4000) >> 11) + | (m_len - 2)); + } else { + m_len -= M4_MAX_LEN; + *op++ = (M4_MARKER + | ((m_off & 0x4000) >> 11)); +m3_m4_len: + while (m_len > 255) { + m_len -= 255; + *op++ = 0; + } + + *op++ = (m_len); + } + } +m3_m4_offset: + *op++ = ((m_off & 63) << 2); + *op++ = (m_off >> 6); + } + + ii = ip; + if (unlikely(ip >= ip_end)) + break; + } + + *out_len = op - out; + return in_end - ii; +} + +int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out, + size_t *out_len, void *wrkmem) +{ + const unsigned char *ii; + unsigned char *op = out; + size_t t; + + if (unlikely(in_len <= M2_MAX_LEN + 5)) { + t = in_len; + } else { + t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem); + op += *out_len; + } + + if (t > 0) { + ii = in + in_len - t; + + if (op == out && t <= 238) { + *op++ = (17 + t); + } else if (t <= 3) { + op[-2] |= t; + } else if (t <= 18) { + *op++ = (t - 3); + } else { + size_t tt = t - 18; + + *op++ = 0; + while (tt > 255) { + tt -= 255; + *op++ = 0; + } + + *op++ = tt; + } + do { + *op++ = *ii++; + } while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = op - out; + return LZO_E_OK; +} +EXPORT_SYMBOL_GPL(lzo1x_1_compress); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LZO1X-1 Compressor"); + diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c new file mode 100644 index 000000000000..9dc7056e5520 --- /dev/null +++ b/lib/lzo/lzo1x_decompress.c @@ -0,0 +1,254 @@ +/* + * LZO1X Decompressor from MiniLZO + * + * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer + * + * The full LZO package can be found at: + * http://www.oberhumer.com/opensource/lzo/ + * + * Changed for kernel use by: + * Nitin Gupta + * Richard Purdie + */ + +#include +#include +#include +#include +#include +#include "lzodefs.h" + +#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x)) +#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x)) +#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op) + +#define COPY4(dst, src) \ + put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst)) + +int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, + unsigned char *out, size_t *out_len) +{ + const unsigned char * const ip_end = in + in_len; + unsigned char * const op_end = out + *out_len; + const unsigned char *ip = in, *m_pos; + unsigned char *op = out; + size_t t; + + *out_len = 0; + + if (*ip > 17) { + t = *ip++ - 17; + if (t < 4) + goto match_next; + if (HAVE_OP(t, op_end, op)) + goto output_overrun; + if (HAVE_IP(t + 1, ip_end, ip)) + goto input_overrun; + do { + *op++ = *ip++; + } while (--t > 0); + goto first_literal_run; + } + + while ((ip < ip_end)) { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) { + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + while (*ip == 0) { + t += 255; + ip++; + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + } + t += 15 + *ip++; + } + if (HAVE_OP(t + 3, op_end, op)) + goto output_overrun; + if (HAVE_IP(t + 4, ip_end, ip)) + goto input_overrun; + + COPY4(op, ip); + op += 4; + ip += 4; + if (--t > 0) { + if (t >= 4) { + do { + COPY4(op, ip); + op += 4; + ip += 4; + t -= 4; + } while (t >= 4); + if (t > 0) { + do { + *op++ = *ip++; + } while (--t > 0); + } + } else { + do { + *op++ = *ip++; + } while (--t > 0); + } + } + +first_literal_run: + t = *ip++; + if (t >= 16) + goto match; + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + + if (HAVE_LB(m_pos, out, op)) + goto lookbehind_overrun; + + if (HAVE_OP(3, op_end, op)) + goto output_overrun; + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos; + + goto match_done; + + do { +match: + if (t >= 64) { + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; + if (HAVE_LB(m_pos, out, op)) + goto lookbehind_overrun; + if (HAVE_OP(t + 3 - 1, op_end, op)) + goto output_overrun; + goto copy_match; + } else if (t >= 32) { + t &= 31; + if (t == 0) { + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + while (*ip == 0) { + t += 255; + ip++; + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + } + t += 31 + *ip++; + } + m_pos = op - 1; + m_pos -= le16_to_cpu(get_unaligned( + (const unsigned short *)ip)) >> 2; + ip += 2; + } else if (t >= 16) { + m_pos = op; + m_pos -= (t & 8) << 11; + + t &= 7; + if (t == 0) { + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + while (*ip == 0) { + t += 255; + ip++; + if (HAVE_IP(1, ip_end, ip)) + goto input_overrun; + } + t += 7 + *ip++; + } + m_pos -= le16_to_cpu(get_unaligned( + (const unsigned short *)ip) >> 2); + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; + } else { + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + + if (HAVE_LB(m_pos, out, op)) + goto lookbehind_overrun; + if (HAVE_OP(2, op_end, op)) + goto output_overrun; + + *op++ = *m_pos++; + *op++ = *m_pos; + goto match_done; + } + + if (HAVE_LB(m_pos, out, op)) + goto lookbehind_overrun; + if (HAVE_OP(t + 3 - 1, op_end, op)) + goto output_overrun; + + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { + COPY4(op, m_pos); + op += 4; + m_pos += 4; + t -= 4 - (3 - 1); + do { + COPY4(op, m_pos); + op += 4; + m_pos += 4; + t -= 4; + } while (t >= 4); + if (t > 0) + do { + *op++ = *m_pos++; + } while (--t > 0); + } else { +copy_match: + *op++ = *m_pos++; + *op++ = *m_pos++; + do { + *op++ = *m_pos++; + } while (--t > 0); + } +match_done: + t = ip[-2] & 3; + if (t == 0) + break; +match_next: + if (HAVE_OP(t, op_end, op)) + goto output_overrun; + if (HAVE_IP(t + 1, ip_end, ip)) + goto input_overrun; + + *op++ = *ip++; + if (t > 1) { + *op++ = *ip++; + if (t > 2) + *op++ = *ip++; + } + + t = *ip++; + } while (ip < ip_end); + } + + *out_len = op - out; + return LZO_E_EOF_NOT_FOUND; + +eof_found: + *out_len = op - out; + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); +input_overrun: + *out_len = op - out; + return LZO_E_INPUT_OVERRUN; + +output_overrun: + *out_len = op - out; + return LZO_E_OUTPUT_OVERRUN; + +lookbehind_overrun: + *out_len = op - out; + return LZO_E_LOOKBEHIND_OVERRUN; +} + +EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LZO1X Decompressor"); + diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h new file mode 100644 index 000000000000..b6d482c492ef --- /dev/null +++ b/lib/lzo/lzodefs.h @@ -0,0 +1,43 @@ +/* + * lzodefs.h -- architecture, OS and compiler specific defines + * + * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer + * + * The full LZO package can be found at: + * http://www.oberhumer.com/opensource/lzo/ + * + * Changed for kernel use by: + * Nitin Gupta + * Richard Purdie + */ + +#define LZO_VERSION 0x2020 +#define LZO_VERSION_STRING "2.02" +#define LZO_VERSION_DATE "Oct 17 2005" + +#define M1_MAX_OFFSET 0x0400 +#define M2_MAX_OFFSET 0x0800 +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#define M2_MAX_LEN 8 +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#define D_BITS 14 +#define D_MASK ((1u << D_BITS) - 1) +#define D_HIGH ((D_MASK >> 1) + 1) + +#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \ + << (s1)) ^ (p)[0]) +#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0]) From c14d444b55f285063a4018c10d521614b70b581a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 10 Jul 2007 17:22:25 -0700 Subject: [PATCH 549/551] sx: switch subven and subid values sx.c is failing to locate Graham's card. Signed-off-by: Jiri Slaby Cc: Graham Murray Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/sx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 1da92a689ae4..85a23283dff5 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -2721,9 +2721,9 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev) its because the standard requires it. So check for SUBVENDOR_ID. */ static struct pci_device_id sx_pci_tbl[] = { { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = 0x0200,.subdevice = PCI_ANY_ID }, + .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = 0x0300,.subdevice = PCI_ANY_ID }, + .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, { 0 } }; From bcf67e16251c42302499499b1c50f7d35622f564 Mon Sep 17 00:00:00 2001 From: Pavel Emelianov Date: Tue, 10 Jul 2007 17:22:26 -0700 Subject: [PATCH 550/551] Make common helpers for seq_files that work with list_heads Many places in kernel use seq_file API to iterate over a regular list_head. The code for such iteration is identical in all the places, so it's worth introducing a common helpers. This makes code about 300 lines smaller: The first version of this patch made the helper functions static inline in the seq_file.h header. This patch moves them to the fs/seq_file.c as Andrew proposed. The vmlinux .text section sizes are as follows: 2.6.22-rc1-mm1: 0x001794d5 with the previous version: 0x00179505 with this patch: 0x00179135 The config file used was make allnoconfig with the "y" inclusion of all the possible options to make the files modified by the patch compile plus drivers I have on the test node. This patch: Many places in kernel use seq_file API to iterate over a regular list_head. The code for such iteration is identical in all the places, so it's worth introducing a common helpers. Signed-off-by: Pavel Emelianov Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/seq_file.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/seq_file.h | 11 +++++++++++ 2 files changed, 45 insertions(+) diff --git a/fs/seq_file.c b/fs/seq_file.c index 0ac22af7afe5..49194a4e6b91 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -447,3 +447,37 @@ int seq_puts(struct seq_file *m, const char *s) return -1; } EXPORT_SYMBOL(seq_puts); + +struct list_head *seq_list_start(struct list_head *head, loff_t pos) +{ + struct list_head *lh; + + list_for_each(lh, head) + if (pos-- == 0) + return lh; + + return NULL; +} + +EXPORT_SYMBOL(seq_list_start); + +struct list_head *seq_list_start_head(struct list_head *head, loff_t pos) +{ + if (!pos) + return head; + + return seq_list_start(head, pos - 1); +} + +EXPORT_SYMBOL(seq_list_start_head); + +struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) +{ + struct list_head *lh; + + lh = ((struct list_head *)v)->next; + ++*ppos; + return lh == head ? NULL : lh; +} + +EXPORT_SYMBOL(seq_list_next); diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 3e3cccbb1cac..83783ab0f552 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -50,5 +50,16 @@ int seq_release_private(struct inode *, struct file *); #define SEQ_START_TOKEN ((void *)1) +/* + * Helpers for iteration over list_head-s in seq_files + */ + +extern struct list_head *seq_list_start(struct list_head *head, + loff_t pos); +extern struct list_head *seq_list_start_head(struct list_head *head, + loff_t pos); +extern struct list_head *seq_list_next(void *v, struct list_head *head, + loff_t *ppos); + #endif #endif From 4eb6bf6bfb580afaf1e1a1d30cba17a078530cf4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 10 Jul 2007 17:22:27 -0700 Subject: [PATCH 551/551] lots-of-architectures: enable arbitary speed tty support Add the termios2 structure ready for enabling on most platforms. One or two like Sparc are plain weird so have been left alone. Most can use the same structure as ktermios for termios2 (ie the newer ioctl uses the structure matching the current kernel structure) Signed-off-by: Alan Cox Cc: Bryan Wu Cc: Ian Molton Cc: Haavard Skinnemoen Cc: Yoshinori Sato Cc: Mikael Starvik Cc: David Howells Cc: "Luck, Tony" Cc: Hirokazu Takata Cc: Geert Uytterhoeven Cc: Roman Zippel Cc: Ralf Baechle Cc: Kyle McMartin Cc: Matthew Wilcox Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Paul Mundt Cc: Kazumoto Kojima Cc: Richard Curnow Cc: Miles Bader Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-arm26/termbits.h | 12 +++++++++++- include/asm-avr32/termbits.h | 11 +++++++++++ include/asm-blackfin/termbits.h | 11 +++++++++++ include/asm-cris/termbits.h | 11 +++++++++++ include/asm-frv/termbits.h | 11 +++++++++++ include/asm-h8300/termbits.h | 11 +++++++++++ include/asm-ia64/termbits.h | 11 +++++++++++ include/asm-m32r/termbits.h | 11 +++++++++++ include/asm-m68k/termbits.h | 11 +++++++++++ include/asm-mips/termbits.h | 11 +++++++++++ include/asm-parisc/termbits.h | 11 +++++++++++ include/asm-s390/termbits.h | 11 +++++++++++ include/asm-sh/termbits.h | 11 +++++++++++ include/asm-v850/termbits.h | 11 +++++++++++ include/asm-xtensa/termbits.h | 11 +++++++++++ 15 files changed, 165 insertions(+), 1 deletion(-) diff --git a/include/asm-arm26/termbits.h b/include/asm-arm26/termbits.h index a3f4fe1742d0..f66b51804736 100644 --- a/include/asm-arm26/termbits.h +++ b/include/asm-arm26/termbits.h @@ -15,7 +15,7 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; -struct ktermios { +struct termios2 { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ @@ -26,6 +26,16 @@ struct ktermios { speed_t c_ospeed; /* output speed */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; /* c_cc characters */ #define VINTR 0 diff --git a/include/asm-avr32/termbits.h b/include/asm-avr32/termbits.h index c215fafdae4d..db2daab31fdb 100644 --- a/include/asm-avr32/termbits.h +++ b/include/asm-avr32/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-blackfin/termbits.h b/include/asm-blackfin/termbits.h index 2fd9dabdba77..4eac38de8ce1 100644 --- a/include/asm-blackfin/termbits.h +++ b/include/asm-blackfin/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-cris/termbits.h b/include/asm-cris/termbits.h index 8d8cec225fe1..6cc2e2736f7b 100644 --- a/include/asm-cris/termbits.h +++ b/include/asm-cris/termbits.h @@ -19,6 +19,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-frv/termbits.h b/include/asm-frv/termbits.h index 2d6d389cff49..74851b424d4f 100644 --- a/include/asm-frv/termbits.h +++ b/include/asm-frv/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-h8300/termbits.h b/include/asm-h8300/termbits.h index 6a1f4d3807b4..e877b40ac5ba 100644 --- a/include/asm-h8300/termbits.h +++ b/include/asm-h8300/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-ia64/termbits.h b/include/asm-ia64/termbits.h index 4531a511bde5..7fae3109ef47 100644 --- a/include/asm-ia64/termbits.h +++ b/include/asm-ia64/termbits.h @@ -26,6 +26,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-m32r/termbits.h b/include/asm-m32r/termbits.h index e402641dfbad..6be3b8a39841 100644 --- a/include/asm-m32r/termbits.h +++ b/include/asm-m32r/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h index a194092240fb..0e520f328f53 100644 --- a/include/asm-m68k/termbits.h +++ b/include/asm-m68k/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-mips/termbits.h b/include/asm-mips/termbits.h index 0bbe07b42a07..5bfdc3b64510 100644 --- a/include/asm-mips/termbits.h +++ b/include/asm-mips/termbits.h @@ -30,6 +30,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-parisc/termbits.h b/include/asm-parisc/termbits.h index a46e299a9391..e847fe979684 100644 --- a/include/asm-parisc/termbits.h +++ b/include/asm-parisc/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-s390/termbits.h b/include/asm-s390/termbits.h index 585c78a6e407..811b9a9cdc08 100644 --- a/include/asm-s390/termbits.h +++ b/include/asm-s390/termbits.h @@ -25,6 +25,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-sh/termbits.h b/include/asm-sh/termbits.h index f1b7b46f4e9a..7ee1b42eeab0 100644 --- a/include/asm-sh/termbits.h +++ b/include/asm-sh/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-v850/termbits.h b/include/asm-v850/termbits.h index f3b433032089..35412f7f3eea 100644 --- a/include/asm-v850/termbits.h +++ b/include/asm-v850/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ diff --git a/include/asm-xtensa/termbits.h b/include/asm-xtensa/termbits.h index 057b9a3d8f83..9972c25ec86f 100644 --- a/include/asm-xtensa/termbits.h +++ b/include/asm-xtensa/termbits.h @@ -30,6 +30,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */